@latticexyz/cli 2.0.0-snapshot-test-32d38619 → 2.0.0
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/chunk-QXUPZVZL.js +4 -0
- package/dist/chunk-QXUPZVZL.js.map +1 -0
- package/dist/commands-WWEJJZV4.js +36 -0
- package/dist/commands-WWEJJZV4.js.map +1 -0
- package/dist/errors-MZURIB7V.js +2 -0
- package/dist/errors-MZURIB7V.js.map +1 -0
- package/dist/index.js +0 -1
- package/dist/mud.js +1 -14
- package/dist/mud.js.map +1 -1
- package/package.json +21 -15
- package/src/build.ts +48 -0
- package/src/commands/build.ts +35 -0
- package/src/commands/deploy.ts +8 -31
- package/src/commands/dev-contracts.ts +80 -141
- package/src/commands/index.ts +2 -0
- package/src/commands/set-version.ts +24 -62
- package/src/commands/tablegen.ts +2 -2
- package/src/commands/test.ts +30 -36
- package/src/commands/trace.ts +15 -11
- package/src/commands/worldgen.ts +7 -6
- package/src/common.ts +1 -0
- package/src/debug.ts +10 -0
- package/src/deploy/common.ts +122 -0
- package/src/deploy/configToTables.ts +70 -0
- package/src/deploy/create2/README.md +13 -0
- package/src/deploy/create2/deployment.json +8 -0
- package/src/deploy/createPrepareDeploy.ts +28 -0
- package/src/deploy/debug.ts +10 -0
- package/src/deploy/deploy.ts +133 -0
- package/src/deploy/deployWorld.ts +38 -0
- package/src/deploy/ensureContract.ts +66 -0
- package/src/deploy/ensureContractsDeployed.ts +33 -0
- package/src/deploy/ensureDeployer.ts +75 -0
- package/src/deploy/ensureFunctions.ts +86 -0
- package/src/deploy/ensureModules.ts +79 -0
- package/src/deploy/ensureNamespaceOwner.ts +71 -0
- package/src/deploy/ensureSystems.ts +187 -0
- package/src/deploy/ensureTables.ts +64 -0
- package/src/deploy/ensureWorldFactory.ts +105 -0
- package/src/deploy/findLibraries.ts +36 -0
- package/src/deploy/getFunctions.ts +58 -0
- package/src/deploy/getResourceAccess.ts +51 -0
- package/src/deploy/getResourceIds.ts +31 -0
- package/src/deploy/getSystems.ts +47 -0
- package/src/deploy/getTableValue.ts +30 -0
- package/src/deploy/getTables.ts +59 -0
- package/src/deploy/getWorldDeploy.ts +39 -0
- package/src/deploy/logsToWorldDeploy.ts +49 -0
- package/src/deploy/orderByDependencies.ts +12 -0
- package/src/deploy/resolveConfig.ts +148 -0
- package/src/index.ts +1 -1
- package/src/mud.ts +37 -31
- package/src/mudPackages.ts +24 -0
- package/src/runDeploy.ts +149 -0
- package/src/utils/defaultModuleContracts.ts +30 -0
- package/src/utils/errors.ts +1 -1
- package/src/utils/findPlaceholders.ts +27 -0
- package/src/utils/getContractData.ts +38 -0
- package/src/utils/{utils/postDeploy.ts → postDeploy.ts} +2 -2
- package/src/utils/printMUD.ts +1 -1
- package/dist/chunk-WERDORTY.js +0 -11
- package/dist/chunk-WERDORTY.js.map +0 -1
- package/src/utils/deploy.ts +0 -255
- package/src/utils/deployHandler.ts +0 -93
- package/src/utils/modules/constants.ts +0 -23
- package/src/utils/modules/getInstallModuleCallData.ts +0 -27
- package/src/utils/modules/getUserModules.ts +0 -5
- package/src/utils/modules/types.ts +0 -14
- package/src/utils/systems/getGrantAccessCallData.ts +0 -29
- package/src/utils/systems/getRegisterFunctionSelectorsCallData.ts +0 -57
- package/src/utils/systems/getRegisterSystemCallData.ts +0 -17
- package/src/utils/systems/types.ts +0 -9
- package/src/utils/systems/utils.ts +0 -42
- package/src/utils/tables/getRegisterTableCallData.ts +0 -49
- package/src/utils/tables/getTableIds.ts +0 -21
- package/src/utils/tables/types.ts +0 -12
- package/src/utils/utils/confirmNonce.ts +0 -24
- package/src/utils/utils/deployContract.ts +0 -33
- package/src/utils/utils/fastTxExecute.ts +0 -56
- package/src/utils/utils/getChainId.ts +0 -10
- package/src/utils/utils/getContractData.ts +0 -29
- package/src/utils/utils/setInternalFeePerGas.ts +0 -49
- package/src/utils/utils/toBytes16.ts +0 -16
- package/src/utils/utils/types.ts +0 -21
- package/src/utils/world.ts +0 -28
@@ -0,0 +1,4 @@
|
|
1
|
+
import e from"chalk";import{ZodError as s}from"zod";import{fromZodError as i,ValidationError as l}from"zod-validation-error";import{NotInsideProjectError as t}from"@latticexyz/config/library";import{MUDError as r}from"@latticexyz/common/errors";function p(o){if(o instanceof l)console.log(e.redBright(o.message));else if(o instanceof s){let n=i(o,{prefixSeparator:`
|
2
|
+
- `,issueSeparator:`
|
3
|
+
- `});console.log(e.redBright(n.message))}else o instanceof t?(console.log(e.red(o.message)),console.log(""),console.log(e.blue("To learn more about MUD's configuration, please go to https://mud.dev/packages/cli/"))):o instanceof r?console.log(e.red(o)):console.log(o)}export{p as a};
|
4
|
+
//# sourceMappingURL=chunk-QXUPZVZL.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/utils/errors.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport { ZodError } from \"zod\";\nimport { fromZodError, ValidationError } from \"zod-validation-error\";\nimport { NotInsideProjectError } from \"@latticexyz/config/library\";\nimport { MUDError } from \"@latticexyz/common/errors\";\n\nexport function logError(error: unknown) {\n if (error instanceof ValidationError) {\n console.log(chalk.redBright(error.message));\n } else if (error instanceof ZodError) {\n // TODO currently this error shouldn't happen, use `fromZodErrorCustom`\n // (see https://github.com/latticexyz/mud/issues/438)\n const validationError = fromZodError(error, {\n prefixSeparator: \"\\n- \",\n issueSeparator: \"\\n- \",\n });\n console.log(chalk.redBright(validationError.message));\n } else if (error instanceof NotInsideProjectError) {\n console.log(chalk.red(error.message));\n console.log(\"\");\n // TODO add docs to the website and update the link to the specific page\n // (see https://github.com/latticexyz/mud/issues/445)\n console.log(chalk.blue(`To learn more about MUD's configuration, please go to https://mud.dev/packages/cli/`));\n } else if (error instanceof MUDError) {\n console.log(chalk.red(error));\n } else {\n console.log(error);\n }\n}\n"],"mappings":"AAAA,OAAOA,MAAW,QAClB,OAAS,YAAAC,MAAgB,MACzB,OAAS,gBAAAC,EAAc,mBAAAC,MAAuB,uBAC9C,OAAS,yBAAAC,MAA6B,6BACtC,OAAS,YAAAC,MAAgB,4BAElB,SAASC,EAASC,EAAgB,CACvC,GAAIA,aAAiBJ,EACnB,QAAQ,IAAIH,EAAM,UAAUO,EAAM,OAAO,CAAC,UACjCA,aAAiBN,EAAU,CAGpC,IAAMO,EAAkBN,EAAaK,EAAO,CAC1C,gBAAiB;AAAA,IACjB,eAAgB;AAAA,GAClB,CAAC,EACD,QAAQ,IAAIP,EAAM,UAAUQ,EAAgB,OAAO,CAAC,OAC3CD,aAAiBH,GAC1B,QAAQ,IAAIJ,EAAM,IAAIO,EAAM,OAAO,CAAC,EACpC,QAAQ,IAAI,EAAE,EAGd,QAAQ,IAAIP,EAAM,KAAK,qFAAqF,CAAC,GACpGO,aAAiBF,EAC1B,QAAQ,IAAIL,EAAM,IAAIO,CAAK,CAAC,EAE5B,QAAQ,IAAIA,CAAK,CAErB","names":["chalk","ZodError","fromZodError","ValidationError","NotInsideProjectError","MUDError","logError","error","validationError"]}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import{a as J}from"./chunk-QXUPZVZL.js";import gs from"@latticexyz/gas-report";import bs from"@latticexyz/abi-ts";import{loadConfig as Jo}from"@latticexyz/config/node";import{getSrcDirectory as qo}from"@latticexyz/common/foundry";import{existsSync as Fo,readFileSync as $o,writeFileSync as Ho}from"node:fs";import ae from"node:path";import{tablegen as Eo}from"@latticexyz/store/codegen";import{worldgen as No}from"@latticexyz/world/node";import{worldToV1 as zo}from"@latticexyz/world/config/v2";import{forge as Lo,getForgeConfig as Vo,getRemappings as Uo}from"@latticexyz/common/foundry";import Ro from"glob";import{basename as Mo}from"path";function I(e){return Ro.sync(`${e}/**/*.sol`).map(o=>({path:o,basename:Mo(o,".sol")}))}import he from"debug";var M=he("mud:cli"),Wo=he("mud:cli");M.log=console.debug.bind(console);Wo.log=console.error.bind(console);import{execa as _o}from"execa";var Ko=M.extend("runDeploy");async function q({config:e,srcDir:o,foundryProfile:n=process.env.FOUNDRY_PROFILE}){let t=zo(e),r=ae.join(o,t.codegenDirectory),s=await Uo(n);await Promise.all([Eo(e,r,s),No(e,I(o),r)]);let i=await Vo(n);if(i.cache){let a=ae.join(i.cache_path,"solidity-files-cache.json");if(Fo(a)){Ko("Unsetting cached content hash of IWorld.sol to force it to regenerate");let m=JSON.parse($o(a,"utf8")),c=ae.join(r,"world","IWorld.sol");m.files[c].contentHash="",Ho(a,JSON.stringify(m,null,2))}}await Lo(["build"],{profile:n}),await _o("mud",["abi-ts"],{stdio:"inherit"})}var Yo={command:"build",describe:"Build contracts and generate MUD artifacts (table libraries, world interface, ABI)",builder(e){return e.options({configPath:{type:"string",desc:"Path to the config file"},profile:{type:"string",desc:"The foundry profile to use"}})},async handler({configPath:e,profile:o}){let n=await Jo(e),t=await qo();await q({config:n,srcDir:t,foundryProfile:o}),process.exit(0)}},we=Yo;import{rmSync as Go}from"fs";import{homedir as Zo}from"os";import Qo from"path";import{execa as Xo}from"execa";var et={command:"devnode",describe:"Start a local Ethereum node for development",builder(e){return e.options({blocktime:{type:"number",default:1,decs:"Interval in which new blocks are produced"}})},async handler({blocktime:e}){console.log("Clearing devnode history");let o=Zo();Go(Qo.join(o,".foundry","anvil","tmp"),{recursive:!0,force:!0});let n=["-b",String(e),"--block-base-fee-per-gas","0"];console.log(`Running: anvil ${n.join(" ")}`);let t=Xo("anvil",n,{stdio:["inherit","inherit","inherit"]});process.on("SIGINT",()=>{console.log(`
|
2
|
+
gracefully shutting down from SIGINT (Crtl-C)`),t.kill(),process.exit()}),await t}},xe=et;import{FaucetServiceDefinition as ot}from"@latticexyz/services/faucet";import{createChannel as tt,createClient as rt}from"nice-grpc-web";import Se from"chalk";import{NodeHttpTransport as nt}from"@improbable-eng/grpc-web-node-http-transport";function st(e){return rt(ot,tt(e,nt()))}var at={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:n}){let t=st(o);e&&(console.log(Se.yellow("Dripping to",n)),await t.dripDev({address:n}),console.log(Se.yellow("Success"))),process.exit(0)}},Ce=at;var it={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)}},De=it;import ct from"path";import{loadConfig as dt}from"@latticexyz/config/node";import{tablegen as lt}from"@latticexyz/store/codegen";import{getRemappings as mt,getSrcDirectory as pt}from"@latticexyz/common/foundry";var ft={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 dt(e),n=await pt(),t=await mt();await lt(o,ct.join(n,o.codegen.outputDirectory),t),process.exit(0)}},Te=ft;import fe from"node:path";import{existsSync as on,mkdirSync as tn,readFileSync as rn,writeFileSync as ye}from"node:fs";import{getBalance as gt,getBytecode as bt,sendRawTransaction as ht,sendTransaction as ve,waitForTransactionReceipt as Ae}from"viem/actions";var A={gasPrice:1e11,gasLimit:1e5,signerAddress:"3fab184622dc19b6109349b94811493bf2a45362",transaction:"f8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222",address:"4e59b44847b379578588920ca78fbf26c0b4956c",bytecode:"604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"};var l=M.extend("deploy"),ut=M.extend("deploy");l.log=console.debug.bind(console);ut.log=console.error.bind(console);var R=`0x${A.address}`,ke=`0x${A.bytecode}`;async function Ie(e){let o=await bt(e,{address:R});if(o)return l("found CREATE2 deployer at",R),o!==ke&&console.warn(`
|
3
|
+
\u26A0\uFE0F Bytecode for deployer at ${R} did not match the expected CREATE2 bytecode. You may have unexpected results.
|
4
|
+
`),R;let n=BigInt(A.gasLimit)*BigInt(A.gasPrice),t=await gt(e,{address:`0x${A.signerAddress}`}),r=n-t;if(r>0){l("sending gas for CREATE2 deployer to signer at",A.signerAddress);let a=await ve(e,{chain:e.chain??null,to:`0x${A.signerAddress}`,value:r}),m=await Ae(e,{hash:a});if(m.status!=="success")throw console.error("failed to send gas to deployer signer",m),new Error("failed to send gas to deployer signer")}l("deploying CREATE2 deployer at",R);let s=await ht(e,{serializedTransaction:`0x${A.transaction}`}).catch(a=>{if(String(a).includes("only replay-protected (EIP-155) transactions allowed over RPC"))return console.warn(`
|
5
|
+
\u26A0\uFE0F Your chain or RPC does not allow for non EIP-155 signed transactions, so your deploys will not be determinstic and contract addresses may change between deploys.
|
6
|
+
|
7
|
+
We recommend running your chain's node with \`--rpc.allow-unprotected-txs\` to enable determinstic deployments.
|
8
|
+
`),l("deploying CREATE2 deployer"),ve(e,{chain:e.chain??null,data:ke});throw a}),i=await Ae(e,{hash:s});if(!i.contractAddress)throw new Error("Deploy receipt did not have contract address, was the deployer not deployed?");return i.contractAddress!==R&&console.warn(`
|
9
|
+
\u26A0\uFE0F CREATE2 deployer created at ${i.contractAddress} does not match the CREATE2 determinstic deployer we expected (${R})`),i.contractAddress}import{waitForTransactionReceipt as Vt}from"viem/actions";import Re from"@latticexyz/world/out/AccessManagementSystem.sol/AccessManagementSystem.json"assert{type:"json"};import Me from"@latticexyz/world/out/BalanceTransferSystem.sol/BalanceTransferSystem.json"assert{type:"json"};import We from"@latticexyz/world/out/BatchCallSystem.sol/BatchCallSystem.json"assert{type:"json"};import Fe from"@latticexyz/world/out/RegistrationSystem.sol/RegistrationSystem.json"assert{type:"json"};import $e from"@latticexyz/world/out/InitModule.sol/InitModule.json"assert{type:"json"};import $t from"@latticexyz/world/out/InitModule.sol/InitModule.abi.json"assert{type:"json"};import He from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.json"assert{type:"json"};import Ht from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"assert{type:"json"};import{getCreate2Address as F,encodeDeployData as Ee,size as $}from"viem";import{padHex as xt}from"viem";import St from"@latticexyz/store/mud.config";import Ct from"@latticexyz/world/mud.config";import Dt from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import Tt from"@latticexyz/world-modules/out/IModule.sol/IModule.abi.json"assert{type:"json"};import{resourceToHex as wt}from"@latticexyz/common";import{resolveUserTypes as Pe}from"@latticexyz/store/internal";function L(e){let o={...e.userTypes,...Object.fromEntries(Object.entries(e.enums).map(([n])=>[n,{internalType:"uint8"}]))};return Object.fromEntries(Object.entries(e.tables).map(([n,t])=>[`${e.namespace}_${n}`,{namespace:e.namespace,name:t.name,tableId:wt({type:t.offchainOnly?"offchainTable":"table",namespace:e.namespace,name:t.name}),keySchema:Pe(t.keySchema,o),valueSchema:Pe(t.valueSchema,o)}]))}import{helloStoreEvent as vt}from"@latticexyz/store";import{helloWorldEvent as At}from"@latticexyz/world";import{storeToV1 as kt}from"@latticexyz/store/config/v2";import{worldToV1 as It}from"@latticexyz/world/config/v2";var T=xt("0x",{size:32}),V=parseInt("6000",16),W=L(kt(St)),v=L(It(Ct)),Y=[vt,At],D=[...Dt,...Tt],Be=["2.0.0"],Oe=["2.0.0"];import{waitForTransactionReceipt as Wt}from"viem/actions";import{concatHex as Pt,getCreate2Address as Bt}from"viem";import{getBytecode as Ot}from"viem/actions";import{sendTransaction as jt}from"@latticexyz/common";import Rt from"p-retry";import{wait as Mt}from"@latticexyz/common/utils";async function je({client:e,deployerAddress:o,bytecode:n,deployedBytecodeSize:t,label:r="contract"}){if(n.includes("__$"))throw new Error(`Found unlinked public library in ${r} bytecode`);let s=Bt({from:o,salt:T,bytecode:n});return await Ot(e,{address:s,blockTag:"pending"})?(l("found",r,"at",s),[]):(t>V?console.warn(`
|
10
|
+
Bytecode for ${r} (${t} bytes) is over the contract size limit (${V} bytes). Run \`forge build --sizes\` for more info.
|
11
|
+
`):t>V*.95&&console.warn(`
|
12
|
+
Bytecode for ${r} (${t} bytes) is almost over the contract size limit (${V} bytes). Run \`forge build --sizes\` for more info.
|
13
|
+
`),l("deploying",r,"at",s),[await Rt(()=>jt(e,{chain:e.chain??null,to:o,data:Pt([T,n])}),{retries:3,onFailedAttempt:async a=>{let m=a.attemptNumber*500;l(`failed to deploy ${r}, retrying in ${m}ms...`),await Mt(m)}})])}import{uniqueBy as Ft}from"@latticexyz/common/utils";async function P({client:e,deployerAddress:o,contracts:n}){let t=Ft(n,s=>s.bytecode),r=(await Promise.all(t.map(s=>je({client:e,deployerAddress:o,...s})))).flat();if(r.length){l("waiting for contracts");for(let s of r)await Wt(e,{hash:s})}return r}async function G(e,o){let n=$(Re.deployedBytecode.object),t=Re.bytecode.object,r=F({from:o,bytecode:t,salt:T}),s=$(Me.deployedBytecode.object),i=Me.bytecode.object,a=F({from:o,bytecode:i,salt:T}),m=$(We.deployedBytecode.object),c=We.bytecode.object,f=F({from:o,bytecode:c,salt:T}),y=$(Fe.deployedBytecode.object),x=Fe.bytecode.object,C=F({from:o,bytecode:x,salt:T}),d=$($e.deployedBytecode.object),u=Ee({bytecode:$e.bytecode.object,abi:$t,args:[r,a,f,C]}),w=F({from:o,bytecode:u,salt:T}),h=$(He.deployedBytecode.object),S=Ee({bytecode:He.bytecode.object,abi:Ht,args:[w]}),p=F({from:o,bytecode:S,salt:T});return await P({client:e,deployerAddress:o,contracts:[{bytecode:t,deployedBytecodeSize:n,label:"access management system"},{bytecode:i,deployedBytecodeSize:s,label:"balance transfer system"},{bytecode:c,deployedBytecodeSize:m,label:"batch call system"},{bytecode:x,deployedBytecodeSize:y,label:"core registration system"},{bytecode:u,deployedBytecodeSize:d,label:"core module"},{bytecode:S,deployedBytecodeSize:h,label:"world factory"}]}),p}import Ut from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"assert{type:"json"};import{writeContract as _t}from"@latticexyz/common";import{AbiEventSignatureNotFoundError as Et,decodeEventLog as Nt,hexToString as Ne,parseAbi as zt}from"viem";import{isDefined as Lt}from"@latticexyz/common/utils";function Z(e){let o=e.map(i=>{try{return{...i,...Nt({strict:!0,abi:zt(Y),topics:i.topics,data:i.data})}}catch(a){if(a instanceof Et)return;throw a}}).filter(Lt),{address:n,deployBlock:t,worldVersion:r,storeVersion:s}=o.reduce((i,a)=>({...i,address:a.address,deployBlock:a.blockNumber,...a.eventName==="HelloWorld"?{worldVersion:Ne(a.args.worldVersion).replace(/\0+$/,"")}:null,...a.eventName==="HelloStore"?{storeVersion:Ne(a.args.storeVersion).replace(/\0+$/,"")}:null}),{});if(n==null)throw new Error("could not find world address");if(t==null)throw new Error("could not find world deploy block number");if(r==null)throw new Error("could not find world version");if(s==null)throw new Error("could not find store version");return{address:n,deployBlock:t,worldVersion:r,storeVersion:s}}async function ze(e,o,n){let t=await G(e,o);l("deploying world");let r=await _t(e,{chain:e.chain??null,address:t,abi:Ut,functionName:"deployWorld",args:[n]});l("waiting for world deploy");let s=await Vt(e,{hash:r});if(s.status!=="success")throw console.error("world deploy failed",s),new Error("world deploy failed");let i=Z(s.logs.map(a=>a));return l("deployed world to",i.address,"at block",i.deployBlock),{...i,stateBlock:i.deployBlock}}import{resourceToLabel as ie,writeContract as Qt}from"@latticexyz/common";import{valueSchemaToFieldLayoutHex as Xt,keySchemaToHex as er,valueSchemaToHex as or}from"@latticexyz/protocol-parser/internal";import{parseAbiItem as Kt,decodeAbiParameters as Le,parseAbiParameters as Ve}from"viem";import{hexToResource as Jt}from"@latticexyz/common";import{storeSetRecordEvent as qt}from"@latticexyz/store";import{getLogs as Yt}from"viem/actions";import{decodeKey as Gt,decodeValueArgs as Zt,hexToSchema as Ue}from"@latticexyz/protocol-parser/internal";async function _e({client:e,worldDeploy:o}){l("looking up tables for",o.address);let t=(await Yt(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:Kt(qt),args:{tableId:W.store_Tables.tableId}})).map(r=>{let{tableId:s}=Gt(W.store_Tables.keySchema,r.args.keyTuple),{namespace:i,name:a}=Jt(s),m=Zt(W.store_Tables.valueSchema,r.args),c=Ue(m.keySchema),f=Ue(m.valueSchema),y=Le(Ve("string[]"),m.abiEncodedKeyNames)[0],x=Le(Ve("string[]"),m.abiEncodedFieldNames)[0],C=[...f.staticFields,...f.dynamicFields],d=Object.fromEntries(c.staticFields.map((w,h)=>[y[h],w])),u=Object.fromEntries(C.map((w,h)=>[x[h],w]));return{namespace:i,name:a,tableId:s,keySchema:d,valueSchema:u}});return l("found",t.length,"tables for",o.address),t}import tr from"p-retry";import{wait as rr}from"@latticexyz/common/utils";async function Ke({client:e,worldDeploy:o,tables:n}){let r=(await _e({client:e,worldDeploy:o})).map(a=>a.tableId),s=n.filter(a=>r.includes(a.tableId));s.length&&l("existing tables",s.map(ie).join(", "));let i=n.filter(a=>!r.includes(a.tableId));return i.length?(l("registering tables",i.map(ie).join(", ")),await Promise.all(i.map(a=>tr(()=>Qt(e,{chain:e.chain??null,address:o.address,abi:D,functionName:"registerTable",args:[a.tableId,Xt(a.valueSchema),er(a.keySchema),or(a.valueSchema),Object.keys(a.keySchema),Object.keys(a.valueSchema)]}),{retries:3,onFailedAttempt:async m=>{let c=m.attemptNumber*500;l(`failed to register table ${ie(a)}, retrying in ${c}ms...`),await rr(c)}})))):[]}import{getAddress as O}from"viem";import{writeContract as ce,resourceToLabel as U}from"@latticexyz/common";import{parseAbiItem as nr}from"viem";import{getLogs as sr}from"viem/actions";import{storeSpliceStaticDataEvent as ar}from"@latticexyz/store";async function Q({client:e,worldDeploy:o}){l("looking up resource IDs for",o.address);let t=(await sr(e,{strict:!0,address:o.address,fromBlock:o.deployBlock,toBlock:o.stateBlock,event:nr(ar),args:{tableId:W.store_ResourceIds.tableId}})).map(r=>r.args.keyTuple[0]);return l("found",t.length,"resource IDs for",o.address),t}import{hexToResource as Sr,resourceToLabel as Cr}from"@latticexyz/common";import{decodeValueArgs as ir,encodeKey as cr}from"@latticexyz/protocol-parser/internal";import{readContract as dr}from"viem/actions";async function B({client:e,worldDeploy:o,table:n,key:t}){let[r,s,i]=await dr(e,{blockNumber:o.stateBlock,address:o.address,abi:D,functionName:"getRecord",args:[n.tableId,cr(n.keySchema,t)]});return ir(n.valueSchema,{staticData:r,encodedLengths:s,dynamicData:i})}import{toFunctionSelector as lr,parseAbiItem as mr}from"viem";import{storeSetRecordEvent as pr}from"@latticexyz/store";import{getLogs as fr}from"viem/actions";import{decodeValueArgs as yr}from"@latticexyz/protocol-parser/internal";import{hexToResource as ur}from"@latticexyz/common";async function X({client:e,worldDeploy:o}){l("looking up function signatures for",o.address);let t=(await fr(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:mr(pr),args:{tableId:v.world_FunctionSignatures.tableId}})).map(s=>yr(v.world_FunctionSignatures.valueSchema,s.args).functionSignature);return l("found",t.length,"function signatures for",o.address),await Promise.all(t.map(async s=>{let i=lr(s),{systemId:a,systemFunctionSelector:m}=await B({client:e,worldDeploy:o,table:v.world_FunctionSelectors,key:{worldFunctionSelector:i}}),{namespace:c,name:f}=ur(a),y=c===""?s:s.replace(`${c}_${f}_`,"");return{signature:s,selector:i,systemId:a,systemFunctionSignature:y,systemFunctionSelector:m}}))}import{parseAbiItem as gr,getAddress as br}from"viem";import{storeSpliceStaticDataEvent as hr}from"@latticexyz/store";import{getLogs as wr}from"viem/actions";import{decodeKey as xr}from"@latticexyz/protocol-parser/internal";async function ee({client:e,worldDeploy:o}){l("looking up resource access for",o.address);let t=(await wr(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:gr(hr),args:{tableId:v.world_ResourceAccess.tableId}})).map(s=>xr(v.world_ResourceAccess.keySchema,s.args.keyTuple)),r=(await Promise.all(t.map(async s=>[s,await B({client:e,worldDeploy:o,table:v.world_ResourceAccess,key:s})]))).filter(([,s])=>s.access).map(([s])=>({resourceId:s.resourceId,address:br(s.caller)}));return l("found",r.length,"resource<>address access pairs"),r}async function Je({client:e,worldDeploy:o}){let[n,t,r]=await Promise.all([Q({client:e,worldDeploy:o}),X({client:e,worldDeploy:o}),ee({client:e,worldDeploy:o})]),s=n.map(Sr).filter(i=>i.type==="system");return l("looking up systems",s.map(Cr).join(", ")),await Promise.all(s.map(async i=>{let{system:a,publicAccess:m}=await B({client:e,worldDeploy:o,table:v.world_Systems,key:{systemId:i.resourceId}}),c=t.filter(f=>f.systemId===i.resourceId);return{address:a,namespace:i.namespace,name:i.name,systemId:i.resourceId,allowAll:m,allowedAddresses:r.filter(({resourceId:f})=>f===i.resourceId).map(({address:f})=>f),functions:c}}))}import{wait as de}from"@latticexyz/common/utils";import le from"p-retry";async function qe({client:e,deployerAddress:o,libraries:n,worldDeploy:t,systems:r}){let[s,i]=await Promise.all([Je({client:e,worldDeploy:t}),ee({client:e,worldDeploy:t})]),a=r.filter(p=>s.some(g=>g.systemId===p.systemId&&O(g.address)===O(p.prepareDeploy(o,n).address)));a.length&&l("existing systems",a.map(U).join(", "));let m=a.map(p=>p.systemId),c=r.filter(p=>!m.includes(p.systemId));if(!c.length)return[];let f=c.filter(p=>s.some(g=>g.systemId===p.systemId&&O(g.address)!==O(p.prepareDeploy(o,n).address)));f.length&&l("upgrading systems",f.map(U).join(", "));let y=c.filter(p=>!s.some(g=>g.systemId===p.systemId));y.length&&l("registering new systems",y.map(U).join(", ")),await P({client:e,deployerAddress:o,contracts:c.map(p=>({bytecode:p.prepareDeploy(o,n).bytecode,deployedBytecodeSize:p.deployedBytecodeSize,label:`${U(p)} system`}))});let x=await Promise.all(c.map(p=>le(()=>ce(e,{chain:e.chain??null,address:t.address,abi:D,functionName:"registerSystem",args:[p.systemId,p.prepareDeploy(o,n).address,p.allowAll]}),{retries:3,onFailedAttempt:async g=>{let b=g.attemptNumber*500;l(`failed to register system ${U(p)}, retrying in ${b}ms...`),await de(b)}}))),C=r.map(p=>p.systemId),d=i.filter(({resourceId:p})=>C.includes(p)),u=[...r.flatMap(p=>p.allowedAddresses.map(g=>({resourceId:p.systemId,address:g}))),...r.flatMap(p=>p.allowedSystemIds.map(g=>({resourceId:p.systemId,address:s.find(b=>b.systemId===g)?.address??r.find(b=>b.systemId===g)?.prepareDeploy(o,n).address})).filter(g=>g.address!=null))],w=u.filter(p=>!d.some(({resourceId:g,address:b})=>g===p.resourceId&&O(b)===O(p.address))),h=d.filter(p=>!u.some(({resourceId:g,address:b})=>g===p.resourceId&&O(b)===O(p.address)));h.length&&l("revoking",h.length,"access grants"),w.length&&l("adding",w.length,"access grants");let S=await Promise.all([...h.map(p=>le(()=>ce(e,{chain:e.chain??null,address:t.address,abi:D,functionName:"revokeAccess",args:[p.resourceId,p.address]}),{retries:3,onFailedAttempt:async g=>{let b=g.attemptNumber*500;l(`failed to revoke access, retrying in ${b}ms...`),await de(b)}})),...w.map(p=>le(()=>ce(e,{chain:e.chain??null,address:t.address,abi:D,functionName:"grantAccess",args:[p.resourceId,p.address]}),{retries:3,onFailedAttempt:async g=>{let b=g.attemptNumber*500;l(`failed to grant access, retrying in ${b}ms...`),await de(b)}}))]);return[...x,...S]}import{waitForTransactionReceipt as io}from"viem/actions";import{getAddress as Dr,parseAbi as Tr}from"viem";import{getBlockNumber as vr,getLogs as Ar}from"viem/actions";var Ye=new Map;async function Ge(e,o){let n=Dr(o),t=Ye.get(n);if(t!=null)return t;l("looking up world deploy for",n);let r=await vr(e),s=await Ar(e,{strict:!0,address:n,events:Tr(Y),fromBlock:"earliest",toBlock:r});return t={...Z(s),stateBlock:r},Ye.set(n,t),l("found world deploy for",n,"at block",t.deployBlock),t}import{hexToResource as kr,writeContract as Ze}from"@latticexyz/common";import Qe from"p-retry";import{wait as Xe}from"@latticexyz/common/utils";async function eo({client:e,worldDeploy:o,functions:n}){let t=await X({client:e,worldDeploy:o}),r=Object.fromEntries(t.map(a=>[a.selector,a])),s=n.filter(a=>r[a.selector]),i=n.filter(a=>!s.includes(a));if(s.length){l("functions already registered:",s.map(m=>m.signature).join(", "));let a=s.filter(m=>m.systemId!==r[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 i.length?(l("registering functions:",i.map(a=>a.signature).join(", ")),Promise.all(i.map(a=>{let{namespace:m}=kr(a.systemId);return m===""?Qe(()=>Ze(e,{chain:e.chain??null,address:o.address,abi:D,functionName:"registerRootFunctionSelector",args:[a.systemId,a.systemFunctionSignature,a.systemFunctionSignature]}),{retries:3,onFailedAttempt:async c=>{let f=c.attemptNumber*500;l(`failed to register function ${a.signature}, retrying in ${f}ms...`),await Xe(f)}}):Qe(()=>Ze(e,{chain:e.chain??null,address:o.address,abi:D,functionName:"registerFunctionSelector",args:[a.systemId,a.systemFunctionSignature]}),{retries:3,onFailedAttempt:async c=>{let f=c.attemptNumber*500;l(`failed to register function ${a.signature}, retrying in ${f}ms...`),await Xe(f)}})}))):[]}import{BaseError as Ir}from"viem";import{writeContract as oo}from"@latticexyz/common";import{isDefined as Pr,wait as Br}from"@latticexyz/common/utils";import Or from"p-retry";async function to({client:e,deployerAddress:o,libraries:n,worldDeploy:t,modules:r}){return r.length?(await P({client:e,deployerAddress:o,contracts:r.map(s=>({bytecode:s.prepareDeploy(o,n).bytecode,deployedBytecodeSize:s.deployedBytecodeSize,label:`${s.name} module`}))}),l("installing modules:",r.map(s=>s.name).join(", ")),(await Promise.all(r.map(s=>Or(async()=>{try{let i=s.prepareDeploy(o,n).address;return s.installAsRoot?await oo(e,{chain:e.chain??null,address:t.address,abi:D,functionName:"installRootModule",args:[i,s.installData]}):await oo(e,{chain:e.chain??null,address:t.address,abi:D,functionName:"installModule",args:[i,s.installData]})}catch(i){if(i instanceof Ir&&i.message.includes("Module_AlreadyInstalled")){l(`module ${s.name} already installed`);return}throw i}},{retries:3,onFailedAttempt:async i=>{let a=i.attemptNumber*500;l(`failed to install module ${s.name}, retrying in ${a}ms...`),await Br(a)}})))).filter(Pr)):[]}import{getAddress as ro}from"viem";import{hexToResource as no,resourceToHex as so,writeContract as jr}from"@latticexyz/common";async function ao({client:e,worldDeploy:o,resourceIds:n}){let t=Array.from(new Set(n.map(y=>no(y).namespace))),r=await Q({client:e,worldDeploy:o}),s=new Set(r.map(y=>no(y).namespace));s.size&&l("found",s.size,"existing namespaces:",Array.from(s).map(y=>y===""?"<root>":y).join(", "));let i=t.filter(y=>s.has(y)),m=(await Promise.all(i.map(async y=>{let{owner:x}=await B({client:e,worldDeploy:o,table:v.world_NamespaceOwner,key:{namespaceId:so({type:"namespace",namespace:y,name:""})}});return[y,x]}))).filter(([,y])=>ro(y)!==ro(e.account.address)).map(([y])=>y);if(m.length)throw new Error(`You are attempting to deploy to namespaces you do not own: ${m.join(", ")}`);let c=t.filter(y=>!s.has(y));return c.length>0&&l("registering namespaces",Array.from(c).join(", ")),Promise.all(c.map(y=>jr(e,{chain:e.chain??null,address:o.address,abi:D,functionName:"registerNamespace",args:[so({namespace:y,type:"namespace",name:""})]})))}import{resourceToLabel as Rr}from"@latticexyz/common";import{randomBytes as Mr}from"crypto";async function co({client:e,config:o,salt:n,worldAddress:t,deployerAddress:r}){let s=Object.values(o.tables),i=r??await Ie(e);await G(e,i),await P({client:e,deployerAddress:i,contracts:[...o.libraries.map(d=>({bytecode:d.prepareDeploy(i,o.libraries).bytecode,deployedBytecodeSize:d.deployedBytecodeSize,label:`${d.path}:${d.name} library`})),...o.systems.map(d=>({bytecode:d.prepareDeploy(i,o.libraries).bytecode,deployedBytecodeSize:d.deployedBytecodeSize,label:`${Rr(d)} system`})),...o.modules.map(d=>({bytecode:d.prepareDeploy(i,o.libraries).bytecode,deployedBytecodeSize:d.deployedBytecodeSize,label:`${d.name} module`}))]});let a=t?await Ge(e,t):await ze(e,i,n??`0x${Mr(32).toString("hex")}`);if(!Be.includes(a.storeVersion))throw new Error(`Unsupported Store version: ${a.storeVersion}`);if(!Oe.includes(a.worldVersion))throw new Error(`Unsupported World version: ${a.worldVersion}`);let m=await ao({client:e,worldDeploy:a,resourceIds:[...s.map(d=>d.tableId),...o.systems.map(d=>d.systemId)]});l("waiting for all namespace registration transactions to confirm");for(let d of m)await io(e,{hash:d});let c=await Ke({client:e,worldDeploy:a,tables:s}),f=await qe({client:e,deployerAddress:i,libraries:o.libraries,worldDeploy:a,systems:o.systems}),y=await eo({client:e,worldDeploy:a,functions:o.systems.flatMap(d=>d.functions)}),x=await to({client:e,deployerAddress:i,libraries:o.libraries,worldDeploy:a,modules:o.modules}),C=[...c,...f,...y,...x];l("waiting for all transactions to confirm");for(let d of C)await io(e,{hash:d});return l("deploy complete"),a}import{createWalletClient as nn,http as sn,isHex as an}from"viem";import{privateKeyToAccount as cn}from"viem/accounts";import{loadConfig as dn}from"@latticexyz/config/node";import{worldToV1 as ln}from"@latticexyz/world/config/v2";import{getOutDirectory as mn,getRpcUrl as pn,getSrcDirectory as fn}from"@latticexyz/common/foundry";import E from"chalk";import{MUDError as bo}from"@latticexyz/common/errors";import Vr from"path";import{resolveWorldConfig as Ur}from"@latticexyz/world/internal";import{resourceToHex as pe}from"@latticexyz/common";import{resolveWithContext as _r}from"@latticexyz/config/library";import{encodeField as Kr}from"@latticexyz/protocol-parser/internal";import{hexToBytes as Jr,bytesToHex as qr,toFunctionSelector as fo,toFunctionSignature as yo}from"viem";import oe from"@latticexyz/world-modules/out/KeysWithValueModule.sol/KeysWithValueModule.json"assert{type:"json"};import te from"@latticexyz/world-modules/out/KeysInTableModule.sol/KeysInTableModule.json"assert{type:"json"};import re from"@latticexyz/world-modules/out/UniqueEntityModule.sol/UniqueEntityModule.json"assert{type:"json"};import{size as me}from"viem";function H(e){return Object.entries(e).flatMap(([o,n])=>Object.entries(n).flatMap(([t,r])=>r.map(s=>({path:o,name:t,start:s.start,length:s.length}))))}var lo=[{name:"KeysWithValueModule",abi:oe.abi,bytecode:oe.bytecode.object,placeholders:H(oe.bytecode.linkReferences),deployedBytecodeSize:me(oe.deployedBytecode.object)},{name:"KeysInTableModule",abi:te.abi,bytecode:te.bytecode.object,placeholders:H(te.bytecode.linkReferences),deployedBytecodeSize:me(te.deployedBytecode.object)},{name:"UniqueEntityModule",abi:re.abi,bytecode:re.bytecode.object,placeholders:H(re.bytecode.linkReferences),deployedBytecodeSize:me(re.deployedBytecode.object)}];import{readFileSync as Wr}from"fs";import Fr from"path";import{MUDError as ne}from"@latticexyz/common/errors";import{size as $r}from"viem";function _(e,o,n){let t,r=Fr.join(n,e,o+".json");try{t=JSON.parse(Wr(r,"utf8"))}catch{throw new ne(`Error reading file at ${r}`)}let s=t?.bytecode?.object;if(!s)throw new ne(`No bytecode found in ${r}`);let i=t?.deployedBytecode?.object;if(!i)throw new ne(`No deployed bytecode found in ${r}`);let a=t?.abi;if(!a)throw new ne(`No ABI found in ${r}`);let m=H(t?.bytecode?.linkReferences??{});return{abi:a,bytecode:s,placeholders:m,deployedBytecodeSize:$r(i)}}import{groupBy as Yr}from"@latticexyz/common/utils";import{readFileSync as Er}from"fs";import Nr from"glob";import Hr from"toposort";function mo(e,o,n){let t=Hr(e.flatMap(r=>n(r).map(s=>[o(r),s])));return[...e].sort((r,s)=>t.indexOf(o(r))-t.indexOf(o(s)))}function po(e){let n=Nr.sync(`${e}/**/*.json`,{ignore:"**/*.abi.json"}).map(t=>JSON.parse(Er(t,"utf8"))).flatMap(t=>{if(!t.metadata)return[];let r=Object.keys(t.metadata.settings.compilationTarget)[0],s=t.metadata.settings.compilationTarget[r],i=t.bytecode.linkReferences;return Object.entries(i).flatMap(([a,m])=>Object.keys(m).map(c=>({path:a,name:c,dependentPath:r,dependentName:s})))});return mo(n,t=>`${t.path}:${t.name}`,t=>[`${t.dependentPath}:${t.dependentName}`])}import{spliceHex as zr}from"@latticexyz/common";import{getCreate2Address as Lr}from"viem";function se(e,o){return function(t,r){let s=e;for(let i of o){let a=r.find(m=>m.path===i.path&&m.name===i.name);if(!a)throw new Error(`Could not find library for bytecode placeholder ${i.path}:${i.name}`);s=zr(s,i.start,i.length,a.prepareDeploy(t,r).address)}return{bytecode:s,address:Lr({from:t,bytecode:s,salt:T})}}}function uo({config:e,forgeSourceDir:o,forgeOutDir:n}){let t=po(n).map(d=>{let u=_(Vr.basename(d.path),d.name,n);return{path:d.path,name:d.name,abi:u.abi,prepareDeploy:se(u.bytecode,u.placeholders),deployedBytecodeSize:u.deployedBytecodeSize}}),r=L(e),s=I(o).map(({basename:d})=>d),i=Ur(e,s),m=_("System.sol","System",n).abi.filter(d=>d.type==="function").map(yo),c=Object.entries(i.systems).map(([d,u])=>{let w=e.namespace,h=u.name,S=pe({type:"system",namespace:w,name:h}),p=_(`${d}.sol`,d,n),g=p.abi.filter(b=>b.type==="function").map(yo).filter(b=>!m.includes(b)).map(b=>{let be=w===""?b:`${w}__${b}`;return{signature:be,selector:fo(be),systemId:S,systemFunctionSignature:b,systemFunctionSelector:fo(b)}});return{namespace:w,name:h,systemId:S,allowAll:u.openAccess,allowedAddresses:u.accessListAddresses,allowedSystemIds:u.accessListSystems.map(b=>pe({type:"system",namespace:w,name:i.systems[b].name})),prepareDeploy:se(p.bytecode,p.placeholders),deployedBytecodeSize:p.deployedBytecodeSize,abi:p.abi,functions:g}}),f=Yr(c,d=>d.systemId),y=Array.from(f.values()).filter(d=>d.length>1).flat();if(y.length){let d=y.map(u=>u.name);throw new Error(`Found systems with overlapping system ID: ${d.join(", ")}.
|
14
|
+
|
15
|
+
System IDs are generated from the first 16 bytes of the name, so you may need to rename them to avoid the overlap.`)}let x={tableIds:Object.fromEntries(Object.entries(e.tables).map(([d,u])=>[d,Jr(pe({type:u.offchainOnly?"offchainTable":"table",namespace:e.namespace,name:u.name}))]))},C=e.modules.map(d=>{let u=lo.find(h=>h.name===d.name)??_(`${d.name}.sol`,d.name,n),w=d.args.map(h=>_r(h,x)).map(h=>{let S=h.value instanceof Uint8Array?qr(h.value):h.value;return Kr(h.type,S)});if(w.length>1)throw new Error(`${d.name} module should only have 0-1 args, but had ${w.length} args.`);return{name:d.name,installAsRoot:d.root,installData:w.length===0?"0x":w[0],prepareDeploy:se(u.bytecode,u.placeholders),deployedBytecodeSize:u.deployedBytecodeSize,abi:u.abi}});return{tables:r,systems:c,modules:C,libraries:t}}import{getChainId as yn}from"viem/actions";import{existsSync as Gr}from"fs";import Zr from"path";import Qr from"chalk";import{getScriptDirectory as Xr,forge as en}from"@latticexyz/common/foundry";async function go(e,o,n,t){let r=Zr.join(await Xr(),e+".s.sol");Gr(r)?(console.log(Qr.blue(`Executing post deploy script at ${r}`)),await en(["script",e,"--sig","run(address)",o,"--broadcast","--rpc-url",n,"-vvv"],{profile:t})):console.log(`No script at ${r}, skipping post deploy hook`)}var k={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"},rpcBatch:{type:"boolean",desc:"Enable batch processing of RPC requests in viem client (defaults to batch size of 100 and wait of 1s)"},deployerAddress:{type:"string",desc:"Deploy using an existing deterministic deployer (https://github.com/Arachnid/deterministic-deployment-proxy)"},worldAddress:{type:"string",desc:"Deploy to an existing World at the given address"},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."},salt:{type:"string",desc:"The deployment salt to use. Defaults to a random salt."}};async function N(e){let o=e.salt;if(o!=null&&!an(o))throw new bo("Expected hex string for salt");let n=e.profile??process.env.FOUNDRY_PROFILE,t=await dn(e.configPath),r=ln(t);e.printConfig&&console.log(E.green(`
|
16
|
+
Resolved config:
|
17
|
+
`),JSON.stringify(r,null,2));let s=e.srcDir??await fn(n),i=await mn(n),a=e.rpc??await pn(n);console.log(E.bgBlue(E.whiteBright(`
|
18
|
+
Deploying MUD contracts${n?" with profile "+n:""} to RPC ${a}
|
19
|
+
`))),e.skipBuild||await q({config:t,srcDir:s,foundryProfile:n});let m=process.env.PRIVATE_KEY;if(!m)throw new bo(`Missing PRIVATE_KEY environment variable.
|
20
|
+
Run 'echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env'
|
21
|
+
in your contracts directory to use the default anvil private key.`);let c=uo({config:r,forgeSourceDir:s,forgeOutDir:i}),f=nn({transport:sn(a,{batch:e.rpcBatch?{batchSize:100,wait:1e3}:void 0}),account:cn(m)});console.log("Deploying from",f.account.address);let y=Date.now(),x=await co({deployerAddress:e.deployerAddress,salt:o,worldAddress:e.worldAddress,client:f,config:c});(e.worldAddress==null||e.alwaysRunPostDeploy)&&await go(r.postDeployScript,x.address,a,n),console.log(E.green("Deployment completed in",(Date.now()-y)/1e3,"seconds"));let C={worldAddress:x.address,blockNumber:Number(x.deployBlock)};if(e.saveDeployment){let d=await yn(f),u=fe.join(r.deploysDirectory,d.toString());tn(u,{recursive:!0}),ye(fe.join(u,"latest.json"),JSON.stringify(C,null,2)),ye(fe.join(u,Date.now()+".json"),JSON.stringify(C,null,2));let w=[1337,31337],h=on(r.worldsFile)?JSON.parse(rn(r.worldsFile,"utf-8")):{};h[d]={address:C.worldAddress,blockNumber:w.includes(d)?void 0:C.blockNumber},ye(r.worldsFile,JSON.stringify(h,null,2)),console.log(E.bgGreen(E.whiteBright(`
|
22
|
+
Deployment result (written to ${r.worldsFile} and ${u}):
|
23
|
+
`)))}return console.log(C),x}var un={command:"deploy",describe:"Deploy MUD contracts",builder(e){return e.options(k)},async handler(e){try{await N(e)}catch(o){J(o),process.exit(1)}process.exit(0)}},ho=un;import{loadConfig as gn}from"@latticexyz/config/node";import{worldgen as bn}from"@latticexyz/world/node";import{getSrcDirectory as hn}from"@latticexyz/common/foundry";import wo from"path";import{rmSync as wn}from"fs";var xn={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 Sn(e),process.exit(0)}};async function Sn(e){let o=e.srcDir??await hn(),n=I(o),t=e.config??await gn(e.configPath),r=wo.join(o,t.codegen.outputDirectory);e.clean&&wn(wo.join(r,t.codegen.worldgenDirectory),{recursive:!0,force:!0}),await bn(t,n,r)}var xo=xn;import K from"chalk";import{readFileSync as An,writeFileSync as kn}from"fs";import ge from"path";import{MUDError as z}from"@latticexyz/common/errors";var So={name:"@latticexyz/cli",version:"2.0.0",description:"Command line interface for mud",repository:{type:"git",url:"https://github.com/latticexyz/mud.git",directory:"packages/cli"},license:"MIT",type:"module",exports:{".":"./dist/index.js"},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",toposort:"^2.0.2",typescript:"5.4.2",viem:"2.7.12",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/toposort":"^2.0.6","@types/yargs":"^17.0.10","ds-test":"https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0","forge-std":"https://github.com/foundry-rs/forge-std.git#74cfb77e308dd188d2f58864aaf44963ae6b88b1",tsup:"^6.7.0",tsx:"^3.12.6",vitest:"0.34.6"}};import In from"glob";import{ZodError as Dn,z as Co}from"zod";var Tn=Co.object({MUD_PACKAGES:Co.string().transform(e=>JSON.parse(e))});function vn(){try{return Tn.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/protocol-parser":{"localPath":"packages/protocol-parser"},"@latticexyz/query":{"localPath":"packages/query"},"@latticexyz/react":{"localPath":"packages/react"},"@latticexyz/recs":{"localPath":"packages/recs"},"@latticexyz/schema-type":{"localPath":"packages/schema-type"},"@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 Dn){let{...o}=e.format();console.error(`
|
24
|
+
Missing or invalid environment variables:
|
25
|
+
|
26
|
+
${Object.keys(o).join(`
|
27
|
+
`)}
|
28
|
+
`),process.exit(1)}throw e}}var ue=vn().MUD_PACKAGES;var Pn={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"],n=o.reduce((r,s)=>e[s]?r+1:r,0);if(n===0)throw new z(`You need to provide one these options: ${o.join(", ")}`);if(n>1)throw new z(`These options are mutually exclusive: ${o.join(", ")}`);e.link||(e.mudVersion=await Bn(e));let t=In.sync("**/package.json").filter(r=>!r.includes("node_modules"));for(let r of t)On(r,e)}catch(o){J(o)}finally{process.exit(0)}}};async function Bn(e){e.mudVersion==="canary"&&(e.tag="main");let o;try{console.log(K.blue("Fetching available versions")),o=await(await fetch(`https://registry.npmjs.org/${So.name}`)).json()}catch{throw new z("Could not fetch available MUD versions")}if(e.tag){let n=o["dist-tags"][e.tag];if(!n)throw new z(`Could not find npm version with tag "${e.tag}"`);return console.log(K.green(`Latest version with tag ${e.tag}: ${n}`)),n}if(e.commit){let n=e.commit.substring(0,8),t=Object.keys(o.versions).find(r=>r.includes(n));if(!t)throw new z(`Could not find npm version based on commit "${e.commit}"`);return console.log(K.green(`Version from commit ${e.commit}: ${t}`)),t}return e.mudVersion}function On(e,o){let{link:n}=o,{mudVersion:t}=o,r=jn(e),s=Object.keys(ue),i={};for(let c in r.dependencies)s.includes(c)&&(i[c]=r.dependencies[c]);let a={};for(let c in r.devDependencies)s.includes(c)&&(a[c]=r.devDependencies[c]);for(let c in r.dependencies)s.includes(c)&&(r.dependencies[c]=m(c,"dependencies"));for(let c in r.devDependencies)s.includes(c)&&(r.devDependencies[c]=m(c,"devDependencies"));return kn(e,JSON.stringify(r,null,2)+`
|
29
|
+
`),console.log(`Updating ${e}`),Do(i,r.dependencies),Do(a,r.devDependencies),r;function m(c,f){return n&&(t=Rn(e,n,c)),t||r[f][c]}}function jn(e){try{let o=An(e,"utf8");return JSON.parse(o)}catch{throw new z("Could not read JSON at "+e)}}function Do(e,o){for(let n in e)e[n]!==o[n]&&console.log(`${n}: ${K.red(e[n])} -> ${K.green(o[n])}`)}function Rn(e,o,n){let t=ge.relative(ge.dirname(e),process.cwd());return"link:"+ge.join(t,o,ue[n].localPath)}var To=Pn;import{anvil as Mn,forge as Wn,getRpcUrl as Fn}from"@latticexyz/common/foundry";import $n from"chalk";var Hn={...k,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"}},En={command:"test",describe:"Run tests in MUD contracts",builder(e){return e.options(Hn)},async handler(e){if(!e.worldAddress){let r=["--block-base-fee-per-gas","0","--port",String(e.port)];Mn(r)}let o=e.worldAddress?await Fn(e.profile):`http://127.0.0.1:${e.port}`,n=e.worldAddress??(await N({...e,saveDeployment:!1,rpc:o})).address;console.log($n.blue("World address",n));let t=e.forgeOptions?.replaceAll("\\","").split(" ")??[];try{await Wn(["test","--fork-url",o,...t],{profile:e.profile,env:{WORLD_ADDRESS:n}}),process.exit(0)}catch(r){console.error(r),process.exit(1)}}},vo=En;import{existsSync as Nn,readFileSync as zn}from"fs";import{ethers as Ao}from"ethers";import{loadConfig as Ln}from"@latticexyz/config/node";import{MUDError as ko}from"@latticexyz/common/errors";import{cast as Vn,getRpcUrl as Un,getSrcDirectory as _n}from"@latticexyz/common/foundry";import{resolveWorldConfig as Kn}from"@latticexyz/world/internal";import Jn from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import Io from"@latticexyz/world/mud.config";import{resourceToHex as Bo}from"@latticexyz/common";import{createClient as qn,http as Yn}from"viem";import{getChainId as Gn}from"viem/actions";import{worldToV1 as Zn}from"@latticexyz/world/config/v2";var Po=Bo({type:"system",namespace:Io.namespace,name:Io.tables.world__Systems.name}),Qn={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 _n(o),e.rpc??=await Un(o);let{tx:n,configPath:t,srcDir:r,rpc:s}=e,i=I(r),a=await Ln(t),m=Zn(a),c=Kn(m,i.map(({basename:S})=>S)),f=e.worldAddress??await Xn(m.worldsFile,s),y=new Ao.providers.StaticJsonRpcProvider(s),x=new Ao.Contract(f,Jn,y),C=m.namespace,d=Object.values(c.systems).map(({name:S})=>S),u=await x.getFieldLayout(Po),w=[];for(let S of d){let p=Bo({type:"system",namespace:C,name:S}),g=await x.getField(Po,[p],0,u);w.push({name:S,address:g})}let h=await Vn(["run","--label",`${f}:World`,...w.map(({name:S,address:p})=>["--label",`${p}:${S}`]).flat(),`${n}`]);console.log(h),process.exit(0)}},Oo=Qn;async function Xn(e,o){if(Nn(e)){let n=qn({transport:Yn(o)}),t=await Gn(n),r=JSON.parse(zn(e,"utf-8"));if(!r[t])throw new ko(`chainId ${t} is missing in worldsFile "${e}"`);return r[t].address}else throw new ko("worldAddress is not specified and worldsFile is missing")}import{anvil as es,getScriptDirectory as os,getSrcDirectory as ts}from"@latticexyz/common/foundry";import j from"chalk";import rs from"chokidar";import{loadConfig as ns,resolveConfigPath as ss}from"@latticexyz/config/node";import as from"path";import{homedir as is}from"os";import{rmSync as cs}from"fs";import{BehaviorSubject as ds,debounceTime as ls,exhaustMap as ms,filter as ps}from"rxjs";import{isDefined as fs}from"@latticexyz/common/utils";var ys={rpc:k.rpc,configPath:k.configPath,alwaysRunPostDeploy:k.alwaysRunPostDeploy,worldAddress:k.worldAddress},us={command:"dev-contracts",describe:"Start a development server for MUD contracts",builder(e){return e.options(ys)},async handler(e){let o=e.rpc,n=e.configPath??await ss(e.configPath),t=await ts(),r=await os(),s=await ns(n);if(!e.rpc){console.log(j.gray("Cleaning devnode cache"));let c=is();cs(as.join(c,".foundry","anvil","tmp"),{recursive:!0,force:!0}),es(["--block-time","1","--block-base-fee-per-gas","0"]),o="http://127.0.0.1:8545"}let i=new ds(Date.now());rs.watch([n,t,r],{ignoreInitial:!0}).on("all",async(c,f)=>{f.includes(n)&&(console.log(j.blue("Config changed, queuing deploy\u2026")),i.next(Date.now())),(f.includes(t)||f.includes(r))&&(f.includes(s.codegen.outputDirectory)||(console.log(j.blue("Contracts changed, queuing deploy\u2026")),i.next(Date.now())))});let a=e.worldAddress;i.pipe(ls(200),ms(async c=>{a&&console.log(j.blue("Rebuilding and upgrading world\u2026"));try{let f=await N({...e,configPath:n,rpc:o,rpcBatch:!1,skipBuild:!1,printConfig:!1,profile:void 0,saveDeployment:!0,deployerAddress:void 0,worldAddress:a,srcDir:t,salt:"0x"});return a=f.address,c<i.value?i.next(i.value):console.log(j.gray(`
|
30
|
+
Waiting for file changes\u2026
|
31
|
+
`)),f}catch(f){console.error(j.bgRed(j.whiteBright(`
|
32
|
+
Error while attempting deploy
|
33
|
+
`))),console.error(f),console.log(j.gray(`
|
34
|
+
Waiting for file changes\u2026
|
35
|
+
`))}}),ps(fs)).subscribe()}},jo=us;var Ep=[we,ho,xe,Ce,gs,De,Te,xo,To,vo,Oo,jo,bs];export{Ep as commands};
|
36
|
+
//# sourceMappingURL=commands-WWEJJZV4.js.map
|