@latticexyz/cli 2.0.0-main-e0377761 → 2.0.0-main-e0193e57
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-3LOTLAJX.js +11 -0
- package/dist/chunk-3LOTLAJX.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/mud.js +6 -6
- package/dist/mud.js.map +1 -1
- package/package.json +11 -11
- package/src/commands/deploy.ts +1 -1
- package/src/commands/dev-contracts.ts +3 -1
- package/src/commands/test.ts +1 -1
- package/src/commands/trace.ts +2 -1
- package/src/commands/worldgen.ts +1 -1
- package/src/utils/deploy.ts +183 -555
- package/src/utils/deployHandler.ts +1 -1
- package/src/utils/modules/constants.ts +23 -0
- package/src/utils/modules/getInstallModuleCallData.ts +27 -0
- package/src/utils/modules/getUserModules.ts +5 -0
- package/src/utils/modules/types.ts +14 -0
- package/src/utils/systems/getGrantAccessCallData.ts +29 -0
- package/src/utils/systems/getRegisterFunctionSelectorsCallData.ts +68 -0
- package/src/utils/systems/getRegisterSystemCallData.ts +17 -0
- package/src/utils/systems/types.ts +14 -0
- package/src/utils/systems/utils.ts +50 -0
- package/src/utils/tables/getRegisterTableCallData.ts +40 -0
- package/src/utils/tables/getTableIds.ts +21 -0
- package/src/utils/tables/types.ts +12 -0
- package/src/utils/utils/confirmNonce.ts +24 -0
- package/src/utils/utils/deployContract.ts +33 -0
- package/src/utils/utils/fastTxExecute.ts +56 -0
- package/src/utils/utils/getContractData.ts +29 -0
- package/src/utils/utils/postDeploy.ts +25 -0
- package/src/utils/utils/setInternalFeePerGas.ts +49 -0
- package/src/utils/utils/toBytes16.ts +16 -0
- package/src/utils/utils/types.ts +21 -0
- package/src/utils/world.ts +28 -0
- package/dist/chunk-KX5JLFDL.js +0 -11
- package/dist/chunk-KX5JLFDL.js.map +0 -1
- package/src/utils/index.ts +0 -6
- /package/src/utils/{getChainId.ts → utils/getChainId.ts} +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import F from"chalk";import B from"path";import{MUDError as et}from"@latticexyz/common/errors";import{loadConfig as tt}from"@latticexyz/config/node";import g from"chalk";import{ethers as O}from"ethers";import{getOutDirectory as He,cast as Ve}from"@latticexyz/common/foundry";import{resolveWorldConfig as Ye}from"@latticexyz/world";import Fe from"chalk";import Te from"@latticexyz/world/out/World.sol/World.json"assert{type:"json"};import Ne from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import G from"chalk";import{ethers as xe}from"ethers";import{MUDError as U}from"@latticexyz/common/errors";async function N(e){let{signer:o,nonce:t,maxPriorityFeePerGas:r,maxFeePerGas:n,debug:a,gasPrice:i,confirmations:m,contract:l}=e;try{let s=new xe.ContractFactory(l.abi,l.bytecode,o);console.log(G.gray(`executing deployment of ${l.name} with nonce ${t}`));let f=s.deploy({nonce:t,maxPriorityFeePerGas:r,maxFeePerGas:n,gasPrice:i}).then(p=>m?p:p.deployed()),{address:u}=await f;return console.log(G.green("Deployed",l.name,"to",u)),u}catch(s){throw a&&console.error(s),s?.message.includes("invalid bytecode")?new U(`Error deploying ${l.name}: invalid bytecode. Note that linking of public libraries is not supported yet, make sure none of your libraries use "external" functions.`):s?.message.includes("CreateContractLimit")?new U(`Error deploying ${l.name}: CreateContractLimit exceeded.`):s}}import{readFileSync as Pe}from"fs";import Se from"path";import{MUDError as v}from"@latticexyz/common/errors";function D(e,o){let t,r=Se.join(o,e+".sol",e+".json");try{t=JSON.parse(Pe(r,"utf8"))}catch{throw new v(`Error reading file at ${r}`)}let n=t?.bytecode?.object;if(!n)throw new v(`No bytecode found in ${r}`);let a=t?.abi;if(!a)throw new v(`No ABI found in ${r}`);return{abi:a,bytecode:n}}async function L(e){console.log(Fe.blue("Deploying World"));let o=e.worldContractName?{name:"World",...D(e.worldContractName,e.forgeOutDirectory)}:{abi:Ne,bytecode:Te.bytecode,name:"World"};return N({...e,nonce:e.nonce,contract:o})}import ze from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import ie from"@latticexyz/world/out/CoreModule.sol/CoreModule.json"assert{type:"json"};import K from"@latticexyz/world/out/KeysWithValueModule.sol/KeysWithValueModule.json"assert{type:"json"};import _ from"@latticexyz/world/out/KeysInTableModule.sol/KeysInTableModule.json"assert{type:"json"};import J from"@latticexyz/world/out/UniqueEntityModule.sol/UniqueEntityModule.json"assert{type:"json"};var R=[{name:"KeysWithValueModule",abi:K.abi,bytecode:K.bytecode},{name:"KeysInTableModule",abi:_.abi,bytecode:_.bytecode},{name:"UniqueEntityModule",abi:J.abi,bytecode:J.bytecode}];import{defaultAbiCoder as Ie}from"ethers/lib/utils.js";import{resolveWithContext as Me}from"@latticexyz/config";async function q(e,o,t){let r=await e[o.name];if(!r)throw new Error(`Module ${o.name} not found`);let n=o.args.map(m=>Me(m,{tableIds:t})),a=n.map(m=>m.value),i=n.map(m=>m.type);return{func:o.root?"installRootModule":"installModule",args:[r,Ie.encode(i,a)]}}function H(e,o){return o.filter(t=>!e.some(r=>r.name===t.name))}import{tableIdToHex as ve}from"@latticexyz/common";async function Y(e){let{systems:o,namespace:t,systemContracts:r}=e,n=[];for(let{name:a,accessListAddresses:i,accessListSystems:m}of o)i.map(async l=>n.push(V(a,t,l))),m.map(async l=>n.push(V(a,t,await r[l])));return n}function V(e,o,t){return{func:"grantAccess",args:[ve(o,e),t]}}import{tableIdToHex as Q}from"@latticexyz/common";import{ethers as A}from"ethers";function k(e,o){let{abi:t}=D(e,o);return t.filter(r=>["fallback","function"].includes(r.type)).map(r=>r.type==="fallback"?{functionName:"",functionArgs:""}:{functionName:r.name,functionArgs:z(r.inputs)})}function $({functionName:e,functionArgs:o}){let t=e+o;return t===""?"0x":Re(t)}function z(e){return`(${e.map(t=>{let r=t.type.match(/tuple(.*)/);return r?z(t.components)+r[1]:t.type})})`}function Re(e){return A.utils.hexDataSlice(A.utils.keccak256(A.utils.toUtf8Bytes(e)),0,4)}function X(e){let o=[],{systemName:t,namespace:r,forgeOutDirectory:n,system:a}=e;if(a.registerFunctionSelectors){let i=k("System",n).map(s=>s.functionName),m=k(t,n).filter(s=>t==="System"||!i.includes(s.functionName)),l=r==="";for(let{functionName:s,functionArgs:f}of m)o.push(Ae({namespace:r,name:a.name,systemName:t,functionName:s,functionArgs:f,isRoot:l}))}return o}function Ae(e){let{namespace:o,name:t,systemName:r,functionName:n,functionArgs:a,isRoot:i}=e,m=i?n+a:`${o}_${t}_${n}${a}`;if(i){let l=$(m===""?{functionName:r,functionArgs:a}:{functionName:n,functionArgs:a}),s=$({functionName:n,functionArgs:a});return{func:"registerRootFunctionSelector",args:[Q(o,t),l,s]}}else return{func:"registerRootFunctionSelector",args:[Q(o,t),n,a]}}import{tableIdToHex as ke}from"@latticexyz/common";async function Z(e){let{namespace:o,systemName:t,systemContracts:r,system:n}=e,a=await r[t];return{func:"registerSystem",args:[ke(o,n.name),a,n.openAccess]}}import{encodeSchema as ee,getStaticByteLength as $e}from"@latticexyz/schema-type/deprecated";import{resolveAbiOrUserType as te}from"@latticexyz/store/codegen";import{tableIdToHex as je}from"@latticexyz/common";import{fieldLayoutToHex as Oe}from"@latticexyz/protocol-parser";function oe(e,o){let{name:t,valueSchema:r,keySchema:n}=e;if(!t)throw Error("Table missing name");let a=Object.values(r).map(s=>{let{schemaType:f}=te(s,o);return f}),i=a.map(s=>$e(s)),m={staticFieldLengths:i.filter(s=>s>0),numDynamicFields:i.filter(s=>s===0).length},l=Object.values(n).map(s=>{let{schemaType:f}=te(s,o);return f});return{func:"registerTable",args:[je(o.namespace,t),Oe(m),ee(l),ee(a),Object.keys(n),Object.keys(r)]}}function S(e){if(e.length>16)throw new Error("String does not fit into 16 bytes");let o=new Uint8Array(16);for(let t=0;t<e.length;t++)o[t]=e.charCodeAt(t);for(let t=e.length;t<16;t++)o[t]=0;return o}function re(e){let o={};for(let[t,{name:r}]of Object.entries(e.tables))o[t]=Be(e.namespace,r);return o}function Be(e,o){let t=S(e),r=S(o),n=new Uint8Array(32);return n.set(t),n.set(r,16),n}import We from"chalk";import{MUDError as Ee}from"@latticexyz/common/errors";async function ne(e,o,t){let r=await e.getTransactionCount(),n=0,a=100;for(;r!==o&&n<a;)console.log(We.gray(`Waiting for transactions to be included before executing postDeployScript (local nonce: ${o}, remote nonce: ${r}, retry number ${n}/${a})`)),await new Promise(i=>setTimeout(i,t)),n++,r=await e.getTransactionCount();if(r!==o)throw new Ee("Remote nonce doesn't match local nonce, indicating that not all deploy transactions were included.")}import Ge from"chalk";import{MUDError as Ue}from"@latticexyz/common/errors";async function x(e){let{func:o,args:t,contract:r,signer:n,nonce:a,maxPriorityFeePerGas:i,maxFeePerGas:m,gasPrice:l,confirmations:s=1,debug:f}=e,u=`${o}(${t.map(p=>`'${p}'`).join(",")})`;try{let p=r.connect(n),d=await p.estimateGas[o].apply(null,t);return console.log(Ge.gray(`executing transaction: ${u} with nonce ${a}`)),p[o].apply(null,[...t,{gasLimit:d,nonce:a,maxPriorityFeePerGas:i,maxFeePerGas:m,gasPrice:l}]).then(h=>s===0?h:h.wait(s))}catch(p){throw f&&console.error(p),new Ue(`Gas estimation error for ${u}: ${p?.reason}`)}}import{existsSync as Le}from"fs";import Ke from"path";import _e from"chalk";import{getScriptDirectory as Je,forge as qe}from"@latticexyz/common/foundry";async function ae(e,o,t,r){let n=Ke.join(await Je(),e+".s.sol");Le(n)?(console.log(_e.blue(`Executing post deploy script at ${n}`)),await qe(["script",e,"--sig","run(address)",o,"--broadcast","--rpc-url",t,"-vvv"],{profile:r})):console.log(`No script at ${n}, skipping post deploy hook`)}import{MUDError as j}from"@latticexyz/common/errors";async function se(e,o){let t=await e.provider.getFeeData(),r,n,a;if(t.lastBaseFeePerGas){if(!t.lastBaseFeePerGas.eq(0)&&(await e.getBalance()).eq(0))throw new j(`Attempting to deploy to a chain with non-zero base fee with an account that has no balance.
|
|
2
|
+
If you're deploying to the Lattice testnet, you can fund your account by running 'pnpm mud faucet --address ${await e.getAddress()}'`);r=t.lastBaseFeePerGas.eq(0)?0:Math.floor(15e8*o),n=t.lastBaseFeePerGas.mul(2).add(r)}else if(t.gasPrice){if(!t.gasPrice.eq(0)&&(await e.getBalance()).eq(0))throw new j("Attempting to deploy to a chain with non-zero gas price with an account that has no balance.");a=t.gasPrice}else throw new j("Can not fetch fee data from RPC");return{maxPriorityFeePerGas:r,maxFeePerGas:n,gasPrice:a}}async function ce(e,o,t){let r=Date.now(),{profile:n,rpc:a,privateKey:i,priorityFeeMultiplier:m,debug:l,worldAddress:s,disableTxWait:f,pollInterval:u}=t,p=Ye(e,o),d=await He(n),h=new O.providers.StaticJsonRpcProvider(a);h.pollingInterval=u;let C=new O.Wallet(i,h);console.log("Deploying from",C.address);let y=await C.getTransactionCount();console.log("Initial nonce",y);let w={...await se(C,m),signer:C,debug:!!l,disableTxWait:f,confirmations:f?0:1},E=Number(await Ve(["block-number","--rpc-url",a],{profile:n}));console.log("Start deployment at block",E);let fe=s?Promise.resolve(s):L({...w,nonce:y++,worldContractName:e.worldContractName,forgeOutDirectory:d}),ue=H(R,e.modules),ge=Object.keys(ue).map(c=>{let{abi:b,bytecode:M}=D(c,d);return{name:c,abi:b,bytecode:M}}),de=Object.keys(p.systems).map(c=>{let{abi:b,bytecode:M}=D(c,d);return{name:c,abi:b,bytecode:M}}),T=[{name:"CoreModule",abi:ie.abi,bytecode:ie.bytecode},...R,...ge,...de].reduce((c,b)=>(c[b.name]=N({...w,nonce:y++,contract:b}),c),{}),I=await fe,P=new O.Contract(I,ze);s||(console.log(g.blue("Installing CoreModule")),await x({...w,nonce:y++,contract:P,func:"initialize",args:[await T.CoreModule]}),console.log(g.green("Installed CoreModule"))),e.namespace&&(console.log(g.blue("Registering Namespace")),await x({...w,nonce:y++,contract:P,func:"registerNamespace",args:[S(e.namespace)]}),console.log(g.green("Namespace registered")));let ye=re(e),be=Object.values(e.tables).map(c=>oe(c,e));console.log(g.blue("Registering tables")),await Promise.all(be.map(c=>x({...w,nonce:y++,contract:P,...c}))),console.log(g.green("Tables registered")),console.log(g.blue("Registering Systems and Functions"));let Ce=await Promise.all(Object.entries(p.systems).map(([c,b])=>Z({systemContracts:T,systemName:c,system:b,namespace:e.namespace}))),we=Object.entries(p.systems).flatMap(([c,b])=>X({systemName:c,system:b,namespace:e.namespace,forgeOutDirectory:d}));await Promise.all([...Ce,...we].map(c=>x({...w,nonce:y++,contract:P,...c}))),console.log(g.green("Systems and Functions registered"));let he=await Y({systems:Object.values(p.systems),systemContracts:T,namespace:e.namespace});console.log(g.blue("Granting Access")),await Promise.all(he.map(c=>x({...w,nonce:y++,contract:P,...c}))),console.log(g.green("Access granted"));let De=await Promise.all(e.modules.map(c=>q(T,c,ye)));return console.log(g.blue("Installing User Modules")),await Promise.all(De.map(c=>x({...w,nonce:y++,contract:P,...c}))),console.log(g.green("User Modules Installed")),await ne(C,y,u),await ae(e.postDeployScript,I,a,n),console.log(g.green("Deployment completed in",(Date.now()-r)/1e3,"seconds")),{worldAddress:I,blockNumber:E}}import{forge as pe,getRpcUrl as ot,getSrcDirectory as rt}from"@latticexyz/common/foundry";import{existsSync as nt,mkdirSync as at,readFileSync as st,writeFileSync as W}from"fs";import Qe from"glob";import{basename as Xe}from"path";function le(e){return Qe.sync(`${e}/**/*.sol`).map(o=>({path:o,basename:Xe(o,".sol")}))}import{execa as it}from"execa";import{ethers as Ze}from"ethers";async function me(e){let{result:o}=await Ze.utils.fetchJson(e,'{ "id": 42, "jsonrpc": "2.0", "method": "eth_chainId", "params": [ ] }');return Number(o)}async function Yo(e){e.profile??=process.env.FOUNDRY_PROFILE;let{configPath:o,printConfig:t,profile:r,clean:n,skipBuild:a}=e,i=e.rpc??await ot(r);console.log(F.bgBlue(F.whiteBright(`
|
|
3
|
+
Deploying MUD contracts${r?" with profile "+r:""} to RPC ${i}
|
|
4
|
+
`))),n&&await pe(["clean"],{profile:r}),a||(await pe(["build","--skip","test","script"],{profile:r}),await it("mud",["abi-ts"],{stdio:"inherit"}));let m=e?.srcDir??await rt(),l=le(m).map(({basename:p})=>p),s=await tt(o);t&&console.log(F.green(`
|
|
5
|
+
Resolved config:
|
|
6
|
+
`),JSON.stringify(s,null,2));let f=process.env.PRIVATE_KEY;if(!f)throw new et(`Missing PRIVATE_KEY environment variable.
|
|
7
|
+
Run 'echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env'
|
|
8
|
+
in your contracts directory to use the default anvil private key.`);let u=await ce(s,l,{...e,rpc:i,privateKey:f});if(e.saveDeployment){let p=await me(i),d=B.join(s.deploysDirectory,p.toString());at(d,{recursive:!0}),W(B.join(d,"latest.json"),JSON.stringify(u,null,2)),W(B.join(d,Date.now()+".json"),JSON.stringify(u,null,2));let h=[1337,31337],C=nt(s.worldsFile)?JSON.parse(st(s.worldsFile,"utf-8")):{};C[p]={address:u.worldAddress,blockNumber:h.includes(p)?void 0:u.blockNumber},W(s.worldsFile,JSON.stringify(C,null,2)),console.log(F.bgGreen(F.whiteBright(`
|
|
9
|
+
Deployment result (written to ${s.worldsFile} and ${d}):
|
|
10
|
+
`)))}return console.log(u),u}export{le as a,me as b,Yo as c};
|
|
11
|
+
//# sourceMappingURL=chunk-3LOTLAJX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/deployHandler.ts","../src/utils/deploy.ts","../src/utils/world.ts","../src/utils/utils/deployContract.ts","../src/utils/utils/getContractData.ts","../src/utils/modules/constants.ts","../src/utils/modules/getInstallModuleCallData.ts","../src/utils/modules/getUserModules.ts","../src/utils/systems/getGrantAccessCallData.ts","../src/utils/systems/getRegisterFunctionSelectorsCallData.ts","../src/utils/systems/utils.ts","../src/utils/systems/getRegisterSystemCallData.ts","../src/utils/tables/getRegisterTableCallData.ts","../src/utils/utils/toBytes16.ts","../src/utils/tables/getTableIds.ts","../src/utils/utils/confirmNonce.ts","../src/utils/utils/fastTxExecute.ts","../src/utils/utils/postDeploy.ts","../src/utils/utils/setInternalFeePerGas.ts","../src/utils/getExistingContracts.ts","../src/utils/utils/getChainId.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport path from \"path\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { WorldConfig } from \"@latticexyz/world\";\nimport { deploy } from \"../utils/deploy\";\nimport { forge, getRpcUrl, getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { getExistingContracts } from \"./getExistingContracts\";\nimport { execa } from \"execa\";\nimport { getChainId } from \"./utils/getChainId\";\n\nexport type DeployOptions = {\n configPath?: string;\n printConfig?: boolean;\n profile?: string;\n priorityFeeMultiplier: number;\n clean?: boolean;\n debug?: boolean;\n saveDeployment: boolean;\n rpc?: string;\n worldAddress?: string;\n srcDir?: string;\n disableTxWait: boolean;\n pollInterval: number;\n skipBuild?: boolean;\n};\n\nexport async function deployHandler(args: DeployOptions) {\n args.profile ??= process.env.FOUNDRY_PROFILE;\n const { configPath, printConfig, profile, clean, skipBuild } = args;\n\n const rpc = args.rpc ?? (await getRpcUrl(profile));\n console.log(\n chalk.bgBlue(\n chalk.whiteBright(`\\n Deploying MUD contracts${profile ? \" with profile \" + profile : \"\"} to RPC ${rpc} \\n`)\n )\n );\n\n if (clean) {\n await forge([\"clean\"], { profile });\n }\n\n // Run forge build\n if (!skipBuild) {\n await forge([\"build\", \"--skip\", \"test\", \"script\"], { profile });\n await execa(\"mud\", [\"abi-ts\"], { stdio: \"inherit\" });\n }\n\n // Get a list of all contract names\n const srcDir = args?.srcDir ?? (await getSrcDirectory());\n const existingContractNames = getExistingContracts(srcDir).map(({ basename }) => basename);\n\n // Load the config\n const mudConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n if (printConfig) console.log(chalk.green(\"\\nResolved config:\\n\"), JSON.stringify(mudConfig, null, 2));\n\n const privateKey = process.env.PRIVATE_KEY;\n if (!privateKey)\n throw new MUDError(\n `Missing PRIVATE_KEY environment variable.\nRun 'echo \"PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80\" > .env'\nin your contracts directory to use the default anvil private key.`\n );\n const deploymentInfo = await deploy(mudConfig, existingContractNames, { ...args, rpc, privateKey });\n\n if (args.saveDeployment) {\n // Write deployment result to file (latest and timestamp)\n const chainId = await getChainId(rpc);\n const outputDir = path.join(mudConfig.deploysDirectory, chainId.toString());\n mkdirSync(outputDir, { recursive: true });\n writeFileSync(path.join(outputDir, \"latest.json\"), JSON.stringify(deploymentInfo, null, 2));\n writeFileSync(path.join(outputDir, Date.now() + \".json\"), JSON.stringify(deploymentInfo, null, 2));\n\n const localChains = [1337, 31337];\n const deploys = existsSync(mudConfig.worldsFile) ? JSON.parse(readFileSync(mudConfig.worldsFile, \"utf-8\")) : {};\n deploys[chainId] = {\n address: deploymentInfo.worldAddress,\n // We expect the worlds file to be committed and since local deployments are often a consistent address but different block number, we'll ignore the block number.\n blockNumber: localChains.includes(chainId) ? undefined : deploymentInfo.blockNumber,\n };\n writeFileSync(mudConfig.worldsFile, JSON.stringify(deploys, null, 2));\n\n console.log(\n chalk.bgGreen(chalk.whiteBright(`\\n Deployment result (written to ${mudConfig.worldsFile} and ${outputDir}): \\n`))\n );\n }\n\n console.log(deploymentInfo);\n return deploymentInfo;\n}\n","import chalk from \"chalk\";\nimport { ethers } from \"ethers\";\nimport { getOutDirectory, cast } from \"@latticexyz/common/foundry\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { WorldConfig, resolveWorldConfig } from \"@latticexyz/world\";\nimport { deployWorldContract } from \"./world\";\nimport IBaseWorldAbi from \"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json\" assert { type: \"json\" };\nimport CoreModuleData from \"@latticexyz/world/out/CoreModule.sol/CoreModule.json\" assert { type: \"json\" };\nimport { defaultModuleContracts } from \"./modules/constants\";\nimport { getInstallModuleCallData } from \"./modules/getInstallModuleCallData\";\nimport { getUserModules } from \"./modules/getUserModules\";\nimport { getGrantAccessCallData } from \"./systems/getGrantAccessCallData\";\nimport { getRegisterFunctionSelectorsCallData } from \"./systems/getRegisterFunctionSelectorsCallData\";\nimport { getRegisterSystemCallData } from \"./systems/getRegisterSystemCallData\";\nimport { getRegisterTableCallData } from \"./tables/getRegisterTableCallData\";\nimport { getTableIds } from \"./tables/getTableIds\";\nimport { confirmNonce } from \"./utils/confirmNonce\";\nimport { deployContract } from \"./utils/deployContract\";\nimport { fastTxExecute } from \"./utils/fastTxExecute\";\nimport { getContractData } from \"./utils/getContractData\";\nimport { postDeploy } from \"./utils/postDeploy\";\nimport { setInternalFeePerGas } from \"./utils/setInternalFeePerGas\";\nimport { toBytes16 } from \"./utils/toBytes16\";\nimport { ContractCode } from \"./utils/types\";\n\nexport interface DeployConfig {\n profile?: string;\n rpc: string;\n privateKey: string;\n priorityFeeMultiplier: number;\n debug?: boolean;\n worldAddress?: string;\n disableTxWait: boolean;\n pollInterval: number;\n}\n\nexport interface DeploymentInfo {\n blockNumber: number;\n worldAddress: string;\n}\n\nexport async function deploy(\n mudConfig: StoreConfig & WorldConfig,\n existingContractNames: string[],\n deployConfig: DeployConfig\n): Promise<DeploymentInfo> {\n const startTime = Date.now();\n const { profile, rpc, privateKey, priorityFeeMultiplier, debug, worldAddress, disableTxWait, pollInterval } =\n deployConfig;\n const resolvedConfig = resolveWorldConfig(mudConfig, existingContractNames);\n const forgeOutDirectory = await getOutDirectory(profile);\n\n // Set up signer for deployment\n const provider = new ethers.providers.StaticJsonRpcProvider(rpc);\n provider.pollingInterval = pollInterval;\n const signer = new ethers.Wallet(privateKey, provider);\n console.log(\"Deploying from\", signer.address);\n\n let nonce = await signer.getTransactionCount();\n console.log(\"Initial nonce\", nonce);\n\n const txParams = await setInternalFeePerGas(signer, priorityFeeMultiplier);\n\n const txConfig = {\n ...txParams,\n signer,\n debug: Boolean(debug),\n disableTxWait,\n confirmations: disableTxWait ? 0 : 1,\n };\n\n // Get block number before deploying\n const blockNumber = Number(await cast([\"block-number\", \"--rpc-url\", rpc], { profile }));\n console.log(\"Start deployment at block\", blockNumber);\n\n // Deploy the World contract. Non-blocking.\n const worldPromise: Promise<string> = worldAddress\n ? Promise.resolve(worldAddress)\n : deployWorldContract({\n ...txConfig,\n nonce: nonce++,\n worldContractName: mudConfig.worldContractName,\n forgeOutDirectory,\n });\n\n // Filters any default modules from config\n const userModules = getUserModules(defaultModuleContracts, mudConfig.modules);\n const userModuleContracts = Object.keys(userModules).map((name) => {\n const { abi, bytecode } = getContractData(name, forgeOutDirectory);\n return {\n name,\n abi,\n bytecode,\n } as ContractCode;\n });\n\n const systemContracts = Object.keys(resolvedConfig.systems).map((name) => {\n const { abi, bytecode } = getContractData(name, forgeOutDirectory);\n return {\n name,\n abi,\n bytecode,\n } as ContractCode;\n });\n\n const contracts: ContractCode[] = [\n {\n name: \"CoreModule\",\n abi: CoreModuleData.abi,\n bytecode: CoreModuleData.bytecode,\n },\n ...defaultModuleContracts,\n ...userModuleContracts,\n ...systemContracts,\n ];\n\n // Deploy the System and Module contracts\n const deployedContracts = contracts.reduce<Record<string, Promise<string>>>((acc, contract) => {\n acc[contract.name] = deployContract({\n ...txConfig,\n nonce: nonce++,\n contract,\n });\n return acc;\n }, {});\n\n // Wait for world to be deployed\n const deployedWorldAddress = await worldPromise;\n const worldContract = new ethers.Contract(deployedWorldAddress, IBaseWorldAbi);\n\n // If an existing World is passed assume its coreModule is already installed - blocking to install if not\n if (!worldAddress) {\n console.log(chalk.blue(\"Installing CoreModule\"));\n await fastTxExecute({\n ...txConfig,\n nonce: nonce++,\n contract: worldContract,\n func: \"initialize\",\n args: [await deployedContracts[\"CoreModule\"]],\n });\n console.log(chalk.green(\"Installed CoreModule\"));\n }\n\n if (mudConfig.namespace) {\n console.log(chalk.blue(\"Registering Namespace\"));\n await fastTxExecute({\n ...txConfig,\n nonce: nonce++,\n contract: worldContract,\n func: \"registerNamespace\",\n args: [toBytes16(mudConfig.namespace)],\n });\n console.log(chalk.green(\"Namespace registered\"));\n }\n\n const tableIds = getTableIds(mudConfig);\n const registerTableCalls = Object.values(mudConfig.tables).map((table) => getRegisterTableCallData(table, mudConfig));\n\n console.log(chalk.blue(\"Registering tables\"));\n await Promise.all(\n registerTableCalls.map((call) =>\n fastTxExecute({\n ...txConfig,\n nonce: nonce++,\n contract: worldContract,\n ...call,\n })\n )\n );\n console.log(chalk.green(`Tables registered`));\n\n console.log(chalk.blue(\"Registering Systems and Functions\"));\n const systemCalls = await Promise.all(\n Object.entries(resolvedConfig.systems).map(([systemName, system]) =>\n getRegisterSystemCallData({\n systemContracts: deployedContracts,\n systemName,\n system,\n namespace: mudConfig.namespace,\n })\n )\n );\n const functionCalls = Object.entries(resolvedConfig.systems).flatMap(([systemName, system]) =>\n getRegisterFunctionSelectorsCallData({\n systemName,\n system,\n namespace: mudConfig.namespace,\n forgeOutDirectory,\n })\n );\n await Promise.all(\n [...systemCalls, ...functionCalls].map((call) =>\n fastTxExecute({\n ...txConfig,\n nonce: nonce++,\n contract: worldContract,\n ...call,\n })\n )\n );\n console.log(chalk.green(`Systems and Functions registered`));\n\n // Wait for System access to be granted before installing modules\n const grantCalls = await getGrantAccessCallData({\n systems: Object.values(resolvedConfig.systems),\n systemContracts: deployedContracts,\n namespace: mudConfig.namespace,\n });\n\n console.log(chalk.blue(\"Granting Access\"));\n await Promise.all(\n grantCalls.map((call) =>\n fastTxExecute({\n ...txConfig,\n nonce: nonce++,\n contract: worldContract,\n ...call,\n })\n )\n );\n console.log(chalk.green(`Access granted`));\n\n const moduleCalls = await Promise.all(\n mudConfig.modules.map((m) => getInstallModuleCallData(deployedContracts, m, tableIds))\n );\n\n console.log(chalk.blue(\"Installing User Modules\"));\n await Promise.all(\n moduleCalls.map((call) =>\n fastTxExecute({\n ...txConfig,\n nonce: nonce++,\n contract: worldContract,\n ...call,\n })\n )\n );\n console.log(chalk.green(`User Modules Installed`));\n\n // Double check that all transactions have been included by confirming the current nonce is the expected nonce\n await confirmNonce(signer, nonce, pollInterval);\n\n await postDeploy(mudConfig.postDeployScript, deployedWorldAddress, rpc, profile);\n\n console.log(chalk.green(\"Deployment completed in\", (Date.now() - startTime) / 1000, \"seconds\"));\n\n return { worldAddress: deployedWorldAddress, blockNumber };\n}\n","import chalk from \"chalk\";\n\nimport WorldData from \"@latticexyz/world/out/World.sol/World.json\" assert { type: \"json\" };\nimport IBaseWorldAbi from \"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json\" assert { type: \"json\" };\nimport { deployContract } from \"./utils/deployContract\";\nimport { getContractData } from \"./utils/getContractData\";\nimport { TxConfig } from \"./utils/types\";\n\nexport async function deployWorldContract(\n ip: TxConfig & {\n nonce: number;\n worldContractName: string | undefined;\n forgeOutDirectory: string;\n }\n): Promise<string> {\n console.log(chalk.blue(`Deploying World`));\n const contractData = ip.worldContractName\n ? {\n name: \"World\",\n ...getContractData(ip.worldContractName, ip.forgeOutDirectory),\n }\n : { abi: IBaseWorldAbi, bytecode: WorldData.bytecode, name: \"World\" };\n return deployContract({\n ...ip,\n nonce: ip.nonce,\n contract: contractData,\n });\n}\n","import chalk from \"chalk\";\nimport { ethers } from \"ethers\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { TxConfig, ContractCode } from \"./types\";\n\nexport async function deployContract(input: TxConfig & { nonce: number; contract: ContractCode }): Promise<string> {\n const { signer, nonce, maxPriorityFeePerGas, maxFeePerGas, debug, gasPrice, confirmations, contract } = input;\n\n try {\n const factory = new ethers.ContractFactory(contract.abi, contract.bytecode, signer);\n console.log(chalk.gray(`executing deployment of ${contract.name} with nonce ${nonce}`));\n const deployPromise = factory\n .deploy({\n nonce,\n maxPriorityFeePerGas,\n maxFeePerGas,\n gasPrice,\n })\n .then((c) => (confirmations ? c : c.deployed()));\n const { address } = await deployPromise;\n console.log(chalk.green(\"Deployed\", contract.name, \"to\", address));\n return address;\n } catch (error: any) {\n if (debug) console.error(error);\n if (error?.message.includes(\"invalid bytecode\")) {\n throw new MUDError(\n `Error deploying ${contract.name}: invalid bytecode. Note that linking of public libraries is not supported yet, make sure none of your libraries use \"external\" functions.`\n );\n } else if (error?.message.includes(\"CreateContractLimit\")) {\n throw new MUDError(`Error deploying ${contract.name}: CreateContractLimit exceeded.`);\n } else throw error;\n }\n}\n","import { readFileSync } from \"fs\";\nimport path from \"path\";\nimport { Fragment } from \"ethers/lib/utils.js\";\nimport { MUDError } from \"@latticexyz/common/errors\";\n\n/**\n * Load the contract's abi and bytecode from the file system\n * @param contractName: Name of the contract to load\n */\nexport function getContractData(\n contractName: string,\n forgeOutDirectory: string\n): { bytecode: string; abi: Fragment[] } {\n let data: any;\n const contractDataPath = path.join(forgeOutDirectory, contractName + \".sol\", contractName + \".json\");\n try {\n data = JSON.parse(readFileSync(contractDataPath, \"utf8\"));\n } catch (error: any) {\n throw new MUDError(`Error reading file at ${contractDataPath}`);\n }\n\n const bytecode = data?.bytecode?.object;\n if (!bytecode) throw new MUDError(`No bytecode found in ${contractDataPath}`);\n\n const abi = data?.abi;\n if (!abi) throw new MUDError(`No ABI found in ${contractDataPath}`);\n\n return { abi, bytecode };\n}\n","import KeysWithValueModuleData from \"@latticexyz/world/out/KeysWithValueModule.sol/KeysWithValueModule.json\" assert { type: \"json\" };\nimport KeysInTableModuleData from \"@latticexyz/world/out/KeysInTableModule.sol/KeysInTableModule.json\" assert { type: \"json\" };\nimport UniqueEntityModuleData from \"@latticexyz/world/out/UniqueEntityModule.sol/UniqueEntityModule.json\" assert { type: \"json\" };\nimport { ContractCode } from \"../utils/types\";\n\n// These modules are always deployed\nexport const defaultModuleContracts: ContractCode[] = [\n {\n name: \"KeysWithValueModule\",\n abi: KeysWithValueModuleData.abi,\n bytecode: KeysWithValueModuleData.bytecode,\n },\n {\n name: \"KeysInTableModule\",\n abi: KeysInTableModuleData.abi,\n bytecode: KeysInTableModuleData.bytecode,\n },\n {\n name: \"UniqueEntityModule\",\n abi: UniqueEntityModuleData.abi,\n bytecode: UniqueEntityModuleData.bytecode,\n },\n];\n","import { defaultAbiCoder } from \"ethers/lib/utils.js\";\nimport { resolveWithContext } from \"@latticexyz/config\";\nimport { Module } from \"./types\";\nimport { CallData } from \"../utils/types\";\nimport { TableIds } from \"../tables/types\";\n\nexport async function getInstallModuleCallData(\n moduleContracts: Record<string, Promise<string>>,\n module: Module,\n tableIds: TableIds\n): Promise<CallData> {\n const moduleAddress = await moduleContracts[module.name];\n if (!moduleAddress) throw new Error(`Module ${module.name} not found`);\n // Resolve arguments\n const resolvedArgs = module.args.map((arg) =>\n resolveWithContext(arg, {\n tableIds,\n })\n );\n const values = resolvedArgs.map((arg) => arg.value);\n const types = resolvedArgs.map((arg) => arg.type);\n\n return {\n func: module.root ? \"installRootModule\" : \"installModule\",\n args: [moduleAddress, defaultAbiCoder.encode(types, values)],\n };\n}\n","import { Module } from \"./types\";\n\nexport function getUserModules(defaultModules: { name: string }[], configModules: Module[]): Omit<Module, \"address\">[] {\n return configModules.filter((module) => !defaultModules.some((m) => m.name === module.name));\n}\n","import { System } from \"./types\";\nimport { CallData } from \"../utils/types\";\nimport { tableIdToHex } from \"@latticexyz/common\";\n\nexport async function getGrantAccessCallData(input: {\n systems: System[];\n systemContracts: Record<string, Promise<string>>;\n namespace: string;\n}): Promise<CallData[]> {\n const { systems, namespace, systemContracts } = input;\n const calls: CallData[] = [];\n for (const { name, accessListAddresses, accessListSystems } of systems) {\n // Grant access to addresses\n accessListAddresses.map(async (address) => calls.push(getGrantSystemAccessCallData(name, namespace, address)));\n\n // Grant access to other systems\n accessListSystems.map(async (granteeSystem) =>\n calls.push(getGrantSystemAccessCallData(name, namespace, await systemContracts[granteeSystem]))\n );\n }\n return calls;\n}\n\nfunction getGrantSystemAccessCallData(name: string, namespace: string, address: string): CallData {\n return {\n func: \"grantAccess\",\n args: [tableIdToHex(namespace, name), address],\n };\n}\n","import { tableIdToHex } from \"@latticexyz/common\";\nimport { System } from \"./types\";\nimport { loadFunctionSignatures, toFunctionSelector } from \"./utils\";\nimport { CallData } from \"../utils/types\";\n\nexport function getRegisterFunctionSelectorsCallData(input: {\n systemName: string;\n system: System;\n namespace: string;\n forgeOutDirectory: string;\n}): CallData[] {\n // Register system at route\n const callData: CallData[] = [];\n const { systemName, namespace, forgeOutDirectory, system } = input;\n\n if (system.registerFunctionSelectors) {\n const baseSystemFunctionNames = loadFunctionSignatures(\"System\", forgeOutDirectory).map((sig) => sig.functionName);\n const functionSignatures = loadFunctionSignatures(systemName, forgeOutDirectory).filter(\n (sig) => systemName === \"System\" || !baseSystemFunctionNames.includes(sig.functionName)\n );\n const isRoot = namespace === \"\";\n for (const { functionName, functionArgs } of functionSignatures) {\n callData.push(\n getRegisterFunctionSelectorCallData({\n namespace,\n name: system.name,\n systemName,\n functionName,\n functionArgs,\n isRoot,\n })\n );\n }\n }\n return callData;\n}\n\nfunction getRegisterFunctionSelectorCallData(input: {\n namespace: string;\n name: string;\n systemName: string;\n functionName: string;\n functionArgs: string;\n isRoot: boolean;\n}): CallData {\n const { namespace, name, systemName, functionName, functionArgs, isRoot } = input;\n const functionSignature = isRoot\n ? functionName + functionArgs\n : `${namespace}_${name}_${functionName}${functionArgs}`;\n\n if (isRoot) {\n const worldFunctionSelector = toFunctionSelector(\n functionSignature === \"\"\n ? { functionName: systemName, functionArgs } // Register the system's fallback function as `<systemName>(<args>)`\n : { functionName, functionArgs }\n );\n const systemFunctionSelector = toFunctionSelector({ functionName, functionArgs });\n return {\n func: \"registerRootFunctionSelector\",\n args: [tableIdToHex(namespace, name), worldFunctionSelector, systemFunctionSelector],\n };\n } else {\n return {\n func: \"registerRootFunctionSelector\",\n args: [tableIdToHex(namespace, name), functionName, functionArgs],\n };\n }\n}\n","import { ethers } from \"ethers\";\nimport { ParamType } from \"ethers/lib/utils.js\";\nimport { FunctionSignature } from \"./types\";\nimport { getContractData } from \"../utils/getContractData\";\n\nexport function loadFunctionSignatures(contractName: string, forgeOutDirectory: string): FunctionSignature[] {\n const { abi } = getContractData(contractName, forgeOutDirectory);\n\n return abi\n .filter((item) => [\"fallback\", \"function\"].includes(item.type))\n .map((item) => {\n if (item.type === \"fallback\") return { functionName: \"\", functionArgs: \"\" };\n\n return {\n functionName: item.name,\n functionArgs: parseComponents(item.inputs),\n };\n });\n}\n\n// TODO: move this to utils as soon as utils are usable inside cli\n// (see https://github.com/latticexyz/mud/issues/499)\nexport function toFunctionSelector({ functionName, functionArgs }: FunctionSignature): string {\n const functionSignature = functionName + functionArgs;\n if (functionSignature === \"\") return \"0x\";\n return sigHash(functionSignature);\n}\n\n/**\n * Recursively turn (nested) structs in signatures into tuples\n */\nfunction parseComponents(params: ParamType[]): string {\n const components = params.map((param) => {\n const tupleMatch = param.type.match(/tuple(.*)/);\n if (tupleMatch) {\n // there can be arrays of tuples,\n // `tupleMatch[1]` preserves the array brackets (or is empty string for non-arrays)\n return parseComponents(param.components) + tupleMatch[1];\n } else {\n return param.type;\n }\n });\n return `(${components})`;\n}\n\n// TODO: move this to utils as soon as utils are usable inside cli\n// (see https://github.com/latticexyz/mud/issues/499)\nfunction sigHash(signature: string) {\n return ethers.utils.hexDataSlice(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(signature)), 0, 4);\n}\n","import { tableIdToHex } from \"@latticexyz/common\";\nimport { System } from \"./types\";\nimport { CallData } from \"../utils/types\";\n\nexport async function getRegisterSystemCallData(input: {\n systemContracts: Record<string, Promise<string>>;\n systemName: string;\n system: System;\n namespace: string;\n}): Promise<CallData> {\n const { namespace, systemName, systemContracts, system } = input;\n const systemAddress = await systemContracts[systemName];\n return {\n func: \"registerSystem\",\n args: [tableIdToHex(namespace, system.name), systemAddress, system.openAccess],\n };\n}\n","import { encodeSchema, getStaticByteLength } from \"@latticexyz/schema-type/deprecated\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { resolveAbiOrUserType } from \"@latticexyz/store/codegen\";\nimport { tableIdToHex } from \"@latticexyz/common\";\nimport { Table } from \"./types\";\nimport { fieldLayoutToHex } from \"@latticexyz/protocol-parser\";\nimport { CallData } from \"../utils/types\";\n\nexport function getRegisterTableCallData(table: Table, storeConfig: StoreConfig): CallData {\n const { name, valueSchema, keySchema } = table;\n if (!name) throw Error(\"Table missing name\");\n\n const schemaTypes = Object.values(valueSchema).map((abiOrUserType) => {\n const { schemaType } = resolveAbiOrUserType(abiOrUserType, storeConfig);\n return schemaType;\n });\n\n const schemaTypeLengths = schemaTypes.map((schemaType) => getStaticByteLength(schemaType));\n const fieldLayout = {\n staticFieldLengths: schemaTypeLengths.filter((schemaTypeLength) => schemaTypeLength > 0),\n numDynamicFields: schemaTypeLengths.filter((schemaTypeLength) => schemaTypeLength === 0).length,\n };\n\n const keyTypes = Object.values(keySchema).map((abiOrUserType) => {\n const { schemaType } = resolveAbiOrUserType(abiOrUserType, storeConfig);\n return schemaType;\n });\n\n return {\n func: \"registerTable\",\n args: [\n tableIdToHex(storeConfig.namespace, name),\n fieldLayoutToHex(fieldLayout),\n encodeSchema(keyTypes),\n encodeSchema(schemaTypes),\n Object.keys(keySchema),\n Object.keys(valueSchema),\n ],\n };\n}\n","// TODO: use stringToBytes16 from utils as soon as utils are usable inside cli\n// (see https://github.com/latticexyz/mud/issues/499)\nexport function toBytes16(input: string) {\n if (input.length > 16) throw new Error(\"String does not fit into 16 bytes\");\n\n const result = new Uint8Array(16);\n // Set ascii bytes\n for (let i = 0; i < input.length; i++) {\n result[i] = input.charCodeAt(i);\n }\n // Set the remaining bytes to 0\n for (let i = input.length; i < 16; i++) {\n result[i] = 0;\n }\n return result;\n}\n","import { StoreConfig } from \"@latticexyz/store\";\nimport { TableIds } from \"./types\";\nimport { toBytes16 } from \"../utils/toBytes16\";\n\nexport function getTableIds(storeConfig: StoreConfig): TableIds {\n const tableIds: TableIds = {};\n for (const [tableName, { name }] of Object.entries(storeConfig.tables)) {\n tableIds[tableName] = toResourceSelector(storeConfig.namespace, name);\n }\n return tableIds;\n}\n\n// (see https://github.com/latticexyz/mud/issues/499)\nfunction toResourceSelector(namespace: string, file: string): Uint8Array {\n const namespaceBytes = toBytes16(namespace);\n const fileBytes = toBytes16(file);\n const result = new Uint8Array(32);\n result.set(namespaceBytes);\n result.set(fileBytes, 16);\n return result;\n}\n","import chalk from \"chalk\";\nimport { Wallet } from \"ethers\";\nimport { MUDError } from \"@latticexyz/common/errors\";\n\nexport async function confirmNonce(signer: Wallet, nonce: number, pollInterval: number): Promise<void> {\n let remoteNonce = await signer.getTransactionCount();\n let retryCount = 0;\n const maxRetries = 100;\n while (remoteNonce !== nonce && retryCount < maxRetries) {\n console.log(\n chalk.gray(\n `Waiting for transactions to be included before executing postDeployScript (local nonce: ${nonce}, remote nonce: ${remoteNonce}, retry number ${retryCount}/${maxRetries})`\n )\n );\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n retryCount++;\n remoteNonce = await signer.getTransactionCount();\n }\n if (remoteNonce !== nonce) {\n throw new MUDError(\n \"Remote nonce doesn't match local nonce, indicating that not all deploy transactions were included.\"\n );\n }\n}\n","import chalk from \"chalk\";\nimport { TransactionReceipt, TransactionResponse } from \"@ethersproject/providers\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { TxConfig } from \"./types\";\n\n/**\n * Only await gas estimation (for speed), only execute if gas estimation succeeds (for safety)\n */\nexport async function fastTxExecute<\n C extends { connect: any; estimateGas: any; [key: string]: any },\n F extends keyof C\n>(\n input: TxConfig & {\n nonce: number;\n contract: C;\n func: F;\n args: Parameters<C[F]>;\n confirmations: number;\n }\n): Promise<TransactionResponse | TransactionReceipt> {\n const {\n func,\n args,\n contract,\n signer,\n nonce,\n maxPriorityFeePerGas,\n maxFeePerGas,\n gasPrice,\n confirmations = 1,\n debug,\n } = input;\n const functionName = `${func as string}(${args.map((arg) => `'${arg}'`).join(\",\")})`;\n try {\n const contractWithSigner = contract.connect(signer);\n const gasLimit = await contractWithSigner.estimateGas[func].apply(null, args);\n console.log(chalk.gray(`executing transaction: ${functionName} with nonce ${nonce}`));\n return contractWithSigner[func]\n .apply(null, [\n ...args,\n {\n gasLimit,\n nonce: nonce,\n maxPriorityFeePerGas: maxPriorityFeePerGas,\n maxFeePerGas: maxFeePerGas,\n gasPrice: gasPrice,\n },\n ])\n .then((tx: TransactionResponse) => {\n return confirmations === 0 ? tx : tx.wait(confirmations);\n });\n } catch (error: any) {\n if (debug) console.error(error);\n throw new MUDError(`Gas estimation error for ${functionName}: ${error?.reason}`);\n }\n}\n","import { existsSync } from \"fs\";\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport { getScriptDirectory, forge } from \"@latticexyz/common/foundry\";\n\nexport async function postDeploy(\n postDeployScript: string,\n worldAddress: string,\n rpc: string,\n profile: string | undefined\n): Promise<void> {\n // Execute postDeploy forge script\n const postDeployPath = path.join(await getScriptDirectory(), postDeployScript + \".s.sol\");\n if (existsSync(postDeployPath)) {\n console.log(chalk.blue(`Executing post deploy script at ${postDeployPath}`));\n await forge(\n [\"script\", postDeployScript, \"--sig\", \"run(address)\", worldAddress, \"--broadcast\", \"--rpc-url\", rpc, \"-vvv\"],\n {\n profile: profile,\n }\n );\n } else {\n console.log(`No script at ${postDeployPath}, skipping post deploy hook`);\n }\n}\n","import { BigNumber, Wallet } from \"ethers\";\nimport { MUDError } from \"@latticexyz/common/errors\";\n\n/**\n * Set the maxFeePerGas and maxPriorityFeePerGas based on the current base fee and the given multiplier.\n * The multiplier is used to allow replacing pending transactions.\n * @param multiplier Multiplier to apply to the base fee\n */\nexport async function setInternalFeePerGas(\n signer: Wallet,\n multiplier: number\n): Promise<{\n maxPriorityFeePerGas: number | undefined;\n maxFeePerGas: BigNumber | undefined;\n gasPrice: BigNumber | undefined;\n}> {\n // Compute maxFeePerGas and maxPriorityFeePerGas like ethers, but allow for a multiplier to allow replacing pending transactions\n const feeData = await signer.provider.getFeeData();\n let maxPriorityFeePerGas: number | undefined;\n let maxFeePerGas: BigNumber | undefined;\n let gasPrice: BigNumber | undefined;\n\n if (feeData.lastBaseFeePerGas) {\n if (!feeData.lastBaseFeePerGas.eq(0) && (await signer.getBalance()).eq(0)) {\n throw new MUDError(`Attempting to deploy to a chain with non-zero base fee with an account that has no balance.\n If you're deploying to the Lattice testnet, you can fund your account by running 'pnpm mud faucet --address ${await signer.getAddress()}'`);\n }\n\n // Set the priority fee to 0 for development chains with no base fee, to allow transactions from unfunded wallets\n maxPriorityFeePerGas = feeData.lastBaseFeePerGas.eq(0) ? 0 : Math.floor(1_500_000_000 * multiplier);\n maxFeePerGas = feeData.lastBaseFeePerGas.mul(2).add(maxPriorityFeePerGas);\n } else if (feeData.gasPrice) {\n // Legacy chains with gasPrice instead of maxFeePerGas\n if (!feeData.gasPrice.eq(0) && (await signer.getBalance()).eq(0)) {\n throw new MUDError(\n `Attempting to deploy to a chain with non-zero gas price with an account that has no balance.`\n );\n }\n\n gasPrice = feeData.gasPrice;\n } else {\n throw new MUDError(\"Can not fetch fee data from RPC\");\n }\n return {\n maxPriorityFeePerGas,\n maxFeePerGas,\n gasPrice,\n };\n}\n","import glob from \"glob\";\nimport { basename } from \"path\";\n\n/**\n * Get a list of all contract paths/names within the provided src directory\n */\nexport function getExistingContracts(srcDir: string) {\n return glob.sync(`${srcDir}/**/*.sol`).map((path) => ({\n path,\n basename: basename(path, \".sol\"),\n }));\n}\n","import { ethers } from \"ethers\";\n\n// TODO: Use viem's getChainId\nexport async function getChainId(rpc: string) {\n const { result: chainId } = await ethers.utils.fetchJson(\n rpc,\n '{ \"id\": 42, \"jsonrpc\": \"2.0\", \"method\": \"eth_chainId\", \"params\": [ ] }'\n );\n return Number(chainId);\n}\n"],"mappings":"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","names":["chalk","path","MUDError","loadConfig","chalk","ethers","getOutDirectory","cast","resolveWorldConfig","chalk","WorldData","IBaseWorldAbi","chalk","ethers","MUDError","deployContract","input","signer","nonce","maxPriorityFeePerGas","maxFeePerGas","debug","gasPrice","confirmations","contract","factory","deployPromise","c","address","error","readFileSync","path","MUDError","getContractData","contractName","forgeOutDirectory","data","contractDataPath","bytecode","abi","deployWorldContract","ip","chalk","contractData","getContractData","IBaseWorldAbi","WorldData","deployContract","IBaseWorldAbi","CoreModuleData","KeysWithValueModuleData","KeysInTableModuleData","UniqueEntityModuleData","defaultModuleContracts","defaultAbiCoder","resolveWithContext","getInstallModuleCallData","moduleContracts","module","tableIds","moduleAddress","resolvedArgs","arg","values","types","getUserModules","defaultModules","configModules","module","m","tableIdToHex","getGrantAccessCallData","input","systems","namespace","systemContracts","calls","name","accessListAddresses","accessListSystems","address","getGrantSystemAccessCallData","granteeSystem","tableIdToHex","ethers","loadFunctionSignatures","contractName","forgeOutDirectory","abi","getContractData","item","parseComponents","toFunctionSelector","functionName","functionArgs","functionSignature","sigHash","params","param","tupleMatch","signature","ethers","getRegisterFunctionSelectorsCallData","input","callData","systemName","namespace","forgeOutDirectory","system","baseSystemFunctionNames","loadFunctionSignatures","sig","functionSignatures","isRoot","functionName","functionArgs","getRegisterFunctionSelectorCallData","name","functionSignature","worldFunctionSelector","toFunctionSelector","systemFunctionSelector","tableIdToHex","tableIdToHex","getRegisterSystemCallData","input","namespace","systemName","systemContracts","system","systemAddress","encodeSchema","getStaticByteLength","resolveAbiOrUserType","tableIdToHex","fieldLayoutToHex","getRegisterTableCallData","table","storeConfig","name","valueSchema","keySchema","schemaTypes","abiOrUserType","schemaType","schemaTypeLengths","fieldLayout","schemaTypeLength","keyTypes","toBytes16","input","result","i","getTableIds","storeConfig","tableIds","tableName","name","toResourceSelector","namespace","file","namespaceBytes","toBytes16","fileBytes","result","chalk","MUDError","confirmNonce","signer","nonce","pollInterval","remoteNonce","retryCount","maxRetries","resolve","chalk","MUDError","fastTxExecute","input","func","args","contract","signer","nonce","maxPriorityFeePerGas","maxFeePerGas","gasPrice","confirmations","debug","functionName","arg","contractWithSigner","gasLimit","tx","error","existsSync","path","chalk","getScriptDirectory","forge","postDeploy","postDeployScript","worldAddress","rpc","profile","postDeployPath","MUDError","setInternalFeePerGas","signer","multiplier","feeData","maxPriorityFeePerGas","maxFeePerGas","gasPrice","deploy","mudConfig","existingContractNames","deployConfig","startTime","profile","rpc","privateKey","priorityFeeMultiplier","debug","worldAddress","disableTxWait","pollInterval","resolvedConfig","resolveWorldConfig","forgeOutDirectory","getOutDirectory","provider","ethers","signer","nonce","txConfig","setInternalFeePerGas","blockNumber","cast","worldPromise","deployWorldContract","userModules","getUserModules","defaultModuleContracts","userModuleContracts","name","abi","bytecode","getContractData","systemContracts","deployedContracts","CoreModuleData","acc","contract","deployContract","deployedWorldAddress","worldContract","IBaseWorldAbi","chalk","fastTxExecute","toBytes16","tableIds","getTableIds","registerTableCalls","table","getRegisterTableCallData","call","systemCalls","systemName","system","getRegisterSystemCallData","functionCalls","getRegisterFunctionSelectorsCallData","grantCalls","getGrantAccessCallData","moduleCalls","m","getInstallModuleCallData","confirmNonce","postDeploy","forge","getRpcUrl","getSrcDirectory","existsSync","mkdirSync","readFileSync","writeFileSync","glob","basename","getExistingContracts","srcDir","path","execa","ethers","getChainId","rpc","chainId","deployHandler","args","configPath","printConfig","profile","clean","skipBuild","rpc","getRpcUrl","chalk","forge","execa","srcDir","getSrcDirectory","existingContractNames","getExistingContracts","basename","mudConfig","loadConfig","privateKey","MUDError","deploymentInfo","deploy","chainId","getChainId","outputDir","path","mkdirSync","writeFileSync","localChains","deploys","existsSync","readFileSync"]}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as o}from"./chunk-
|
|
1
|
+
import{c as o}from"./chunk-3LOTLAJX.js";export{o as deployHandler};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/mud.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as
|
|
2
|
+
import{a as M,b as R,c as w}from"./chunk-3LOTLAJX.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 de}from"fs";import{homedir as le}from"os";import pe from"path";import{execa as me}from"execa";var fe={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=le();de(pe.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=me("anvil",t,{stdio:["inherit","inherit","inherit"]});process.on("SIGINT",()=>{console.log(`
|
|
3
3
|
gracefully shutting down from SIGINT (Crtl-C)`),r.kill(),process.exit()}),await r}},$=fe;import{FaucetServiceDefinition as ge}from"@latticexyz/services/faucet";import{createChannel as ue,createClient as ye}from"nice-grpc-web";import W from"chalk";import{NodeHttpTransport as he}from"@improbable-eng/grpc-web-node-http-transport";function be(e){return ye(ge,ue(e,he()))}var we={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=be(o);e&&(console.log(W.yellow("Dripping to",t)),await r.dripDev({address:t}),console.log(W.yellow("Success"))),process.exit(0)}},A=we;var ve={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)}},E=ve;import De from"path";import{loadConfig as Ce}from"@latticexyz/config/node";import{tablegen as ke}from"@latticexyz/store/codegen";import{getSrcDirectory as xe}from"@latticexyz/common/foundry";var Me={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 Ce(e),t=await xe();await ke(o,De.join(t,o.codegenDirectory)),process.exit(0)}},I=Me;import D from"chalk";import{ZodError as Se}from"zod";import{fromZodError as Oe,ValidationError as Ue}from"zod-validation-error";import{NotInsideProjectError as je}from"@latticexyz/config";import{MUDError as Pe}from"@latticexyz/common/errors";function g(e){if(e instanceof Ue)console.log(D.redBright(e.message));else if(e instanceof Se){let o=Oe(e,{prefixSeparator:`
|
|
4
4
|
- `,issueSeparator:`
|
|
5
|
-
- `});console.log(D.redBright(o.message))}else e instanceof je?(console.log(D.red(e.message)),console.log(""),console.log(D.blue("To learn more about MUD's configuration, please go to https://mud.dev/packages/cli/"))):e instanceof Pe?console.log(D.red(e)):console.log(e)}
|
|
5
|
+
- `});console.log(D.redBright(o.message))}else e instanceof je?(console.log(D.red(e.message)),console.log(""),console.log(D.blue("To learn more about MUD's configuration, please go to https://mud.dev/packages/cli/"))):e instanceof Pe?console.log(D.red(e)):console.log(e)}var U={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"}},Re={command:"deploy",describe:"Deploy MUD contracts",builder(e){return e.options(U)},async handler(e){try{await w(e)}catch(o){g(o),process.exit(1)}process.exit(0)}},F=Re;import{loadConfig as $e}from"@latticexyz/config/node";import{worldgen as We}from"@latticexyz/world/node";import{getSrcDirectory as Ae}from"@latticexyz/common/foundry";import T from"path";import{rmSync as Ee}from"fs";var Ie={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 j(e),process.exit(0)}};async function j(e){let o=e.srcDir??await Ae(),t=M(o),r=e.config??await $e(e.configPath),i=T.join(o,r.codegenDirectory);e.clean&&Ee(T.join(i,r.worldgenDirectory),{recursive:!0,force:!0}),await We(r,t,i)}var z=Ie;import h from"chalk";import{existsSync as Te,readFileSync as ze,rmSync as Je,writeFileSync as H}from"fs";import k from"path";import{MUDError as b}from"@latticexyz/common/errors";var J={name:"@latticexyz/cli",version:"2.0.0-main-e0193e57",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","clean:js":"rimraf dist",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:*",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",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 He from"glob";var S=".mudbackup",C="@latticexyz",Ne={command:"set-version",describe:"Set MUD version in all package.json files and optionally backup the previously installed version",builder(e){return e.options({backup:{type:"boolean",description:`Back up the current MUD versions to "${S}"`},force:{type:"boolean",description:`Backup fails if a "${S}" file is found, unless --force is provided`},restore:{type:"boolean",description:`Restore the previous MUD versions from "${S}"`},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((i,c)=>e[c]?i+1:i,0);if(t===0)throw new b(`You need to provide one these options: ${o.join(", ")}`);if(t>1)throw new b(`These options are mutually exclusive: ${o.join(", ")}`);e.mudVersion=await Ve(e);let r=He.sync("**/package.json").filter(i=>!i.includes("node_modules"));for(let i of r)Be(i,e)}catch(o){g(o)}finally{process.exit(0)}}};async function Ve(e){e.mudVersion==="canary"&&(e.tag="main");let o;try{console.log(h.blue("Fetching available versions")),o=await(await fetch(`https://registry.npmjs.org/${J.name}`)).json()}catch{throw new b("Could not fetch available MUD versions")}if(e.tag){let t=o["dist-tags"][e.tag];if(!t)throw new b(`Could not find npm version with tag "${e.tag}"`);return console.log(h.green(`Latest version with tag ${e.tag}: ${t}`)),t}if(e.commit){let t=e.commit.substring(0,8),r=Object.keys(o.versions).find(i=>i.includes(t));if(!r)throw new b(`Could not find npm version based on commit "${e.commit}"`);return console.log(h.green(`Version from commit ${e.commit}: ${r}`)),r}return e.mudVersion}function Be(e,o){let{restore:t,force:r,link:i}=o,{backup:c,mudVersion:d}=o,a=k.join(k.dirname(e),S),v=Te(a);if(i&&!v&&(c=!0),c&&!r&&v)throw new b(`A backup file already exists at ${a}.
|
|
6
|
+
Use --force to overwrite it or --restore to restore it.`);let s=N(e),u=t?N(a):void 0,m={};for(let n in s.dependencies)n.startsWith(C)&&(m[n]=s.dependencies[n]);let y={};for(let n in s.devDependencies)n.startsWith(C)&&(y[n]=s.devDependencies[n]);c&&(H(a,JSON.stringify({dependencies:m,devDependencies:y},null,2)),console.log(h.green(`Backed up MUD dependencies from ${e} to ${a}`)));for(let n in s.dependencies)n.startsWith(C)&&(s.dependencies[n]=l(n,"dependencies"));for(let n in s.devDependencies)n.startsWith(C)&&(s.devDependencies[n]=l(n,"devDependencies"));return H(e,JSON.stringify(s,null,2)+`
|
|
7
|
+
`),console.log(`Updating ${e}`),V(m,s.dependencies),V(y,s.devDependencies),t&&!c&&(Je(a),console.log(h.green(`Cleaned up ${a}`))),s;function l(n,p){return t&&u?u[p][n]:(i&&(d=Le(e,i,n)),d||s[p][n])}}function N(e){try{let o=ze(e,"utf8");return JSON.parse(o)}catch{throw new b("Could not read JSON at "+e)}}function V(e,o){for(let t in e)e[t]!==o[t]&&console.log(`${t}: ${h.red(e[t])} -> ${h.green(o[t])}`)}function Le(e,o,t){let r=t.replace(C,""),i=k.relative(k.dirname(e),process.cwd());return"link:"+k.join(i,o,"packages",r)}var B=Ne;import{anvil as _e,forge as qe,getRpcUrl as Ge}from"@latticexyz/common/foundry";import Ye from"chalk";import{rmSync as L,writeFileSync as Ze}from"fs";var P=".mudtest",Ke={command:"test",describe:"Run tests in MUD contracts",builder(e){return e.options({...U,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 i=["--block-base-fee-per-gas","0","--port",String(e.port)];_e(i)}let o=e.worldAddress?await Ge(e.profile):`http://127.0.0.1:${e.port}`,t=e.worldAddress??(await w({...e,saveDeployment:!1,rpc:o})).worldAddress;console.log(Ye.blue("World address",t)),Ze(P,t);let r=e.forgeOptions?.replaceAll("\\","").split(" ")??[];try{let i=await qe(["test","--fork-url",o,...r],{profile:e.profile});console.log(i)}catch(i){console.error(i),L(P),process.exit(1)}L(P),process.exit(0)}},_=Ke;import{existsSync as Xe,readFileSync as Qe}from"fs";import{ethers as q}from"ethers";import{loadConfig as eo}from"@latticexyz/config/node";import{MUDError as G}from"@latticexyz/common/errors";import{cast as oo,getRpcUrl as to,getSrcDirectory as ro}from"@latticexyz/common/foundry";import{resolveWorldConfig as no}from"@latticexyz/world";import io from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import Y from"@latticexyz/world/mud.config.js";import{tableIdToHex as K}from"@latticexyz/common";var Z=K(Y.namespace,Y.tables.Systems.name),so={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 ro(o),e.rpc??=await to(o);let{tx:t,configPath:r,srcDir:i,rpc:c}=e,d=M(i),a=await eo(r),v=no(a,d.map(({basename:f})=>f)),s=e.worldAddress??await ao(a.worldsFile,c),u=new q.providers.StaticJsonRpcProvider(c),m=new q.Contract(s,io,u),y=a.namespace,l=Object.values(v.systems).map(({name:f})=>f),n=await m.getFieldLayout(Z),p=[];for(let f of l){let O=K(y,f),ce=await m.getField(Z,[O],0,n);p.push({name:f,address:ce})}let ae=await oo(["run","--label",`${s}:World`,...p.map(({name:f,address:O})=>["--label",`${O}:${f}`]).flat(),`${t}`]);console.log(ae),process.exit(0)}},X=so;async function ao(e,o){if(Xe(e)){let t=await R(o),r=JSON.parse(Qe(e,"utf-8"));if(!r[t])throw new G(`chainId ${t} is missing in worldsFile "${e}"`);return r[t].address}else throw new G("worldAddress is not specified and worldsFile is missing")}import{anvil as lo,forge as ee,getRpcUrl as po,getScriptDirectory as mo,getSrcDirectory as fo}from"@latticexyz/common/foundry";import x from"chalk";import go from"chokidar";import{loadConfig as oe,resolveConfigPath as uo}from"@latticexyz/config/node";import{tablegen as yo}from"@latticexyz/store/codegen";import te 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 co from"chalk";function Q(){console.log(co.yellow(`
|
|
6
8
|
.------..------..------.
|
|
7
9
|
|M.--. ||U.--. ||D.--. |
|
|
8
10
|
| (\\/) || (\\/) || :/\\: |
|
|
9
11
|
| :\\/: || :\\/: || (__) |
|
|
10
12
|
| '--'M|| '--'U|| '--'D|
|
|
11
13
|
'------''------''------'
|
|
12
|
-
`))}var
|
|
13
|
-
|
|
14
|
-
`),console.log(`Updating ${e}`),B(m,s.dependencies),B(y,s.devDependencies),t&&!c&&(He(a),console.log(h.green(`Cleaned up ${a}`))),s;function l(n,p){return t&&u?u[p][n]:(i&&(d=_e(e,i,n)),d||s[p][n])}}function V(e){try{let o=Je(e,"utf8");return JSON.parse(o)}catch{throw new b("Could not read JSON at "+e)}}function B(e,o){for(let t in e)e[t]!==o[t]&&console.log(`${t}: ${h.red(e[t])} -> ${h.green(o[t])}`)}function _e(e,o,t){let r=t.replace(C,""),i=k.relative(k.dirname(e),process.cwd());return"link:"+k.join(i,o,"packages",r)}var L=Ve;import{anvil as qe,forge as Ge,getRpcUrl as Ye}from"@latticexyz/common/foundry";import Ze from"chalk";import{rmSync as _,writeFileSync as Ke}from"fs";var P=".mudtest",Xe={command:"test",describe:"Run tests in MUD contracts",builder(e){return e.options({...U,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 i=["--block-base-fee-per-gas","0","--port",String(e.port)];qe(i)}let o=e.worldAddress?await Ye(e.profile):`http://127.0.0.1:${e.port}`,t=e.worldAddress??(await w({...e,saveDeployment:!1,rpc:o})).worldAddress;console.log(Ze.blue("World address",t)),Ke(P,t);let r=e.forgeOptions?.replaceAll("\\","").split(" ")??[];try{let i=await Ge(["test","--fork-url",o,...r],{profile:e.profile});console.log(i)}catch(i){console.error(i),_(P),process.exit(1)}_(P),process.exit(0)}},q=Xe;import{existsSync as Qe,readFileSync as eo}from"fs";import{ethers as G}from"ethers";import{loadConfig as oo}from"@latticexyz/config/node";import{MUDError as Y}from"@latticexyz/common/errors";import{cast as to,getRpcUrl as ro,getSrcDirectory as no}from"@latticexyz/common/foundry";import{resolveWorldConfig as io}from"@latticexyz/world";import so from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import Z from"@latticexyz/world/mud.config.js";import{tableIdToHex as X}from"@latticexyz/common";var K=X(Z.namespace,Z.tables.Systems.name),ao={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 no(o),e.rpc??=await ro(o);let{tx:t,configPath:r,srcDir:i,rpc:c}=e,d=M(i),a=await oo(r),v=io(a,d.map(({basename:f})=>f)),s=e.worldAddress??await co(a.worldsFile,c),u=new G.providers.StaticJsonRpcProvider(c),m=new G.Contract(s,so,u),y=a.namespace,l=Object.values(v.systems).map(({name:f})=>f),n=await m.getFieldLayout(K),p=[];for(let f of l){let O=X(y,f),ce=await m.getField(K,[O],0,n);p.push({name:f,address:ce})}let ae=await to(["run","--label",`${s}:World`,...p.map(({name:f,address:O})=>["--label",`${O}:${f}`]).flat(),`${t}`]);console.log(ae),process.exit(0)}},Q=ao;async function co(e,o){if(Qe(e)){let t=await R(o),r=JSON.parse(eo(e,"utf-8"));if(!r[t])throw new Y(`chainId ${t} is missing in worldsFile "${e}"`);return r[t].address}else throw new Y("worldAddress is not specified and worldsFile is missing")}import{anvil as lo,forge as ee,getRpcUrl as po,getScriptDirectory as mo,getSrcDirectory as fo}from"@latticexyz/common/foundry";import x from"chalk";import go from"chokidar";import{loadConfig as oe,resolveConfigPath as uo}from"@latticexyz/config/node";import{tablegen as yo}from"@latticexyz/store/codegen";import te 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";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 ee(["clean"]);let o=e.rpc??await po(),t=e.configPath??await uo(e.configPath),r=await fo(),i=await mo(),c=await oe(t);if(await u(c),await m(c),!e.rpc){console.log(x.gray("Cleaning devnode cache"));let l=bo();wo(te.join(l,".foundry","anvil","tmp"),{recursive:!0,force:!0}),lo(["--block-time","1","--block-base-fee-per-gas","0"])}let d={config:!1,contracts:!1},a={current:!1};go.watch([t,r]).on("all",async(l,n)=>{if(n.includes(t)&&(d.config=!0,d.contracts=!0),n.includes(r)||n.includes(i)){if(n.includes(c.codegenDirectory))return;d.contracts=!0}s()});let s=ho(100,async()=>{if(a.current)return;a.current=!0;let{config:l,contracts:n}=d;d.config=!1,d.contracts=!1;try{let p=await oe(t);l&&await u(p),n&&await m(p),await y()}catch(p){console.error(x.red(`MUD dev-contracts watcher failed to deploy config or contracts changes
|
|
15
|
-
`)),g(p)}a.current=!1,(d.config||d.contracts)&&(console.log("Detected change while handling the previous change"),s()),F(),console.log("MUD watching for changes...")});async function u(l){console.log(x.blue("mud.config.ts changed - regenerating tables and recs types"));let n=te.join(r,l.codegenDirectory);await yo(l,n)}async function m(l){console.log(x.blue("contracts changed - regenerating interfaces and contract types")),await j({config:l,clean:!0,srcDir:r}),await ee(["build","--skip","test","script"]),await vo("mud",["abi-ts"],{stdio:"inherit"})}async function y(){console.log(x.blue("redeploying World")),await w({configPath:t,skipBuild:!0,priorityFeeMultiplier:1,disableTxWait:!0,pollInterval:1e3,saveDeployment:!0,srcDir:r,rpc:o})}}},re=Do;var ne=[T,$,A,Co,E,I,J,L,q,Q,re,ko];import*as se from"dotenv";import ie from"chalk";se.config();xo(Mo(process.argv)).scriptName("mud").command(ne).strict().fail((e,o)=>{console.error(ie.red(e)),e.includes("Missing required argument")&&console.log(ie.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`)),console.log(""),o!=null&&(g(o),console.log("")),process.exit(1)}).alias({h:"help"}).argv;
|
|
14
|
+
`))}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 ee(["clean"]);let o=e.rpc??await po(),t=e.configPath??await uo(e.configPath),r=await fo(),i=await mo(),c=await oe(t);if(await u(c),await m(c),!e.rpc){console.log(x.gray("Cleaning devnode cache"));let l=bo();wo(te.join(l,".foundry","anvil","tmp"),{recursive:!0,force:!0}),lo(["--block-time","1","--block-base-fee-per-gas","0"])}let d={config:!1,contracts:!1},a={current:!1};go.watch([t,r]).on("all",async(l,n)=>{if(n.includes(t)&&(d.config=!0,d.contracts=!0),n.includes(r)||n.includes(i)){if(n.includes(c.codegenDirectory))return;d.contracts=!0}s()});let s=ho(100,async()=>{if(a.current)return;a.current=!0;let{config:l,contracts:n}=d;d.config=!1,d.contracts=!1;try{let p=await oe(t);l&&await u(p),n&&await m(p),await y()}catch(p){console.error(x.red(`MUD dev-contracts watcher failed to deploy config or contracts changes
|
|
15
|
+
`)),g(p)}a.current=!1,(d.config||d.contracts)&&(console.log("Detected change while handling the previous change"),s()),Q(),console.log("MUD watching for changes...")});async function u(l){console.log(x.blue("mud.config.ts changed - regenerating tables and recs types"));let n=te.join(r,l.codegenDirectory);await yo(l,n)}async function m(l){console.log(x.blue("contracts changed - regenerating interfaces and contract types")),await j({config:l,clean:!0,srcDir:r}),await ee(["build","--skip","test","script"]),await vo("mud",["abi-ts"],{stdio:"inherit"})}async function y(){console.log(x.blue("redeploying World")),await w({configPath:t,skipBuild:!0,priorityFeeMultiplier:1,disableTxWait:!0,pollInterval:1e3,saveDeployment:!0,srcDir:r,rpc:o})}}},re=Do;var ne=[F,$,A,Co,E,I,z,B,_,X,re,ko];import*as se from"dotenv";import ie from"chalk";se.config();xo(Mo(process.argv)).scriptName("mud").command(ne).strict().fail((e,o)=>{console.error(ie.red(e)),e.includes("Missing required argument")&&console.log(ie.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`)),console.log(""),o!=null&&(g(o),console.log("")),process.exit(1)}).alias({h:"help"}).argv;
|
|
16
16
|
//# sourceMappingURL=mud.js.map
|