@latticexyz/cli 2.0.0-next.5 → 2.0.0-next.7

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.
@@ -0,0 +1,11 @@
1
+ import W from"chalk";import Y from"path";import{MUDError as Ee}from"@latticexyz/common/errors";import{loadConfig as Oe}from"@latticexyz/config/node";import{existsSync as Ce,readFileSync as De}from"fs";import ne from"path";import s from"chalk";import{ethers as M}from"ethers";import{defaultAbiCoder as Se}from"ethers/lib/utils.js";import{getOutDirectory as Fe,getScriptDirectory as ve,cast as xe,forge as Ie}from"@latticexyz/common/foundry";import{resolveWithContext as Re}from"@latticexyz/config";import{MUDError as h}from"@latticexyz/common/errors";import{encodeSchema as re}from"@latticexyz/schema-type/deprecated";import{resolveAbiOrUserType as ie}from"@latticexyz/store/codegen";import{resolveWorldConfig as Me}from"@latticexyz/world";import se from"@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json"assert{type:"json"};import je from"@latticexyz/world/abi/World.sol/World.json"assert{type:"json"};import ae from"@latticexyz/world/abi/CoreModule.sol/CoreModule.json"assert{type:"json"};import le from"@latticexyz/world/abi/KeysWithValueModule.sol/KeysWithValueModule.json"assert{type:"json"};import ce from"@latticexyz/world/abi/KeysInTableModule.sol/KeysInTableModule.json"assert{type:"json"};import de from"@latticexyz/world/abi/UniqueEntityModule.sol/UniqueEntityModule.json"assert{type:"json"};import{tableIdToHex as j}from"@latticexyz/common";async function pe(r,p,u){let m=Me(r,p),x=Date.now(),{worldContractName:B,namespace:a,postDeployScript:k}=r,{profile:A,rpc:y,privateKey:E,priorityFeeMultiplier:b,debug:S,worldAddress:F,disableTxWait:f,pollInterval:T}=u,fe=await Fe(A),N=new M.providers.StaticJsonRpcProvider(y);N.pollingInterval=T;let $=new M.Wallet(E,N);console.log("Deploying from",$.address);let v=await $.getTransactionCount();console.log("Initial nonce",v);let O,U,K;await L(b);let d=[],z=Number(await xe(["block-number","--rpc-url",y],{profile:A}));console.log("Start deployment at block",z);let be={World:F?Promise.resolve(F):B?J(B,f):R(se.abi,je.bytecode,f,"World")},we=Object.keys(m.systems).reduce((e,t)=>(e[t]=J(t,f),e),{}),Q={CoreModule:R(ae.abi,ae.bytecode,f,"CoreModule"),KeysWithValueModule:R(le.abi,le.bytecode,f,"KeysWithValueModule"),KeysInTableModule:R(ce.abi,ce.bytecode,f,"KeysInTableModule"),UniqueEntityModule:R(de.abi,de.bytecode,f,"UniqueEntityModule")},X=r.modules.filter(e=>!Q[e.name]).reduce((e,t)=>(e[t.name]=J(t.name,f),e),Q),I={...be,...we,...X},P=new M.Contract(await I.World,se.abi,$),C=f?0:1;F||(console.log(s.blue("Installing core World modules")),await w(P,"installRootModule",[await X.CoreModule,"0x"],C),console.log(s.green("Installed core World modules"))),a&&await w(P,"registerNamespace",[V(a)],C);let Z={};d=[...d,...Object.entries(r.tables).map(async([e,{name:t,schema:o,keySchema:i}])=>{console.log(s.blue(`Registering table ${e} at ${a}/${t}`)),Z[e]=ke(a,t);let c=Object.values(o).map(l=>{let{schemaType:g}=ie(l,r);return g}),n=Object.values(i).map(l=>{let{schemaType:g}=ie(l,r);return g});await w(P,"registerTable",[j(a,t),re(n),re(c),Object.keys(i),Object.keys(o)],C),console.log(s.green(`Registered table ${e} at ${t}`))})],d=[...d,...Object.entries(m.systems).map(async([e,{name:t,openAccess:o,registerFunctionSelectors:i}])=>{if(console.log(s.blue(`Registering system ${e} at ${a}/${t}`)),await w(P,"registerSystem",[j(a,t),await I[e],o],C),console.log(s.green(`Registered system ${e} at ${a}/${t}`)),i){let c=await he(e),n=a==="";await Promise.all(c.map(async({functionName:l,functionArgs:g})=>{let D=n?l+g:`${a}_${t}_${l}${g}`;if(console.log(s.blue(`Registering function "${D}"`)),n){let $e=ue(D===""?{functionName:e,functionArgs:g}:{functionName:l,functionArgs:g}),Pe=ue({functionName:l,functionArgs:g});await w(P,"registerRootFunctionSelector",[j(a,t),$e,Pe],C)}else await w(P,"registerFunctionSelector",[j(a,t),l,g],C);console.log(s.green(`Registered function "${D}"`))}))}})],await Promise.all(d),d=[];for(let[e,{name:t,accessListAddresses:o,accessListSystems:i}]of Object.entries(m.systems)){let c=`${a}/${t}`;d=[...d,...o.map(async n=>{console.log(s.blue(`Grant ${n} access to ${e} (${c})`)),await w(P,"grantAccess",[j(a,t),n],C),console.log(s.green(`Granted ${n} access to ${e} (${a}/${t})`))})],d=[...d,...i.map(async n=>{console.log(s.blue(`Grant ${n} access to ${e} (${c})`)),await w(P,"grantAccess",[j(a,t),await I[n]],C),console.log(s.green(`Granted ${n} access to ${e} (${c})`))})]}await Promise.all(d),d=[],d=[...d,...r.modules.map(async e=>{console.log(s.blue(`Installing${e.root?" root ":" "}module ${e.name}`));let t=await Promise.all(e.args.map(n=>Re(n,{tableIds:Z,systemAddresses:I}))),o=t.map(n=>n.value),i=t.map(n=>n.type),c=await I[e.name];if(!c)throw new Error(`Module ${e.name} not found`);await w(P,e.root?"installRootModule":"installModule",[c,Se.encode(i,o)],C),console.log(s.green(`Installed${e.root?" root ":" "}module ${e.name}`))})],await Promise.all(d);let G=await $.getTransactionCount(),_=0,ee=100;for(;G!==v&&_<ee;)console.log(s.gray(`Waiting for transactions to be included before executing ${k} (local nonce: ${v}, remote nonce: ${G}, retry number ${_}/${ee})`)),await new Promise(e=>setTimeout(e,T)),_++,G=await $.getTransactionCount();if(G!==v)throw new h("Remote nonce doesn't match local nonce, indicating that not all deploy transactions were included.");d=[];let q=ne.join(await ve(),k+".s.sol");return Ce(q)?(console.log(s.blue(`Executing post deploy script at ${q}`)),await Ie(["script",k,"--sig","run(address)",await I.World,"--broadcast","--rpc-url",y,"-vvv"],{profile:A})):console.log(`No script at ${q}, skipping post deploy hook`),console.log(s.green("Deployment completed in",(Date.now()-x)/1e3,"seconds")),{worldAddress:await I.World,blockNumber:z};async function J(e,t){console.log(s.blue("Deploying",e));let{abi:o,bytecode:i}=await oe(e);return R(o,i,t,e)}async function R(e,t,o,i,c=0){try{let n=new M.ContractFactory(e,t,$);console.log(s.gray(`executing deployment of ${i} with nonce ${v}`));let l=n.deploy({nonce:v++,maxPriorityFeePerGas:O,maxFeePerGas:U,gasPrice:K}).then(D=>o?D:D.deployed());d.push(l);let{address:g}=await l;return console.log(s.green("Deployed",i,"to",g)),g}catch(n){if(S&&console.error(n),c===0&&n?.message.includes("transaction already imported"))return L(b*1.1),R(e,t,o,i,c++);throw n?.message.includes("invalid bytecode")?new h(`Error deploying ${i}: invalid bytecode. Note that linking of public libraries is not supported yet, make sure none of your libraries use "external" functions.`):n?.message.includes("CreateContractLimit")?new h(`Error deploying ${i}: CreateContractLimit exceeded.`):n}}async function he(e){let{abi:t}=await oe(e);return t.filter(o=>["fallback","function"].includes(o.type)).map(o=>o.type==="fallback"?{functionName:"",functionArgs:""}:{functionName:o.name,functionArgs:te(o.inputs)})}function te(e){return`(${e.map(o=>{let i=o.type.match(/tuple(.*)/);return i?te(o.components)+i[1]:o.type})})`}async function w(e,t,o,i=1,c=0){let n=`${t}(${o.map(l=>`'${l}'`).join(",")})`;try{let l=await e.estimateGas[t].apply(null,o);console.log(s.gray(`executing transaction: ${n} with nonce ${v}`));let g=e[t].apply(null,[...o,{gasLimit:l,nonce:v++,maxPriorityFeePerGas:O,maxFeePerGas:U,gasPrice:K}]).then(D=>i===0?D:D.wait(i));return d.push(g),g}catch(l){if(S&&console.error(l),c===0&&l?.message.includes("transaction already imported"))return L(b*1.1),w(e,t,o,i,c++);throw new h(`Gas estimation error for ${n}: ${l?.reason}`)}}async function oe(e){let t,o=ne.join(fe,e+".sol",e+".json");try{t=JSON.parse(De(o,"utf8"))}catch{throw new h(`Error reading file at ${o}`)}let i=t?.bytecode?.object;if(!i)throw new h(`No bytecode found in ${o}`);let c=t?.abi;if(!c)throw new h(`No ABI found in ${o}`);return{abi:c,bytecode:i}}async function L(e){let t=await N.getFeeData();if(t.lastBaseFeePerGas){if(!t.lastBaseFeePerGas.eq(0)&&(await $.getBalance()).eq(0))throw new h(`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 $.getAddress()}'`);O=t.lastBaseFeePerGas.eq(0)?0:Math.floor(15e8*e),U=t.lastBaseFeePerGas.mul(2).add(O)}else if(t.gasPrice){if(!t.gasPrice.eq(0)&&(await $.getBalance()).eq(0))throw new h("Attempting to deploy to a chain with non-zero gas price with an account that has no balance.");K=t.gasPrice}else throw new h("Can not fetch fee data from RPC")}}function V(r){if(r.length>16)throw new Error("String does not fit into 16 bytes");let p=new Uint8Array(16);for(let u=0;u<r.length;u++)p[u]=r.charCodeAt(u);for(let u=r.length;u<16;u++)p[u]=0;return p}function ke(r,p){let u=V(r),m=V(p),x=new Uint8Array(32);return x.set(u),x.set(m,16),x}function ue({functionName:r,functionArgs:p}){let u=r+p;return u===""?"0x":Ae(u)}function Ae(r){return M.utils.hexDataSlice(M.utils.keccak256(M.utils.toUtf8Bytes(r)),0,4)}import{forge as ye,getRpcUrl as Ge,getSrcDirectory as Ne}from"@latticexyz/common/foundry";import{existsSync as Ue,mkdirSync as Ke,readFileSync as _e,writeFileSync as H}from"fs";import{ethers as Te}from"ethers";async function ge(r){let{result:p}=await Te.utils.fetchJson(r,'{ "id": 42, "jsonrpc": "2.0", "method": "eth_chainId", "params": [ ] }');return Number(p)}import We from"glob";import{basename as Be}from"path";function me(r){return We.sync(`${r}/**/*.sol`).map(p=>({path:p,basename:Be(p,".sol")}))}async function It(r){r.profile??=process.env.FOUNDRY_PROFILE;let{configPath:p,printConfig:u,profile:m,clean:x,skipBuild:B}=r,a=r.rpc??await Ge(m);console.log(W.bgBlue(W.whiteBright(`
3
+ Deploying MUD contracts${m?" with profile "+m:""} to RPC ${a}
4
+ `))),x&&await ye(["clean"],{profile:m}),B||await ye(["build"],{profile:m});let k=r?.srcDir??await Ne(),A=me(k).map(({basename:S})=>S),y=await Oe(p);u&&console.log(W.green(`
5
+ Resolved config:
6
+ `),JSON.stringify(y,null,2));let E=process.env.PRIVATE_KEY;if(!E)throw new Ee(`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 b=await pe(y,A,{...r,rpc:a,privateKey:E});if(r.saveDeployment){let S=await ge(a),F=Y.join(y.deploysDirectory,S.toString());Ke(F,{recursive:!0}),H(Y.join(F,"latest.json"),JSON.stringify(b,null,2)),H(Y.join(F,Date.now()+".json"),JSON.stringify(b,null,2));let f=[1337,31337],T=Ue(y.worldsFile)?JSON.parse(_e(y.worldsFile,"utf-8")):{};T[S]={address:b.worldAddress,blockNumber:f.includes(S)?void 0:b.blockNumber},H(y.worldsFile,JSON.stringify(T,null,2)),console.log(W.bgGreen(W.whiteBright(`
9
+ Deployment result (written to ${y.worldsFile} and ${F}):
10
+ `)))}return console.log(b),b}export{ge as a,me as b,It as c};
11
+ //# sourceMappingURL=chunk-KRDCJ5DZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/deployHandler.ts","../src/utils/deploy.ts","../src/utils/getChainId.ts","../src/utils/getExistingContracts.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 { getChainId } from \"../utils/getChainId\";\nimport { getExistingContracts } from \"./getExistingContracts\";\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) await forge([\"clean\"], { profile });\n\n // Run forge build\n if (!skipBuild) await forge([\"build\"], { profile });\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 { existsSync, readFileSync } from \"fs\";\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport { BigNumber, ContractInterface, ethers } from \"ethers\";\nimport { defaultAbiCoder as abi, Fragment, ParamType } from \"ethers/lib/utils.js\";\n\nimport { getOutDirectory, getScriptDirectory, cast, forge } from \"@latticexyz/common/foundry\";\nimport { resolveWithContext } from \"@latticexyz/config\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { encodeSchema } from \"@latticexyz/schema-type/deprecated\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { resolveAbiOrUserType } from \"@latticexyz/store/codegen\";\nimport { WorldConfig, resolveWorldConfig } from \"@latticexyz/world\";\nimport IBaseWorldData from \"@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json\" assert { type: \"json\" };\nimport WorldData from \"@latticexyz/world/abi/World.sol/World.json\" assert { type: \"json\" };\nimport CoreModuleData from \"@latticexyz/world/abi/CoreModule.sol/CoreModule.json\" assert { type: \"json\" };\nimport KeysWithValueModuleData from \"@latticexyz/world/abi/KeysWithValueModule.sol/KeysWithValueModule.json\" assert { type: \"json\" };\nimport KeysInTableModuleData from \"@latticexyz/world/abi/KeysInTableModule.sol/KeysInTableModule.json\" assert { type: \"json\" };\nimport UniqueEntityModuleData from \"@latticexyz/world/abi/UniqueEntityModule.sol/UniqueEntityModule.json\" assert { type: \"json\" };\nimport { tableIdToHex } from \"@latticexyz/common\";\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 resolvedConfig = resolveWorldConfig(mudConfig, existingContractNames);\n\n const startTime = Date.now();\n const { worldContractName, namespace, postDeployScript } = mudConfig;\n const { profile, rpc, privateKey, priorityFeeMultiplier, debug, worldAddress, disableTxWait, pollInterval } =\n deployConfig;\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 // Manual nonce handling to allow for faster sending of transactions without waiting for previous transactions\n let nonce = await signer.getTransactionCount();\n console.log(\"Initial nonce\", nonce);\n\n // Compute maxFeePerGas and maxPriorityFeePerGas like ethers, but allow for a multiplier to allow replacing pending transactions\n let maxPriorityFeePerGas: number | undefined;\n let maxFeePerGas: BigNumber | undefined;\n let gasPrice: BigNumber | undefined;\n\n await setInternalFeePerGas(priorityFeeMultiplier);\n\n // Catch all to await any promises before exiting the script\n let promises: Promise<unknown>[] = [];\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 World\n const worldPromise = {\n World: worldAddress\n ? Promise.resolve(worldAddress)\n : worldContractName\n ? deployContractByName(worldContractName, disableTxWait)\n : deployContract(IBaseWorldData.abi, WorldData.bytecode, disableTxWait, \"World\"),\n };\n\n // Deploy Systems\n const systemPromises = Object.keys(resolvedConfig.systems).reduce<Record<string, Promise<string>>>(\n (acc, systemName) => {\n acc[systemName] = deployContractByName(systemName, disableTxWait);\n return acc;\n },\n {}\n );\n\n // Deploy default World modules\n const defaultModules: Record<string, Promise<string>> = {\n // TODO: these only need to be deployed once per chain, add a check if they exist already\n CoreModule: deployContract(CoreModuleData.abi, CoreModuleData.bytecode, disableTxWait, \"CoreModule\"),\n KeysWithValueModule: deployContract(\n KeysWithValueModuleData.abi,\n KeysWithValueModuleData.bytecode,\n disableTxWait,\n \"KeysWithValueModule\"\n ),\n KeysInTableModule: deployContract(\n KeysInTableModuleData.abi,\n KeysInTableModuleData.bytecode,\n disableTxWait,\n \"KeysInTableModule\"\n ),\n UniqueEntityModule: deployContract(\n UniqueEntityModuleData.abi,\n UniqueEntityModuleData.bytecode,\n disableTxWait,\n \"UniqueEntityModule\"\n ),\n };\n\n // Deploy user Modules\n const modulePromises = mudConfig.modules\n .filter((module) => !defaultModules[module.name]) // Only deploy user modules here, not default modules\n .reduce<Record<string, Promise<string>>>((acc, module) => {\n acc[module.name] = deployContractByName(module.name, disableTxWait);\n return acc;\n }, defaultModules);\n\n // Combine all contracts into one object\n const contractPromises: Record<string, Promise<string>> = { ...worldPromise, ...systemPromises, ...modulePromises };\n\n // Create World contract instance from deployed address\n const WorldContract = new ethers.Contract(await contractPromises.World, IBaseWorldData.abi, signer);\n\n const confirmations = disableTxWait ? 0 : 1;\n\n // Install core Modules\n if (!worldAddress) {\n console.log(chalk.blue(\"Installing core World modules\"));\n await fastTxExecute(WorldContract, \"installRootModule\", [await modulePromises.CoreModule, \"0x\"], confirmations);\n console.log(chalk.green(\"Installed core World modules\"));\n }\n\n // Register namespace\n if (namespace) await fastTxExecute(WorldContract, \"registerNamespace\", [toBytes16(namespace)], confirmations);\n\n // Register tables\n const tableIds: { [tableName: string]: Uint8Array } = {};\n promises = [\n ...promises,\n ...Object.entries(mudConfig.tables).map(async ([tableName, { name, schema, keySchema }]) => {\n console.log(chalk.blue(`Registering table ${tableName} at ${namespace}/${name}`));\n\n // Store the tableId for later use\n tableIds[tableName] = toResourceSelector(namespace, name);\n\n // Register table\n const schemaTypes = Object.values(schema).map((abiOrUserType) => {\n const { schemaType } = resolveAbiOrUserType(abiOrUserType, mudConfig);\n return schemaType;\n });\n\n const keyTypes = Object.values(keySchema).map((abiOrUserType) => {\n const { schemaType } = resolveAbiOrUserType(abiOrUserType, mudConfig);\n return schemaType;\n });\n\n await fastTxExecute(\n WorldContract,\n \"registerTable\",\n [\n tableIdToHex(namespace, name),\n encodeSchema(keyTypes),\n encodeSchema(schemaTypes),\n Object.keys(keySchema),\n Object.keys(schema),\n ],\n confirmations\n );\n\n console.log(chalk.green(`Registered table ${tableName} at ${name}`));\n }),\n ];\n\n // Register systems (using forEach instead of for..of to avoid blocking on async calls)\n promises = [\n ...promises,\n ...Object.entries(resolvedConfig.systems).map(\n async ([systemName, { name, openAccess, registerFunctionSelectors }]) => {\n // Register system at route\n console.log(chalk.blue(`Registering system ${systemName} at ${namespace}/${name}`));\n await fastTxExecute(\n WorldContract,\n \"registerSystem\",\n [tableIdToHex(namespace, name), await contractPromises[systemName], openAccess],\n confirmations\n );\n console.log(chalk.green(`Registered system ${systemName} at ${namespace}/${name}`));\n\n // Register function selectors for the system\n if (registerFunctionSelectors) {\n const functionSignatures: FunctionSignature[] = await loadFunctionSignatures(systemName);\n const isRoot = namespace === \"\";\n // Using Promise.all to avoid blocking on async calls\n await Promise.all(\n functionSignatures.map(async ({ functionName, functionArgs }) => {\n const functionSignature = isRoot\n ? functionName + functionArgs\n : `${namespace}_${name}_${functionName}${functionArgs}`;\n\n console.log(chalk.blue(`Registering function \"${functionSignature}\"`));\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 await fastTxExecute(\n WorldContract,\n \"registerRootFunctionSelector\",\n [tableIdToHex(namespace, name), worldFunctionSelector, systemFunctionSelector],\n confirmations\n );\n } else {\n await fastTxExecute(\n WorldContract,\n \"registerFunctionSelector\",\n [tableIdToHex(namespace, name), functionName, functionArgs],\n confirmations\n );\n }\n console.log(chalk.green(`Registered function \"${functionSignature}\"`));\n })\n );\n }\n }\n ),\n ];\n\n // Wait for resources to be registered before granting access to them\n await Promise.all(promises); // ----------------------------------------------------------------------------------------------\n promises = [];\n\n // Grant access to systems\n for (const [systemName, { name, accessListAddresses, accessListSystems }] of Object.entries(resolvedConfig.systems)) {\n const resourceSelector = `${namespace}/${name}`;\n\n // Grant access to addresses\n promises = [\n ...promises,\n ...accessListAddresses.map(async (address) => {\n console.log(chalk.blue(`Grant ${address} access to ${systemName} (${resourceSelector})`));\n await fastTxExecute(WorldContract, \"grantAccess\", [tableIdToHex(namespace, name), address], confirmations);\n console.log(chalk.green(`Granted ${address} access to ${systemName} (${namespace}/${name})`));\n }),\n ];\n\n // Grant access to other systems\n promises = [\n ...promises,\n ...accessListSystems.map(async (granteeSystem) => {\n console.log(chalk.blue(`Grant ${granteeSystem} access to ${systemName} (${resourceSelector})`));\n await fastTxExecute(\n WorldContract,\n \"grantAccess\",\n [tableIdToHex(namespace, name), await contractPromises[granteeSystem]],\n confirmations\n );\n console.log(chalk.green(`Granted ${granteeSystem} access to ${systemName} (${resourceSelector})`));\n }),\n ];\n }\n\n // Wait for access to be granted before installing modules\n await Promise.all(promises); // ----------------------------------------------------------------------------------------------\n promises = [];\n\n // Install modules\n promises = [\n ...promises,\n ...mudConfig.modules.map(async (module) => {\n console.log(chalk.blue(`Installing${module.root ? \" root \" : \" \"}module ${module.name}`));\n // Resolve arguments\n const resolvedArgs = await Promise.all(\n module.args.map((arg) => resolveWithContext(arg, { tableIds, systemAddresses: contractPromises }))\n );\n const values = resolvedArgs.map((arg) => arg.value);\n const types = resolvedArgs.map((arg) => arg.type);\n const moduleAddress = await contractPromises[module.name];\n if (!moduleAddress) throw new Error(`Module ${module.name} not found`);\n\n // Send transaction to install module\n await fastTxExecute(\n WorldContract,\n module.root ? \"installRootModule\" : \"installModule\",\n [moduleAddress, abi.encode(types, values)],\n confirmations\n );\n\n console.log(chalk.green(`Installed${module.root ? \" root \" : \" \"}module ${module.name}`));\n }),\n ];\n\n // Await all promises before executing PostDeploy script\n await Promise.all(promises); // ----------------------------------------------------------------------------------------------\n\n // Confirm the current nonce is the expected nonce to make sure all transactions have been included\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 promises = [];\n\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 [\n \"script\",\n postDeployScript,\n \"--sig\",\n \"run(address)\",\n await contractPromises.World,\n \"--broadcast\",\n \"--rpc-url\",\n rpc,\n \"-vvv\",\n ],\n {\n profile,\n }\n );\n } else {\n console.log(`No script at ${postDeployPath}, skipping post deploy hook`);\n }\n\n console.log(chalk.green(\"Deployment completed in\", (Date.now() - startTime) / 1000, \"seconds\"));\n\n return { worldAddress: await contractPromises.World, blockNumber };\n\n // ------------------- INTERNAL FUNCTIONS -------------------\n // (Inlined to avoid having to pass around nonce, signer and forgeOutDir)\n\n /**\n * Deploy a contract and return the address\n * @param contractName Name of the contract to deploy (must exist in the file system)\n * @param disableTxWait Disable waiting for contract deployment\n * @returns Address of the deployed contract\n */\n async function deployContractByName(contractName: string, disableTxWait: boolean): Promise<string> {\n console.log(chalk.blue(\"Deploying\", contractName));\n\n const { abi, bytecode } = await getContractData(contractName);\n return deployContract(abi, bytecode, disableTxWait, contractName);\n }\n\n /**\n * Deploy a contract and return the address\n * @param abi The contract interface\n * @param bytecode The contract bytecode\n * @param disableTxWait Disable waiting for contract deployment\n * @param contractName The contract name (optional, used for logs)\n * @param retryCount\n * @returns Address of the deployed contract\n */\n async function deployContract(\n abi: ContractInterface,\n bytecode: string | { object: string },\n disableTxWait: boolean,\n contractName?: string,\n retryCount = 0\n ): Promise<string> {\n try {\n const factory = new ethers.ContractFactory(abi, bytecode, signer);\n console.log(chalk.gray(`executing deployment of ${contractName} with nonce ${nonce}`));\n const deployPromise = factory\n .deploy({\n nonce: nonce++,\n maxPriorityFeePerGas,\n maxFeePerGas,\n gasPrice,\n })\n .then((c) => (disableTxWait ? c : c.deployed()));\n\n promises.push(deployPromise);\n const { address } = await deployPromise;\n\n console.log(chalk.green(\"Deployed\", contractName, \"to\", address));\n return address;\n } catch (error: any) {\n if (debug) console.error(error);\n if (retryCount === 0 && error?.message.includes(\"transaction already imported\")) {\n // If the deployment failed because the transaction was already imported,\n // retry with a higher priority fee\n setInternalFeePerGas(priorityFeeMultiplier * 1.1);\n return deployContract(abi, bytecode, disableTxWait, contractName, retryCount++);\n } else if (error?.message.includes(\"invalid bytecode\")) {\n throw new MUDError(\n `Error deploying ${contractName}: 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 ${contractName}: CreateContractLimit exceeded.`);\n } else throw error;\n }\n }\n\n /**\n * Deploy a contract and return the address\n * @param contractName Name of the contract to deploy (must exist in the file system)\n * @returns Address of the deployed contract\n *\n * NOTE: Forge deploy seems to be slightly slower than ethers\n * (probably due to the extra overhead spawning a child process to run forge),\n * so we mostly use ethersDeployContract here.\n * However, for contracts not in the user directory (eg. the vanilla World contract),\n * using forge is more convenient because it automatically finds the contract in the @latticexyz/world package.\n */\n // async function forgeDeployContract(contractName: string): Promise<string> {\n // console.log(chalk.blue(\"Deploying\", contractName));\n\n // const { deployedTo } = JSON.parse(\n // await forge(\n // [\"create\", contractName, \"--rpc-url\", rpc, \"--private-key\", privateKey, \"--json\", \"--nonce\", String(nonce++)],\n // { profile, silent: true }\n // )\n // );\n // return deployedTo;\n // }\n\n async function loadFunctionSignatures(contractName: string): Promise<FunctionSignature[]> {\n const { abi } = await getContractData(contractName);\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 /**\n * Recursively turn (nested) structs in signatures into tuples\n */\n function 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 /**\n * Only await gas estimation (for speed), only execute if gas estimation succeeds (for safety)\n */\n async function fastTxExecute<C extends { estimateGas: any; [key: string]: any }, F extends keyof C>(\n contract: C,\n func: F,\n args: Parameters<C[F]>,\n confirmations = 1,\n retryCount = 0\n ): Promise<Awaited<ReturnType<Awaited<ReturnType<C[F]>>[\"wait\"]>>> {\n const functionName = `${func as string}(${args.map((arg) => `'${arg}'`).join(\",\")})`;\n try {\n const gasLimit = await contract.estimateGas[func].apply(null, args);\n console.log(chalk.gray(`executing transaction: ${functionName} with nonce ${nonce}`));\n const txPromise = contract[func]\n .apply(null, [...args, { gasLimit, nonce: nonce++, maxPriorityFeePerGas, maxFeePerGas, gasPrice }])\n .then((tx: any) => (confirmations === 0 ? tx : tx.wait(confirmations)));\n promises.push(txPromise);\n return txPromise;\n } catch (error: any) {\n if (debug) console.error(error);\n if (retryCount === 0 && error?.message.includes(\"transaction already imported\")) {\n // If the deployment failed because the transaction was already imported,\n // retry with a higher priority fee\n setInternalFeePerGas(priorityFeeMultiplier * 1.1);\n return fastTxExecute(contract, func, args, confirmations, retryCount++);\n } else throw new MUDError(`Gas estimation error for ${functionName}: ${error?.reason}`);\n }\n }\n\n /**\n * Load the contract's abi and bytecode from the file system\n * @param contractName: Name of the contract to load\n */\n async function getContractData(contractName: string): Promise<{ 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\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 */\n async function setInternalFeePerGas(multiplier: number) {\n // Compute maxFeePerGas and maxPriorityFeePerGas like ethers, but allow for a multiplier to allow replacing pending transactions\n const feeData = await provider.getFeeData();\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 }\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)\nfunction 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\n// TODO: use TableId from utils as soon as utils are usable inside cli\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\ninterface FunctionSignature {\n functionName: string;\n functionArgs: string;\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 toFunctionSelector({ functionName, functionArgs }: FunctionSignature): string {\n const functionSignature = functionName + functionArgs;\n if (functionSignature === \"\") return \"0x\";\n return sigHash(functionSignature);\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 { 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","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"],"mappings":"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","names":["chalk","path","MUDError","loadConfig","existsSync","readFileSync","path","chalk","ethers","abi","getOutDirectory","getScriptDirectory","cast","forge","resolveWithContext","MUDError","encodeSchema","resolveAbiOrUserType","resolveWorldConfig","IBaseWorldData","WorldData","CoreModuleData","KeysWithValueModuleData","KeysInTableModuleData","UniqueEntityModuleData","tableIdToHex","deploy","mudConfig","existingContractNames","deployConfig","resolvedConfig","startTime","worldContractName","namespace","postDeployScript","profile","rpc","privateKey","priorityFeeMultiplier","debug","worldAddress","disableTxWait","pollInterval","forgeOutDirectory","provider","signer","nonce","maxPriorityFeePerGas","maxFeePerGas","gasPrice","setInternalFeePerGas","promises","blockNumber","worldPromise","deployContractByName","deployContract","systemPromises","acc","systemName","defaultModules","modulePromises","module","contractPromises","WorldContract","confirmations","fastTxExecute","toBytes16","tableIds","tableName","name","schema","keySchema","toResourceSelector","schemaTypes","abiOrUserType","schemaType","keyTypes","openAccess","registerFunctionSelectors","functionSignatures","loadFunctionSignatures","isRoot","functionName","functionArgs","functionSignature","worldFunctionSelector","toFunctionSelector","systemFunctionSelector","accessListAddresses","accessListSystems","resourceSelector","address","granteeSystem","resolvedArgs","arg","values","types","moduleAddress","remoteNonce","retryCount","maxRetries","resolve","postDeployPath","contractName","bytecode","getContractData","factory","deployPromise","c","error","item","parseComponents","params","param","tupleMatch","contract","func","args","gasLimit","txPromise","tx","data","contractDataPath","multiplier","feeData","input","result","i","file","namespaceBytes","fileBytes","sigHash","signature","forge","getRpcUrl","getSrcDirectory","existsSync","mkdirSync","readFileSync","writeFileSync","ethers","getChainId","rpc","chainId","glob","basename","getExistingContracts","srcDir","path","deployHandler","args","configPath","printConfig","profile","clean","skipBuild","rpc","getRpcUrl","chalk","forge","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-YDUX555R.js";export{o as deployHandler};
1
+ import{c as o}from"./chunk-KRDCJ5DZ.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 W,b as M,c as w}from"./chunk-YDUX555R.js";import So from"yargs";import{hideBin as Oo}from"yargs/helpers";import Mo from"@latticexyz/gas-report";import{rmSync as le}from"fs";import{homedir as pe}from"os";import me from"path";import{execa as fe}from"execa";var ge={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=pe();le(me.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=fe("anvil",t,{stdio:["inherit","inherit","inherit"]});process.on("SIGINT",()=>{console.log(`
3
- gracefully shutting down from SIGINT (Crtl-C)`),r.kill(),process.exit()}),await r}},R=ge;import{FaucetServiceDefinition as ue}from"@latticexyz/services/faucet";import{createChannel as ye,createClient as he}from"nice-grpc-web";import I from"chalk";import{NodeHttpTransport as be}from"@improbable-eng/grpc-web-node-http-transport";function we(e){return he(ue,ye(e,be()))}var ve={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=we(o);e&&(console.log(I.yellow("Dripping to",t)),await r.dripDev({address:t}),console.log(I.yellow("Success"))),process.exit(0)}},$=ve;var De={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=De;import Ce from"path";import{loadConfig as ke}from"@latticexyz/config/node";import{tablegen as xe}from"@latticexyz/store/codegen";import{getSrcDirectory as Me}from"@latticexyz/common/foundry";var Se={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 ke(e),t=await Me();await xe(o,Ce.join(t,o.codegenDirectory)),process.exit(0)}},A=Se;import D from"chalk";import{ZodError as Oe}from"zod";import{fromZodError as Ue,ValidationError as je}from"zod-validation-error";import{NotInsideProjectError as Pe}from"@latticexyz/config";import{MUDError as We}from"@latticexyz/common/errors";function g(e){if(e instanceof je)console.log(D.redBright(e.message));else if(e instanceof Oe){let o=Ue(e,{prefixSeparator:`
2
+ import{a as $,b as M,c as w}from"./chunk-KRDCJ5DZ.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
+ gracefully shutting down from SIGINT (Crtl-C)`),r.kill(),process.exit()}),await r}},W=fe;import{FaucetServiceDefinition as ge}from"@latticexyz/services/faucet";import{createChannel as ue,createClient as ye}from"nice-grpc-web";import E 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(E.yellow("Dripping to",t)),await r.dripDev({address:t}),console.log(E.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)}},I=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)}},F=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 Pe?(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 We?console.log(D.red(e)):console.log(e)}import Re from"chalk";function F(){console.log(Re.yellow(`
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)}import Re from"chalk";function T(){console.log(Re.yellow(`
6
6
  .------..------..------.
7
7
  |M.--. ||U.--. ||D.--. |
8
8
  | (\\/) || (\\/) || :/\\: |
9
9
  | :\\/: || :\\/: || (__) |
10
10
  | '--'M|| '--'U|| '--'D|
11
11
  '------''------''------'
12
- `))}import{getOutDirectory as Ie}from"@latticexyz/common/foundry";import $e from"path";import{runTypeChain as Ee}from"typechain";async function T(){let e=process.cwd(),o=await Ie(),t=$e.join(process.cwd(),o,"IWorld.sol/IWorld.json");await Ee({cwd:e,filesToProcess:[t],allFiles:[t],target:"ethers-v5"}),console.log("Typechain generated IWorld interface")}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"}},Ae={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)}},z=Ae;import{loadConfig as Fe}from"@latticexyz/config/node";import{worldgen as Te}from"@latticexyz/world/node";import{getSrcDirectory as ze}from"@latticexyz/common/foundry";import J from"path";import{rmSync as Je}from"fs";var Be={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 ze(),t=M(o),r=e.config??await Fe(e.configPath),i=J.join(o,r.codegenDirectory);e.clean&&Je(J.join(i,r.worldgenDirectory),{recursive:!0,force:!0}),await Te(r,t,i)}var B=Be;import h from"chalk";import{existsSync as He,readFileSync as Ne,rmSync as _e,writeFileSync as H}from"fs";import k from"path";import{MUDError as b}from"@latticexyz/common/errors";var V={name:"@latticexyz/cli",version:"2.0.0-next.5",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",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/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:*","@typechain/ethers-v5":"^10.2.0",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",typechain:"^8.1.1",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 Le from"glob";var S=".mudbackup",C="@latticexyz",qe={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 Ge(e);let r=Le.sync("**/package.json").filter(i=>!i.includes("node_modules"));for(let i of r)Ye(i,e)}catch(o){g(o)}finally{process.exit(0)}}};async function Ge(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/${V.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 Ye(e,o){let{restore:t,force:r,link:i}=o,{backup:c,mudVersion:d}=o,a=k.join(k.dirname(e),S),v=He(a);if(i&&!v&&(c=!0),c&&!r&&v)throw new b(`A backup file already exists at ${a}.
13
- 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)+`
14
- `),console.log(`Updating ${e}`),_(m,s.dependencies),_(y,s.devDependencies),t&&!c&&(_e(a),console.log(h.green(`Cleaned up ${a}`))),s;function l(n,p){return t&&u?u[p][n]:(i&&(d=Ze(e,i,n)),d||s[p][n])}}function N(e){try{let o=Ne(e,"utf8");return JSON.parse(o)}catch{throw new b("Could not read JSON at "+e)}}function _(e,o){for(let t in e)e[t]!==o[t]&&console.log(`${t}: ${h.red(e[t])} -> ${h.green(o[t])}`)}function Ze(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=qe;import{anvil as Ke,forge as Xe,getRpcUrl as Qe}from"@latticexyz/common/foundry";import eo from"chalk";import{rmSync as q,writeFileSync as oo}from"fs";var P=".mudtest",to={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)];Ke(i)}let o=e.worldAddress?await Qe(e.profile):`http://127.0.0.1:${e.port}`,t=e.worldAddress??(await w({...e,saveDeployment:!1,rpc:o})).worldAddress;console.log(eo.blue("World address",t)),oo(P,t);let r=e.forgeOptions?.replaceAll("\\","").split(" ")??[];try{let i=await Xe(["test","--fork-url",o,...r],{profile:e.profile});console.log(i)}catch(i){console.error(i),q(P),process.exit(1)}q(P),process.exit(0)}},G=to;import{existsSync as ro,readFileSync as no}from"fs";import{ethers as Y}from"ethers";import{loadConfig as io}from"@latticexyz/config/node";import{MUDError as Z}from"@latticexyz/common/errors";import{cast as so,getRpcUrl as ao,getSrcDirectory as co}from"@latticexyz/common/foundry";import{resolveWorldConfig as lo}from"@latticexyz/world";import po from"@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json"assert{type:"json"};import K from"@latticexyz/world/mud.config.js";import{tableIdToHex as Q}from"@latticexyz/common";var X=Q(K.namespace,K.tables.Systems.name),mo={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 co(o),e.rpc??=await ao(o);let{tx:t,configPath:r,srcDir:i,rpc:c}=e,d=M(i),a=await io(r),v=lo(a,d.map(({basename:f})=>f)),s=e.worldAddress??await fo(a.worldsFile,c),u=new Y.providers.StaticJsonRpcProvider(c),m=new Y.Contract(s,po.abi,u),y=a.namespace,l=Object.values(v.systems).map(({name:f})=>f),n=await m.getValueSchema(X),p=[];for(let f of l){let O=Q(y,f),de=await m.getField(X,[O],0,n);p.push({name:f,address:de})}let ce=await so(["run","--label",`${s}:World`,...p.map(({name:f,address:O})=>["--label",`${O}:${f}`]).flat(),`${t}`]);console.log(ce),process.exit(0)}},ee=mo;async function fo(e,o){if(ro(e)){let t=await W(o),r=JSON.parse(no(e,"utf-8"));if(!r[t])throw new Z(`chainId ${t} is missing in worldsFile "${e}"`);return r[t].address}else throw new Z("worldAddress is not specified and worldsFile is missing")}import{anvil as go,forge as oe,getRpcUrl as uo,getScriptDirectory as yo,getSrcDirectory as ho}from"@latticexyz/common/foundry";import x from"chalk";import bo from"chokidar";import{loadConfig as te,resolveConfigPath as wo}from"@latticexyz/config/node";import{tablegen as vo}from"@latticexyz/store/codegen";import re from"path";import{debounce as Do}from"throttle-debounce";import{homedir as Co}from"os";import{rmSync as ko}from"fs";var xo={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 oe(["clean"]);let o=e.rpc??await uo(),t=e.configPath??await wo(e.configPath),r=await ho(),i=await yo(),c=await te(t);if(await u(c),await m(c),!e.rpc){console.log(x.gray("Cleaning devnode cache"));let l=Co();ko(re.join(l,".foundry","anvil","tmp"),{recursive:!0,force:!0}),go(["--block-time","1","--block-base-fee-per-gas","0"])}let d={config:!1,contracts:!1},a={current:!1};bo.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=Do(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 te(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=re.join(r,l.codegenDirectory);await vo(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 oe(["build"]),await T()}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})}}},ne=xo;var ie=[z,R,$,Mo,E,A,B,L,G,ee,ne];import*as ae from"dotenv";import se from"chalk";ae.config();So(Oo(process.argv)).scriptName("mud").command(ie).strict().fail((e,o)=>{console.error(se.red(e)),e.includes("Missing required argument")&&console.log(se.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`)),console.log(""),g(o),console.log(""),process.exit(1)}).alias({h:"help"}).argv;
12
+ `))}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"}},$e={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)}},z=$e;import{loadConfig as We}from"@latticexyz/config/node";import{worldgen as Ee}from"@latticexyz/world/node";import{getSrcDirectory as Ae}from"@latticexyz/common/foundry";import J from"path";import{rmSync as Ie}from"fs";var Fe={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 We(e.configPath),i=J.join(o,r.codegenDirectory);e.clean&&Ie(J.join(i,r.worldgenDirectory),{recursive:!0,force:!0}),await Ee(r,t,i)}var V=Fe;import h from"chalk";import{existsSync as ze,readFileSync as Je,rmSync as Ve,writeFileSync as N}from"fs";import k from"path";import{MUDError as b}from"@latticexyz/common/errors";var H={name:"@latticexyz/cli",version:"2.0.0-next.7",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 Be(e);let r=He.sync("**/package.json").filter(i=>!i.includes("node_modules"));for(let i of r)_e(i,e)}catch(o){g(o)}finally{process.exit(0)}}};async function Be(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/${H.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 _e(e,o){let{restore:t,force:r,link:i}=o,{backup:c,mudVersion:d}=o,a=k.join(k.dirname(e),S),v=ze(a);if(i&&!v&&(c=!0),c&&!r&&v)throw new b(`A backup file already exists at ${a}.
13
+ Use --force to overwrite it or --restore to restore it.`);let s=B(e),u=t?B(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&&(N(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 N(e,JSON.stringify(s,null,2)+`
14
+ `),console.log(`Updating ${e}`),_(m,s.dependencies),_(y,s.devDependencies),t&&!c&&(Ve(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 B(e){try{let o=Je(e,"utf8");return JSON.parse(o)}catch{throw new b("Could not read JSON at "+e)}}function _(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 L=Ne;import{anvil as qe,forge as Ge,getRpcUrl as Ye}from"@latticexyz/common/foundry";import Ze from"chalk";import{rmSync as q,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),q(P),process.exit(1)}q(P),process.exit(0)}},G=Xe;import{existsSync as Qe,readFileSync as eo}from"fs";import{ethers as Y}from"ethers";import{loadConfig as oo}from"@latticexyz/config/node";import{MUDError as Z}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/abi/IBaseWorld.sol/IBaseWorld.json"assert{type:"json"};import K from"@latticexyz/world/mud.config.js";import{tableIdToHex as Q}from"@latticexyz/common";var X=Q(K.namespace,K.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 Y.providers.StaticJsonRpcProvider(c),m=new Y.Contract(s,so.abi,u),y=a.namespace,l=Object.values(v.systems).map(({name:f})=>f),n=await m.getValueSchema(X),p=[];for(let f of l){let O=Q(y,f),ce=await m.getField(X,[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)}},ee=ao;async function co(e,o){if(Qe(e)){let t=await $(o),r=JSON.parse(eo(e,"utf-8"));if(!r[t])throw new Z(`chainId ${t} is missing in worldsFile "${e}"`);return r[t].address}else throw new Z("worldAddress is not specified and worldsFile is missing")}import{anvil as lo,forge as R,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 R(["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()),T(),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 R(["build"]),await R(["build","--extra-output-files","abi","--out","abi","--skip","test","script","MudTest.sol"]),await vo("mud",["abi-ts"])}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=[z,W,A,Co,I,F,V,L,G,ee,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
package/dist/mud.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mud.ts","../src/commands/index.ts","../src/commands/devnode.ts","../src/commands/faucet.ts","../src/commands/hello.ts","../src/commands/tablegen.ts","../src/utils/errors.ts","../src/utils/printMUD.ts","../src/utils/worldtypes.ts","../src/commands/deploy.ts","../src/commands/worldgen.ts","../src/commands/set-version.ts","../package.json","../src/commands/test.ts","../src/commands/trace.ts","../src/commands/dev-contracts.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { commands } from \"./commands\";\nimport { logError } from \"./utils/errors\";\n\n// Load .env file into process.env\nimport * as dotenv from \"dotenv\";\nimport chalk from \"chalk\";\ndotenv.config();\n\nyargs(hideBin(process.argv))\n // Explicit name to display in help (by default it's the entry file, which may not be \"mud\" for e.g. ts-node)\n .scriptName(\"mud\")\n // Use the commands directory to scaffold\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- command array overload isn't typed, see https://github.com/yargs/yargs/blob/main/docs/advanced.md#esm-hierarchy\n .command(commands as any)\n // Enable strict mode.\n .strict()\n // Custom error handler\n .fail((msg, err) => {\n console.error(chalk.red(msg));\n if (msg.includes(\"Missing required argument\")) {\n console.log(\n chalk.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`)\n );\n }\n console.log(\"\");\n logError(err);\n console.log(\"\");\n\n process.exit(1);\n })\n // Useful aliases.\n .alias({ h: \"help\" }).argv;\n","import { CommandModule } from \"yargs\";\n\nimport gasReport from \"@latticexyz/gas-report\";\n\nimport devnode from \"./devnode\";\nimport faucet from \"./faucet\";\nimport hello from \"./hello\";\nimport tablegen from \"./tablegen\";\nimport deploy from \"./deploy\";\nimport worldgen from \"./worldgen\";\nimport setVersion from \"./set-version\";\nimport test from \"./test\";\nimport trace from \"./trace\";\nimport devContracts from \"./dev-contracts\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Each command has different options\nexport const commands: CommandModule<any, any>[] = [\n deploy,\n devnode,\n faucet,\n gasReport as CommandModule,\n hello,\n tablegen,\n worldgen,\n setVersion,\n test,\n trace,\n devContracts,\n];\n","import { rmSync } from \"fs\";\nimport { homedir } from \"os\";\nimport path from \"path\";\nimport type { CommandModule } from \"yargs\";\nimport { execa } from \"execa\";\n\ntype Options = {\n blocktime: number;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"devnode\",\n\n describe: \"Start a local Ethereum node for development\",\n\n builder(yargs) {\n return yargs.options({\n blocktime: { type: \"number\", default: 1, decs: \"Interval in which new blocks are produced\" },\n });\n },\n\n async handler({ blocktime }) {\n console.log(\"Clearing devnode history\");\n const userHomeDir = homedir();\n rmSync(path.join(userHomeDir, \".foundry\", \"anvil\", \"tmp\"), { recursive: true, force: true });\n\n const anvilArgs = [\"-b\", String(blocktime), \"--block-base-fee-per-gas\", \"0\"];\n console.log(`Running: anvil ${anvilArgs.join(\" \")}`);\n const child = execa(\"anvil\", anvilArgs, {\n stdio: [\"inherit\", \"inherit\", \"inherit\"],\n });\n\n process.on(\"SIGINT\", () => {\n console.log(\"\\ngracefully shutting down from SIGINT (Crtl-C)\");\n child.kill();\n process.exit();\n });\n await child;\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\nimport { FaucetServiceDefinition } from \"@latticexyz/services/faucet\";\nimport { createChannel, createClient } from \"nice-grpc-web\";\nimport chalk from \"chalk\";\nimport { NodeHttpTransport } from \"@improbable-eng/grpc-web-node-http-transport\";\n\ntype Options = {\n dripDev?: boolean;\n faucetUrl: string;\n address: string;\n};\n\n/**\n * Create a FaucetServiceClient\n * @param url FaucetService URL\n * @returns FaucetServiceClient\n */\nfunction createFaucetService(url: string) {\n return createClient(FaucetServiceDefinition, createChannel(url, NodeHttpTransport()));\n}\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"faucet\",\n\n describe: \"Interact with a MUD faucet\",\n\n builder(yargs) {\n return yargs.options({\n dripDev: {\n type: \"boolean\",\n desc: \"Request a drip from the dev endpoint (requires faucet to have dev mode enabled)\",\n default: true,\n },\n faucetUrl: {\n type: \"string\",\n desc: \"URL of the MUD faucet\",\n default: \"https://faucet.testnet-mud-services.linfra.xyz\",\n },\n address: {\n type: \"string\",\n desc: \"Ethereum address to fund\",\n required: true,\n },\n });\n },\n\n async handler({ dripDev, faucetUrl, address }) {\n const faucet = createFaucetService(faucetUrl);\n\n if (dripDev) {\n console.log(chalk.yellow(\"Dripping to\", address));\n await faucet.dripDev({ address });\n console.log(chalk.yellow(\"Success\"));\n }\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\n\ntype Options = {\n name: string;\n upper: boolean | undefined;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"hello <name>\",\n\n describe: \"Greet <name> with Hello\",\n\n builder(yargs) {\n return yargs\n .options({\n upper: { type: \"boolean\" },\n })\n .positional(\"name\", { type: \"string\", demandOption: true });\n },\n\n handler({ name }) {\n const greeting = `Gm, ${name}!`;\n console.log(greeting);\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import path from \"path\";\nimport type { CommandModule } from \"yargs\";\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { tablegen } from \"@latticexyz/store/codegen\";\nimport { getSrcDirectory } from \"@latticexyz/common/foundry\";\n\ntype Options = {\n configPath?: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"tablegen\",\n\n describe: \"Autogenerate MUD Store table libraries based on the config file\",\n\n builder(yargs) {\n return yargs.options({\n configPath: { type: \"string\", desc: \"Path to the config file\" },\n });\n },\n\n async handler({ configPath }) {\n const config = (await loadConfig(configPath)) as StoreConfig;\n const srcDir = await getSrcDirectory();\n\n await tablegen(config, path.join(srcDir, config.codegenDirectory));\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import chalk from \"chalk\";\nimport { ZodError } from \"zod\";\nimport { fromZodError, ValidationError } from \"zod-validation-error\";\nimport { NotInsideProjectError } from \"@latticexyz/config\";\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","import chalk from \"chalk\";\n\nexport function printMUD() {\n console.log(\n chalk.yellow(`\n.------..------..------.\n|M.--. ||U.--. ||D.--. |\n| (\\\\/) || (\\\\/) || :/\\\\: |\n| :\\\\/: || :\\\\/: || (__) |\n| '--'M|| '--'U|| '--'D|\n'------''------''------'\n`)\n );\n}\n","import { getOutDirectory } from \"@latticexyz/common/foundry\";\nimport path from \"path\";\nimport { runTypeChain } from \"typechain\";\n\n/**\n * Generate IWorld typescript bindings\n */\nexport async function worldtypes() {\n const cwd = process.cwd();\n const forgeOurDir = await getOutDirectory();\n const IWorldPath = path.join(process.cwd(), forgeOurDir, \"IWorld.sol/IWorld.json\");\n\n await runTypeChain({\n cwd,\n filesToProcess: [IWorldPath],\n allFiles: [IWorldPath],\n target: \"ethers-v5\",\n });\n\n console.log(\"Typechain generated IWorld interface\");\n}\n","import type { CommandModule, Options } from \"yargs\";\nimport { logError } from \"../utils/errors\";\nimport { deployHandler, DeployOptions } from \"../utils\";\n\nexport const yDeployOptions = {\n configPath: { type: \"string\", desc: \"Path to the config file\" },\n clean: { type: \"boolean\", desc: \"Remove the build forge artifacts and cache directories before building\" },\n printConfig: { type: \"boolean\", desc: \"Print the resolved config\" },\n profile: { type: \"string\", desc: \"The foundry profile to use\" },\n debug: { type: \"boolean\", desc: \"Print debug logs, like full error messages\" },\n priorityFeeMultiplier: {\n type: \"number\",\n desc: \"Multiply the estimated priority fee by the provided factor\",\n default: 1,\n },\n saveDeployment: { type: \"boolean\", desc: \"Save the deployment info to a file\", default: true },\n rpc: { type: \"string\", desc: \"The RPC URL to use. Defaults to the RPC url from the local foundry.toml\" },\n worldAddress: { type: \"string\", desc: \"Deploy to an existing World at the given address\" },\n srcDir: { type: \"string\", desc: \"Source directory. Defaults to foundry src directory.\" },\n disableTxWait: { type: \"boolean\", desc: \"Disable waiting for transactions to be confirmed.\", default: false },\n pollInterval: {\n type: \"number\",\n desc: \"Interval in miliseconds to use to poll for transaction receipts / block inclusion\",\n default: 1000,\n },\n skipBuild: { type: \"boolean\", desc: \"Skip rebuilding the contracts before deploying\" },\n} satisfies Record<keyof DeployOptions, Options>;\n\nconst commandModule: CommandModule<DeployOptions, DeployOptions> = {\n command: \"deploy\",\n\n describe: \"Deploy MUD contracts\",\n\n builder(yargs) {\n return yargs.options(yDeployOptions);\n },\n\n async handler(args) {\n try {\n await deployHandler(args);\n } catch (error: any) {\n logError(error);\n process.exit(1);\n }\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { WorldConfig } from \"@latticexyz/world\";\nimport { worldgen } from \"@latticexyz/world/node\";\nimport { getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport path from \"path\";\nimport { rmSync } from \"fs\";\nimport { getExistingContracts } from \"../utils\";\n\ntype Options = {\n configPath?: string;\n clean?: boolean;\n srcDir?: string;\n config?: StoreConfig & WorldConfig;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"worldgen\",\n\n describe: \"Autogenerate interfaces for Systems and World based on existing contracts and the config file\",\n\n builder(yargs) {\n return yargs.options({\n configPath: { type: \"string\", desc: \"Path to the config file\" },\n clean: {\n type: \"boolean\",\n desc: \"Clear the worldgen directory before generating new interfaces (defaults to true)\",\n default: true,\n },\n });\n },\n\n async handler(args) {\n await worldgenHandler(args);\n process.exit(0);\n },\n};\n\nexport async function worldgenHandler(args: Options) {\n const srcDir = args.srcDir ?? (await getSrcDirectory());\n\n const existingContracts = getExistingContracts(srcDir);\n\n // Load the config\n const mudConfig = args.config ?? ((await loadConfig(args.configPath)) as StoreConfig & WorldConfig);\n\n const outputBaseDirectory = path.join(srcDir, mudConfig.codegenDirectory);\n\n // clear the worldgen directory\n if (args.clean) rmSync(path.join(outputBaseDirectory, mudConfig.worldgenDirectory), { recursive: true, force: true });\n\n // generate new interfaces\n await worldgen(mudConfig, existingContracts, outputBaseDirectory);\n}\n\nexport default commandModule;\n","import chalk from \"chalk\";\nimport { existsSync, readFileSync, rmSync, writeFileSync } from \"fs\";\nimport path from \"path\";\nimport type { CommandModule } from \"yargs\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { logError } from \"../utils/errors\";\nimport localPackageJson from \"../../package.json\" assert { type: \"json\" };\nimport glob from \"glob\";\n\ntype Options = {\n backup?: boolean;\n force?: boolean;\n restore?: boolean;\n mudVersion?: string;\n tag?: string;\n commit?: string;\n link?: string;\n};\n\nconst BACKUP_FILE = \".mudbackup\";\nconst MUD_PREFIX = \"@latticexyz\";\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"set-version\",\n\n describe: \"Set MUD version in all package.json files and optionally backup the previously installed version\",\n\n builder(yargs) {\n return yargs.options({\n backup: { type: \"boolean\", description: `Back up the current MUD versions to \"${BACKUP_FILE}\"` },\n force: {\n type: \"boolean\",\n description: `Backup fails if a \"${BACKUP_FILE}\" file is found, unless --force is provided`,\n },\n restore: { type: \"boolean\", description: `Restore the previous MUD versions from \"${BACKUP_FILE}\"` },\n mudVersion: { alias: \"v\", type: \"string\", description: \"Set MUD to the given version\" },\n tag: {\n alias: \"t\",\n type: \"string\",\n description: \"Set MUD to the latest version with the given tag from npm\",\n },\n commit: {\n alias: \"c\",\n type: \"string\",\n description: \"Set MUD to the version based on a given git commit hash from npm\",\n },\n link: { alias: \"l\", type: \"string\", description: \"Relative path to the local MUD root directory to link\" },\n });\n },\n\n async handler(options) {\n try {\n const mutuallyExclusiveOptions = [\"mudVersion\", \"link\", \"tag\", \"commit\", \"restore\"];\n const numMutuallyExclusiveOptions = mutuallyExclusiveOptions.reduce(\n (acc, opt) => (options[opt] ? acc + 1 : acc),\n 0\n );\n\n if (numMutuallyExclusiveOptions === 0) {\n throw new MUDError(`You need to provide one these options: ${mutuallyExclusiveOptions.join(\", \")}`);\n }\n\n if (numMutuallyExclusiveOptions > 1) {\n throw new MUDError(`These options are mutually exclusive: ${mutuallyExclusiveOptions.join(\", \")}`);\n }\n\n // Resolve the version number from available options like `tag` or `commit`\n options.mudVersion = await resolveVersion(options);\n\n // Update all package.json below the current working directory (except in node_modules)\n const packageJsons = glob.sync(\"**/package.json\").filter((p) => !p.includes(\"node_modules\"));\n for (const packageJson of packageJsons) {\n updatePackageJson(packageJson, options);\n }\n } catch (e) {\n logError(e);\n } finally {\n process.exit(0);\n }\n },\n};\n\nasync function resolveVersion(options: Options) {\n // Backwards compatibility to previous behavior of this script where passing \"canary\" as the version resolved to the latest commit on main\n if (options.mudVersion === \"canary\") options.tag = \"main\";\n\n let npmResult;\n try {\n console.log(chalk.blue(`Fetching available versions`));\n npmResult = await (await fetch(`https://registry.npmjs.org/${localPackageJson.name}`)).json();\n } catch (e) {\n throw new MUDError(`Could not fetch available MUD versions`);\n }\n\n if (options.tag) {\n const version = npmResult[\"dist-tags\"][options.tag];\n if (!version) {\n throw new MUDError(`Could not find npm version with tag \"${options.tag}\"`);\n }\n console.log(chalk.green(`Latest version with tag ${options.tag}: ${version}`));\n return version;\n }\n\n if (options.commit) {\n // Find a version with this commit hash\n const commit = options.commit.substring(0, 8); // changesets uses the first 8 characters of the commit hash as version for prereleases/snapshot releases\n const version = Object.keys(npmResult[\"versions\"]).find((v) => (v as string).includes(commit));\n if (!version) {\n throw new MUDError(`Could not find npm version based on commit \"${options.commit}\"`);\n }\n console.log(chalk.green(`Version from commit ${options.commit}: ${version}`));\n return version;\n }\n\n // If neither a tag nor a commit option is given, return the `mudVersion`\n return options.mudVersion;\n}\n\nfunction updatePackageJson(filePath: string, options: Options): { workspaces?: string[] } {\n const { restore, force, link } = options;\n let { backup, mudVersion } = options;\n\n const backupFilePath = path.join(path.dirname(filePath), BACKUP_FILE);\n const backupFileExists = existsSync(backupFilePath);\n\n // Create a backup file for previous MUD versions by default if linking to local MUD\n if (link && !backupFileExists) backup = true;\n\n // If `backup` is true and force not set, check if a backup file already exists and throw an error if it does\n if (backup && !force && backupFileExists) {\n throw new MUDError(\n `A backup file already exists at ${backupFilePath}.\\nUse --force to overwrite it or --restore to restore it.`\n );\n }\n\n const packageJson = readPackageJson(filePath);\n\n // Load .mudbackup if `restore` is true\n const backupJson = restore ? readPackageJson(backupFilePath) : undefined;\n\n // Find all MUD dependencies\n const mudDependencies: Record<string, string> = {};\n for (const key in packageJson.dependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n mudDependencies[key] = packageJson.dependencies[key];\n }\n }\n\n // Find all MUD devDependencies\n const mudDevDependencies: Record<string, string> = {};\n for (const key in packageJson.devDependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n mudDevDependencies[key] = packageJson.devDependencies[key];\n }\n }\n\n // Back up the current dependencies if `backup` is true\n if (backup) {\n writeFileSync(\n backupFilePath,\n JSON.stringify({ dependencies: mudDependencies, devDependencies: mudDevDependencies }, null, 2)\n );\n console.log(chalk.green(`Backed up MUD dependencies from ${filePath} to ${backupFilePath}`));\n }\n\n // Update the dependencies\n for (const key in packageJson.dependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n packageJson.dependencies[key] = resolveMudVersion(key, \"dependencies\");\n }\n }\n\n // Update the devDependencies\n for (const key in packageJson.devDependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n packageJson.devDependencies[key] = resolveMudVersion(key, \"devDependencies\");\n }\n }\n\n // Write the updated package.json\n writeFileSync(filePath, JSON.stringify(packageJson, null, 2) + \"\\n\");\n\n console.log(`Updating ${filePath}`);\n logComparison(mudDependencies, packageJson.dependencies);\n logComparison(mudDevDependencies, packageJson.devDependencies);\n\n // Remove the backup file if `restore` is true and `backup` is false\n // because the old backup file is no longer needed\n if (restore && !backup) {\n rmSync(backupFilePath);\n console.log(chalk.green(`Cleaned up ${backupFilePath}`));\n }\n\n return packageJson;\n\n function resolveMudVersion(key: string, type: \"dependencies\" | \"devDependencies\") {\n if (restore && backupJson) return backupJson[type][key];\n if (link) mudVersion = resolveLinkPath(filePath, link, key);\n if (!mudVersion) return packageJson[type][key];\n return mudVersion;\n }\n}\n\nfunction readPackageJson(path: string): {\n workspaces?: string[];\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n} {\n try {\n const jsonString = readFileSync(path, \"utf8\");\n return JSON.parse(jsonString);\n } catch {\n throw new MUDError(\"Could not read JSON at \" + path);\n }\n}\n\nfunction logComparison(prev: Record<string, string>, curr: Record<string, string>) {\n for (const key in prev) {\n if (prev[key] !== curr[key]) {\n console.log(`${key}: ${chalk.red(prev[key])} -> ${chalk.green(curr[key])}`);\n }\n }\n}\n\n/**\n * Returns path of the package to link, given a path to a local MUD clone and a package\n */\nfunction resolveLinkPath(packageJsonPath: string, mudLinkPath: string, pkg: string) {\n const pkgName = pkg.replace(MUD_PREFIX, \"\");\n const packageJsonToRootPath = path.relative(path.dirname(packageJsonPath), process.cwd());\n const linkPath = path.join(packageJsonToRootPath, mudLinkPath, \"packages\", pkgName);\n return \"link:\" + linkPath;\n}\n\nexport default commandModule;\n","{\n \"name\": \"@latticexyz/cli\",\n \"version\": \"2.0.0-next.5\",\n \"description\": \"Command line interface for mud\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/latticexyz/mud.git\",\n \"directory\": \"packages/cli\"\n },\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"exports\": {\n \".\": \"./dist/index.js\"\n },\n \"types\": \"src/index.ts\",\n \"bin\": {\n \"mud\": \"./dist/mud.js\"\n },\n \"scripts\": {\n \"build\": \"pnpm run build:js && pnpm run build:test-tables\",\n \"build:js\": \"tsup && chmod +x ./dist/mud.js\",\n \"build:test-tables\": \"tsx ./scripts/generate-test-tables.ts\",\n \"clean\": \"pnpm run clean:js\",\n \"clean:js\": \"rimraf dist\",\n \"dev\": \"tsup --watch\",\n \"lint\": \"eslint . --ext .ts\",\n \"test\": \"tsc --noEmit && forge test\",\n \"test:ci\": \"pnpm run test\"\n },\n \"dependencies\": {\n \"@ethersproject/abi\": \"^5.7.0\",\n \"@ethersproject/providers\": \"^5.7.2\",\n \"@improbable-eng/grpc-web\": \"^0.15.0\",\n \"@improbable-eng/grpc-web-node-http-transport\": \"^0.15.0\",\n \"@latticexyz/common\": \"workspace:*\",\n \"@latticexyz/config\": \"workspace:*\",\n \"@latticexyz/gas-report\": \"workspace:*\",\n \"@latticexyz/protocol-parser\": \"workspace:*\",\n \"@latticexyz/schema-type\": \"workspace:*\",\n \"@latticexyz/services\": \"workspace:*\",\n \"@latticexyz/store\": \"workspace:*\",\n \"@latticexyz/utils\": \"workspace:*\",\n \"@latticexyz/world\": \"workspace:*\",\n \"@typechain/ethers-v5\": \"^10.2.0\",\n \"chalk\": \"^5.0.1\",\n \"chokidar\": \"^3.5.3\",\n \"dotenv\": \"^16.0.3\",\n \"ejs\": \"^3.1.8\",\n \"ethers\": \"^5.7.2\",\n \"execa\": \"^7.0.0\",\n \"glob\": \"^8.0.3\",\n \"nice-grpc-web\": \"^2.0.1\",\n \"openurl\": \"^1.1.1\",\n \"path\": \"^0.12.7\",\n \"throttle-debounce\": \"^5.0.0\",\n \"typechain\": \"^8.1.1\",\n \"typescript\": \"5.1.6\",\n \"yargs\": \"^17.7.1\",\n \"zod\": \"^3.21.4\",\n \"zod-validation-error\": \"^1.3.0\"\n },\n \"devDependencies\": {\n \"@types/ejs\": \"^3.1.1\",\n \"@types/glob\": \"^7.2.0\",\n \"@types/node\": \"^18.15.11\",\n \"@types/openurl\": \"^1.0.0\",\n \"@types/throttle-debounce\": \"^5.0.0\",\n \"@types/yargs\": \"^17.0.10\",\n \"ds-test\": \"https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0\",\n \"forge-std\": \"https://github.com/foundry-rs/forge-std.git#74cfb77e308dd188d2f58864aaf44963ae6b88b1\",\n \"tsup\": \"^6.7.0\",\n \"tsx\": \"^3.12.6\",\n \"vitest\": \"0.31.4\"\n },\n \"gitHead\": \"914a1e0ae4a573d685841ca2ea921435057deb8f\"\n}\n","import type { CommandModule } from \"yargs\";\nimport { anvil, forge, getRpcUrl } from \"@latticexyz/common/foundry\";\nimport chalk from \"chalk\";\nimport { rmSync, writeFileSync } from \"fs\";\nimport { yDeployOptions } from \"./deploy\";\nimport { deployHandler, DeployOptions } from \"../utils\";\n\ntype Options = DeployOptions & { port?: number; worldAddress?: string; forgeOptions?: string };\n\nconst WORLD_ADDRESS_FILE = \".mudtest\";\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"test\",\n\n describe: \"Run tests in MUD contracts\",\n\n builder(yargs) {\n return yargs.options({\n ...yDeployOptions,\n port: { type: \"number\", description: \"Port to run internal node for fork testing on\", default: 4242 },\n worldAddress: {\n type: \"string\",\n description:\n \"Address of an existing world contract. If provided, deployment is skipped and the RPC provided in the foundry.toml is used for fork testing.\",\n },\n forgeOptions: { type: \"string\", description: \"Options to pass to forge test\" },\n });\n },\n\n async handler(args) {\n // Start an internal anvil process if no world address is provided\n if (!args.worldAddress) {\n const anvilArgs = [\"--block-base-fee-per-gas\", \"0\", \"--port\", String(args.port)];\n anvil(anvilArgs);\n }\n\n const forkRpc = args.worldAddress ? await getRpcUrl(args.profile) : `http://127.0.0.1:${args.port}`;\n\n const worldAddress =\n args.worldAddress ??\n (\n await deployHandler({\n ...args,\n saveDeployment: false,\n rpc: forkRpc,\n })\n ).worldAddress;\n\n console.log(chalk.blue(\"World address\", worldAddress));\n\n // Create a temporary file to pass the world address to the tests\n writeFileSync(WORLD_ADDRESS_FILE, worldAddress);\n\n const userOptions = args.forgeOptions?.replaceAll(\"\\\\\", \"\").split(\" \") ?? [];\n try {\n const testResult = await forge([\"test\", \"--fork-url\", forkRpc, ...userOptions], {\n profile: args.profile,\n });\n console.log(testResult);\n } catch (e) {\n console.error(e);\n rmSync(WORLD_ADDRESS_FILE);\n process.exit(1);\n }\n\n rmSync(WORLD_ADDRESS_FILE);\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import { existsSync, readFileSync } from \"fs\";\nimport type { CommandModule } from \"yargs\";\nimport { ethers } from \"ethers\";\n\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { cast, getRpcUrl, getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { resolveWorldConfig, WorldConfig } from \"@latticexyz/world\";\nimport { IBaseWorld } from \"@latticexyz/world/types/ethers-contracts/IBaseWorld\";\nimport IBaseWorldData from \"@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json\" assert { type: \"json\" };\nimport worldConfig from \"@latticexyz/world/mud.config.js\";\nimport { tableIdToHex } from \"@latticexyz/common\";\nimport { getChainId, getExistingContracts } from \"../utils\";\n\n// TODO account for multiple namespaces (https://github.com/latticexyz/mud/issues/994)\nconst systemsTableId = tableIdToHex(worldConfig.namespace, worldConfig.tables.Systems.name);\n\ntype Options = {\n tx: string;\n worldAddress?: string;\n configPath?: string;\n profile?: string;\n srcDir?: string;\n rpc?: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"trace\",\n\n describe: \"Display the trace of a transaction\",\n\n builder(yargs) {\n return yargs.options({\n tx: { type: \"string\", required: true, description: \"Transaction hash to replay\" },\n worldAddress: {\n type: \"string\",\n description: \"World contract address. Defaults to the value from worlds.json, based on rpc's chainId\",\n },\n configPath: { type: \"string\", description: \"Path to the config file\" },\n profile: { type: \"string\", description: \"The foundry profile to use\" },\n srcDir: { type: \"string\", description: \"Source directory. Defaults to foundry src directory.\" },\n rpc: { type: \"string\", description: \"json rpc endpoint. Defaults to foundry's configured eth_rpc_url\" },\n });\n },\n\n async handler(args) {\n args.profile ??= process.env.FOUNDRY_PROFILE;\n const { profile } = args;\n args.srcDir ??= await getSrcDirectory(profile);\n args.rpc ??= await getRpcUrl(profile);\n const { tx, configPath, srcDir, rpc } = args;\n\n const existingContracts = getExistingContracts(srcDir);\n\n // Load the config\n const mudConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n const resolvedConfig = resolveWorldConfig(\n mudConfig,\n existingContracts.map(({ basename }) => basename)\n );\n\n // Get worldAddress either from args or from worldsFile\n const worldAddress = args.worldAddress ?? (await getWorldAddress(mudConfig.worldsFile, rpc));\n\n // Create World contract instance from deployed address\n const provider = new ethers.providers.StaticJsonRpcProvider(rpc);\n const WorldContract = new ethers.Contract(worldAddress, IBaseWorldData.abi, provider) as IBaseWorld;\n\n // TODO account for multiple namespaces (https://github.com/latticexyz/mud/issues/994)\n const namespace = mudConfig.namespace;\n const names = Object.values(resolvedConfig.systems).map(({ name }) => name);\n\n // Fetch system table schema from chain\n const systemTableSchema = await WorldContract.getValueSchema(systemsTableId);\n const labels: { name: string; address: string }[] = [];\n for (const name of names) {\n const systemSelector = tableIdToHex(namespace, name);\n // Get the first field of `Systems` table (the table maps system name to its address and other data)\n const address = await WorldContract.getField(systemsTableId, [systemSelector], 0, systemTableSchema);\n labels.push({ name, address });\n }\n\n const result = await cast([\n \"run\",\n \"--label\",\n `${worldAddress}:World`,\n ...labels.map(({ name, address }) => [\"--label\", `${address}:${name}`]).flat(),\n `${tx}`,\n ]);\n console.log(result);\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n\nasync function getWorldAddress(worldsFile: string, rpc: string) {\n if (existsSync(worldsFile)) {\n const chainId = await getChainId(rpc);\n const deploys = JSON.parse(readFileSync(worldsFile, \"utf-8\"));\n\n if (!deploys[chainId]) {\n throw new MUDError(`chainId ${chainId} is missing in worldsFile \"${worldsFile}\"`);\n }\n return deploys[chainId].address as string;\n } else {\n throw new MUDError(\"worldAddress is not specified and worldsFile is missing\");\n }\n}\n","import type { CommandModule } from \"yargs\";\nimport { anvil, forge, getRpcUrl, getScriptDirectory, getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport chalk from \"chalk\";\nimport chokidar from \"chokidar\";\nimport { loadConfig, resolveConfigPath } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { tablegen } from \"@latticexyz/store/codegen\";\nimport path from \"path\";\nimport { debounce } from \"throttle-debounce\";\nimport { worldgenHandler } from \"./worldgen\";\nimport { WorldConfig } from \"@latticexyz/world\";\nimport { deployHandler, logError, printMUD, worldtypes } from \"../utils\";\nimport { homedir } from \"os\";\nimport { rmSync } from \"fs\";\n\ntype Options = {\n rpc?: string;\n configPath?: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"dev-contracts\",\n\n describe: \"Start a development server for MUD contracts\",\n\n builder(yargs) {\n return yargs.options({\n rpc: {\n type: \"string\",\n decs: \"RPC endpoint of the development node. If none is provided, an anvil instance is spawned in the background on port 8545.\",\n },\n configPath: {\n type: \"string\",\n decs: \"Path to MUD config\",\n },\n });\n },\n\n async handler(args) {\n // Initial cleanup\n await forge([\"clean\"]);\n\n const rpc = args.rpc ?? (await getRpcUrl());\n const configPath = args.configPath ?? (await resolveConfigPath(args.configPath));\n const srcDirectory = await getSrcDirectory();\n const scriptDirectory = await getScriptDirectory();\n const initialConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n // Initial run of all codegen steps before starting anvil\n // (so clients can wait for everything to be ready before starting)\n await handleConfigChange(initialConfig);\n await handleContractsChange(initialConfig);\n\n // Start an anvil instance in the background if no RPC url is provided\n if (!args.rpc) {\n console.log(chalk.gray(\"Cleaning devnode cache\"));\n const userHomeDir = homedir();\n rmSync(path.join(userHomeDir, \".foundry\", \"anvil\", \"tmp\"), { recursive: true, force: true });\n\n const anvilArgs = [\"--block-time\", \"1\", \"--block-base-fee-per-gas\", \"0\"];\n anvil(anvilArgs);\n }\n\n const changedSinceLastHandled = {\n config: false,\n contracts: false,\n };\n\n const changeInProgress = {\n current: false,\n };\n\n // Watch for changes\n const configWatcher = chokidar.watch([configPath, srcDirectory]);\n configWatcher.on(\"all\", async (_, updatePath) => {\n if (updatePath.includes(configPath)) {\n changedSinceLastHandled.config = true;\n // We trigger contract changes if the config changed here instead of\n // listening to changes in the codegen directory to avoid an infinite loop\n changedSinceLastHandled.contracts = true;\n }\n\n if (updatePath.includes(srcDirectory) || updatePath.includes(scriptDirectory)) {\n // Ignore changes to codegen files to avoid an infinite loop\n if (updatePath.includes(initialConfig.codegenDirectory)) return;\n changedSinceLastHandled.contracts = true;\n }\n\n // Trigger debounced onChange\n handleChange();\n });\n\n const handleChange = debounce(100, async () => {\n // Avoid handling changes multiple times in parallel\n if (changeInProgress.current) return;\n changeInProgress.current = true;\n\n // Reset dirty flags\n const { config, contracts } = changedSinceLastHandled;\n changedSinceLastHandled.config = false;\n changedSinceLastHandled.contracts = false;\n\n try {\n // Load latest config\n const mudConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n // Handle changes\n if (config) await handleConfigChange(mudConfig);\n if (contracts) await handleContractsChange(mudConfig);\n\n await deploy();\n } catch (error) {\n console.error(chalk.red(\"MUD dev-contracts watcher failed to deploy config or contracts changes\\n\"));\n logError(error);\n }\n\n changeInProgress.current = false;\n if (changedSinceLastHandled.config || changedSinceLastHandled.contracts) {\n console.log(\"Detected change while handling the previous change\");\n handleChange();\n }\n\n printMUD();\n console.log(\"MUD watching for changes...\");\n });\n\n /** Codegen to run if config changes */\n async function handleConfigChange(config: StoreConfig & WorldConfig) {\n console.log(chalk.blue(\"mud.config.ts changed - regenerating tables and recs types\"));\n // Run tablegen to generate tables based on the config\n const outPath = path.join(srcDirectory, config.codegenDirectory);\n await tablegen(config, outPath);\n }\n\n /** Codegen to run if contracts changed */\n async function handleContractsChange(config: StoreConfig & WorldConfig) {\n console.log(chalk.blue(\"contracts changed - regenerating interfaces and contract types\"));\n\n // Run worldgen to generate interfaces based on the systems\n await worldgenHandler({ config, clean: true, srcDir: srcDirectory });\n\n // Build the contracts\n await forge([\"build\"]);\n\n // Run typechain to rebuild typescript types for the contracts\n await worldtypes();\n }\n\n /** Run after codegen if either mud config or contracts changed */\n async function deploy() {\n console.log(chalk.blue(\"redeploying World\"));\n await deployHandler({\n configPath,\n skipBuild: true,\n priorityFeeMultiplier: 1,\n disableTxWait: true,\n pollInterval: 1000,\n saveDeployment: true,\n srcDir: srcDirectory,\n rpc,\n });\n }\n },\n};\n\nexport default commandModule;\n"],"mappings":"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","names":["yargs","hideBin","gasReport","rmSync","homedir","path","execa","commandModule","yargs","blocktime","userHomeDir","anvilArgs","child","devnode_default","FaucetServiceDefinition","createChannel","createClient","chalk","NodeHttpTransport","createFaucetService","url","commandModule","yargs","dripDev","faucetUrl","address","faucet","faucet_default","commandModule","yargs","name","greeting","hello_default","path","loadConfig","tablegen","getSrcDirectory","commandModule","yargs","configPath","config","srcDir","tablegen_default","chalk","ZodError","fromZodError","ValidationError","NotInsideProjectError","MUDError","logError","error","validationError","chalk","printMUD","getOutDirectory","path","runTypeChain","worldtypes","cwd","forgeOurDir","IWorldPath","yDeployOptions","commandModule","yargs","args","deployHandler","error","logError","deploy_default","loadConfig","worldgen","getSrcDirectory","path","rmSync","commandModule","yargs","args","worldgenHandler","srcDir","getSrcDirectory","existingContracts","getExistingContracts","mudConfig","loadConfig","outputBaseDirectory","path","rmSync","worldgen","worldgen_default","chalk","existsSync","readFileSync","rmSync","writeFileSync","path","MUDError","package_default","glob","BACKUP_FILE","MUD_PREFIX","commandModule","yargs","options","mutuallyExclusiveOptions","numMutuallyExclusiveOptions","acc","opt","MUDError","resolveVersion","packageJsons","p","packageJson","updatePackageJson","e","logError","npmResult","chalk","package_default","version","commit","v","filePath","restore","force","link","backup","mudVersion","backupFilePath","path","backupFileExists","existsSync","readPackageJson","backupJson","mudDependencies","key","mudDevDependencies","writeFileSync","resolveMudVersion","logComparison","rmSync","type","resolveLinkPath","jsonString","readFileSync","prev","curr","packageJsonPath","mudLinkPath","pkg","pkgName","packageJsonToRootPath","set_version_default","anvil","forge","getRpcUrl","chalk","rmSync","writeFileSync","WORLD_ADDRESS_FILE","commandModule","yargs","yDeployOptions","args","anvilArgs","anvil","forkRpc","getRpcUrl","worldAddress","deployHandler","chalk","writeFileSync","userOptions","testResult","forge","e","rmSync","test_default","existsSync","readFileSync","ethers","loadConfig","MUDError","cast","getRpcUrl","getSrcDirectory","resolveWorldConfig","IBaseWorldData","worldConfig","tableIdToHex","systemsTableId","tableIdToHex","worldConfig","commandModule","yargs","args","profile","getSrcDirectory","getRpcUrl","tx","configPath","srcDir","rpc","existingContracts","getExistingContracts","mudConfig","loadConfig","resolvedConfig","resolveWorldConfig","basename","worldAddress","getWorldAddress","provider","ethers","WorldContract","IBaseWorldData","namespace","names","name","systemTableSchema","labels","systemSelector","address","result","cast","trace_default","worldsFile","existsSync","chainId","getChainId","deploys","readFileSync","MUDError","anvil","forge","getRpcUrl","getScriptDirectory","getSrcDirectory","chalk","chokidar","loadConfig","resolveConfigPath","tablegen","path","debounce","homedir","rmSync","commandModule","yargs","args","forge","rpc","getRpcUrl","configPath","resolveConfigPath","srcDirectory","getSrcDirectory","scriptDirectory","getScriptDirectory","initialConfig","loadConfig","handleConfigChange","handleContractsChange","chalk","userHomeDir","path","anvil","changedSinceLastHandled","changeInProgress","chokidar","_","updatePath","handleChange","debounce","config","contracts","mudConfig","deploy","error","logError","printMUD","outPath","tablegen","worldgenHandler","worldtypes","deployHandler","dev_contracts_default","commands","deploy_default","devnode_default","faucet_default","gasReport","hello_default","tablegen_default","worldgen_default","set_version_default","test_default","trace_default","dev_contracts_default","dotenv","chalk","yargs","hideBin","commands","msg","err","logError"]}
1
+ {"version":3,"sources":["../src/mud.ts","../src/commands/index.ts","../src/commands/devnode.ts","../src/commands/faucet.ts","../src/commands/hello.ts","../src/commands/tablegen.ts","../src/utils/errors.ts","../src/utils/printMUD.ts","../src/commands/deploy.ts","../src/commands/worldgen.ts","../src/commands/set-version.ts","../package.json","../src/commands/test.ts","../src/commands/trace.ts","../src/commands/dev-contracts.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { commands } from \"./commands\";\nimport { logError } from \"./utils/errors\";\n\n// Load .env file into process.env\nimport * as dotenv from \"dotenv\";\nimport chalk from \"chalk\";\ndotenv.config();\n\nyargs(hideBin(process.argv))\n // Explicit name to display in help (by default it's the entry file, which may not be \"mud\" for e.g. ts-node)\n .scriptName(\"mud\")\n // Use the commands directory to scaffold\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- command array overload isn't typed, see https://github.com/yargs/yargs/blob/main/docs/advanced.md#esm-hierarchy\n .command(commands as any)\n // Enable strict mode.\n .strict()\n // Custom error handler\n .fail((msg, err) => {\n console.error(chalk.red(msg));\n if (msg.includes(\"Missing required argument\")) {\n console.log(\n chalk.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`)\n );\n }\n console.log(\"\");\n // Even though `.fail` type says we should get an `Error`, this can sometimes be undefined\n if (err != null) {\n logError(err);\n console.log(\"\");\n }\n\n process.exit(1);\n })\n // Useful aliases.\n .alias({ h: \"help\" }).argv;\n","import { CommandModule } from \"yargs\";\n\nimport gasReport from \"@latticexyz/gas-report\";\nimport abiTs from \"@latticexyz/abi-ts\";\n\nimport devnode from \"./devnode\";\nimport faucet from \"./faucet\";\nimport hello from \"./hello\";\nimport tablegen from \"./tablegen\";\nimport deploy from \"./deploy\";\nimport worldgen from \"./worldgen\";\nimport setVersion from \"./set-version\";\nimport test from \"./test\";\nimport trace from \"./trace\";\nimport devContracts from \"./dev-contracts\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Each command has different options\nexport const commands: CommandModule<any, any>[] = [\n deploy,\n devnode,\n faucet,\n gasReport as CommandModule,\n hello,\n tablegen,\n worldgen,\n setVersion,\n test,\n trace,\n devContracts,\n abiTs,\n];\n","import { rmSync } from \"fs\";\nimport { homedir } from \"os\";\nimport path from \"path\";\nimport type { CommandModule } from \"yargs\";\nimport { execa } from \"execa\";\n\ntype Options = {\n blocktime: number;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"devnode\",\n\n describe: \"Start a local Ethereum node for development\",\n\n builder(yargs) {\n return yargs.options({\n blocktime: { type: \"number\", default: 1, decs: \"Interval in which new blocks are produced\" },\n });\n },\n\n async handler({ blocktime }) {\n console.log(\"Clearing devnode history\");\n const userHomeDir = homedir();\n rmSync(path.join(userHomeDir, \".foundry\", \"anvil\", \"tmp\"), { recursive: true, force: true });\n\n const anvilArgs = [\"-b\", String(blocktime), \"--block-base-fee-per-gas\", \"0\"];\n console.log(`Running: anvil ${anvilArgs.join(\" \")}`);\n const child = execa(\"anvil\", anvilArgs, {\n stdio: [\"inherit\", \"inherit\", \"inherit\"],\n });\n\n process.on(\"SIGINT\", () => {\n console.log(\"\\ngracefully shutting down from SIGINT (Crtl-C)\");\n child.kill();\n process.exit();\n });\n await child;\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\nimport { FaucetServiceDefinition } from \"@latticexyz/services/faucet\";\nimport { createChannel, createClient } from \"nice-grpc-web\";\nimport chalk from \"chalk\";\nimport { NodeHttpTransport } from \"@improbable-eng/grpc-web-node-http-transport\";\n\ntype Options = {\n dripDev?: boolean;\n faucetUrl: string;\n address: string;\n};\n\n/**\n * Create a FaucetServiceClient\n * @param url FaucetService URL\n * @returns FaucetServiceClient\n */\nfunction createFaucetService(url: string) {\n return createClient(FaucetServiceDefinition, createChannel(url, NodeHttpTransport()));\n}\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"faucet\",\n\n describe: \"Interact with a MUD faucet\",\n\n builder(yargs) {\n return yargs.options({\n dripDev: {\n type: \"boolean\",\n desc: \"Request a drip from the dev endpoint (requires faucet to have dev mode enabled)\",\n default: true,\n },\n faucetUrl: {\n type: \"string\",\n desc: \"URL of the MUD faucet\",\n default: \"https://faucet.testnet-mud-services.linfra.xyz\",\n },\n address: {\n type: \"string\",\n desc: \"Ethereum address to fund\",\n required: true,\n },\n });\n },\n\n async handler({ dripDev, faucetUrl, address }) {\n const faucet = createFaucetService(faucetUrl);\n\n if (dripDev) {\n console.log(chalk.yellow(\"Dripping to\", address));\n await faucet.dripDev({ address });\n console.log(chalk.yellow(\"Success\"));\n }\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\n\ntype Options = {\n name: string;\n upper: boolean | undefined;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"hello <name>\",\n\n describe: \"Greet <name> with Hello\",\n\n builder(yargs) {\n return yargs\n .options({\n upper: { type: \"boolean\" },\n })\n .positional(\"name\", { type: \"string\", demandOption: true });\n },\n\n handler({ name }) {\n const greeting = `Gm, ${name}!`;\n console.log(greeting);\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import path from \"path\";\nimport type { CommandModule } from \"yargs\";\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { tablegen } from \"@latticexyz/store/codegen\";\nimport { getSrcDirectory } from \"@latticexyz/common/foundry\";\n\ntype Options = {\n configPath?: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"tablegen\",\n\n describe: \"Autogenerate MUD Store table libraries based on the config file\",\n\n builder(yargs) {\n return yargs.options({\n configPath: { type: \"string\", desc: \"Path to the config file\" },\n });\n },\n\n async handler({ configPath }) {\n const config = (await loadConfig(configPath)) as StoreConfig;\n const srcDir = await getSrcDirectory();\n\n await tablegen(config, path.join(srcDir, config.codegenDirectory));\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import chalk from \"chalk\";\nimport { ZodError } from \"zod\";\nimport { fromZodError, ValidationError } from \"zod-validation-error\";\nimport { NotInsideProjectError } from \"@latticexyz/config\";\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","import chalk from \"chalk\";\n\nexport function printMUD() {\n console.log(\n chalk.yellow(`\n.------..------..------.\n|M.--. ||U.--. ||D.--. |\n| (\\\\/) || (\\\\/) || :/\\\\: |\n| :\\\\/: || :\\\\/: || (__) |\n| '--'M|| '--'U|| '--'D|\n'------''------''------'\n`)\n );\n}\n","import type { CommandModule, Options } from \"yargs\";\nimport { logError } from \"../utils/errors\";\nimport { deployHandler, DeployOptions } from \"../utils\";\n\nexport const yDeployOptions = {\n configPath: { type: \"string\", desc: \"Path to the config file\" },\n clean: { type: \"boolean\", desc: \"Remove the build forge artifacts and cache directories before building\" },\n printConfig: { type: \"boolean\", desc: \"Print the resolved config\" },\n profile: { type: \"string\", desc: \"The foundry profile to use\" },\n debug: { type: \"boolean\", desc: \"Print debug logs, like full error messages\" },\n priorityFeeMultiplier: {\n type: \"number\",\n desc: \"Multiply the estimated priority fee by the provided factor\",\n default: 1,\n },\n saveDeployment: { type: \"boolean\", desc: \"Save the deployment info to a file\", default: true },\n rpc: { type: \"string\", desc: \"The RPC URL to use. Defaults to the RPC url from the local foundry.toml\" },\n worldAddress: { type: \"string\", desc: \"Deploy to an existing World at the given address\" },\n srcDir: { type: \"string\", desc: \"Source directory. Defaults to foundry src directory.\" },\n disableTxWait: { type: \"boolean\", desc: \"Disable waiting for transactions to be confirmed.\", default: false },\n pollInterval: {\n type: \"number\",\n desc: \"Interval in miliseconds to use to poll for transaction receipts / block inclusion\",\n default: 1000,\n },\n skipBuild: { type: \"boolean\", desc: \"Skip rebuilding the contracts before deploying\" },\n} satisfies Record<keyof DeployOptions, Options>;\n\nconst commandModule: CommandModule<DeployOptions, DeployOptions> = {\n command: \"deploy\",\n\n describe: \"Deploy MUD contracts\",\n\n builder(yargs) {\n return yargs.options(yDeployOptions);\n },\n\n async handler(args) {\n try {\n await deployHandler(args);\n } catch (error: any) {\n logError(error);\n process.exit(1);\n }\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import type { CommandModule } from \"yargs\";\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { WorldConfig } from \"@latticexyz/world\";\nimport { worldgen } from \"@latticexyz/world/node\";\nimport { getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport path from \"path\";\nimport { rmSync } from \"fs\";\nimport { getExistingContracts } from \"../utils\";\n\ntype Options = {\n configPath?: string;\n clean?: boolean;\n srcDir?: string;\n config?: StoreConfig & WorldConfig;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"worldgen\",\n\n describe: \"Autogenerate interfaces for Systems and World based on existing contracts and the config file\",\n\n builder(yargs) {\n return yargs.options({\n configPath: { type: \"string\", desc: \"Path to the config file\" },\n clean: {\n type: \"boolean\",\n desc: \"Clear the worldgen directory before generating new interfaces (defaults to true)\",\n default: true,\n },\n });\n },\n\n async handler(args) {\n await worldgenHandler(args);\n process.exit(0);\n },\n};\n\nexport async function worldgenHandler(args: Options) {\n const srcDir = args.srcDir ?? (await getSrcDirectory());\n\n const existingContracts = getExistingContracts(srcDir);\n\n // Load the config\n const mudConfig = args.config ?? ((await loadConfig(args.configPath)) as StoreConfig & WorldConfig);\n\n const outputBaseDirectory = path.join(srcDir, mudConfig.codegenDirectory);\n\n // clear the worldgen directory\n if (args.clean) rmSync(path.join(outputBaseDirectory, mudConfig.worldgenDirectory), { recursive: true, force: true });\n\n // generate new interfaces\n await worldgen(mudConfig, existingContracts, outputBaseDirectory);\n}\n\nexport default commandModule;\n","import chalk from \"chalk\";\nimport { existsSync, readFileSync, rmSync, writeFileSync } from \"fs\";\nimport path from \"path\";\nimport type { CommandModule } from \"yargs\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { logError } from \"../utils/errors\";\nimport localPackageJson from \"../../package.json\" assert { type: \"json\" };\nimport glob from \"glob\";\n\ntype Options = {\n backup?: boolean;\n force?: boolean;\n restore?: boolean;\n mudVersion?: string;\n tag?: string;\n commit?: string;\n link?: string;\n};\n\nconst BACKUP_FILE = \".mudbackup\";\nconst MUD_PREFIX = \"@latticexyz\";\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"set-version\",\n\n describe: \"Set MUD version in all package.json files and optionally backup the previously installed version\",\n\n builder(yargs) {\n return yargs.options({\n backup: { type: \"boolean\", description: `Back up the current MUD versions to \"${BACKUP_FILE}\"` },\n force: {\n type: \"boolean\",\n description: `Backup fails if a \"${BACKUP_FILE}\" file is found, unless --force is provided`,\n },\n restore: { type: \"boolean\", description: `Restore the previous MUD versions from \"${BACKUP_FILE}\"` },\n mudVersion: { alias: \"v\", type: \"string\", description: \"Set MUD to the given version\" },\n tag: {\n alias: \"t\",\n type: \"string\",\n description: \"Set MUD to the latest version with the given tag from npm\",\n },\n commit: {\n alias: \"c\",\n type: \"string\",\n description: \"Set MUD to the version based on a given git commit hash from npm\",\n },\n link: { alias: \"l\", type: \"string\", description: \"Relative path to the local MUD root directory to link\" },\n });\n },\n\n async handler(options) {\n try {\n const mutuallyExclusiveOptions = [\"mudVersion\", \"link\", \"tag\", \"commit\", \"restore\"];\n const numMutuallyExclusiveOptions = mutuallyExclusiveOptions.reduce(\n (acc, opt) => (options[opt] ? acc + 1 : acc),\n 0\n );\n\n if (numMutuallyExclusiveOptions === 0) {\n throw new MUDError(`You need to provide one these options: ${mutuallyExclusiveOptions.join(\", \")}`);\n }\n\n if (numMutuallyExclusiveOptions > 1) {\n throw new MUDError(`These options are mutually exclusive: ${mutuallyExclusiveOptions.join(\", \")}`);\n }\n\n // Resolve the version number from available options like `tag` or `commit`\n options.mudVersion = await resolveVersion(options);\n\n // Update all package.json below the current working directory (except in node_modules)\n const packageJsons = glob.sync(\"**/package.json\").filter((p) => !p.includes(\"node_modules\"));\n for (const packageJson of packageJsons) {\n updatePackageJson(packageJson, options);\n }\n } catch (e) {\n logError(e);\n } finally {\n process.exit(0);\n }\n },\n};\n\nasync function resolveVersion(options: Options) {\n // Backwards compatibility to previous behavior of this script where passing \"canary\" as the version resolved to the latest commit on main\n if (options.mudVersion === \"canary\") options.tag = \"main\";\n\n let npmResult;\n try {\n console.log(chalk.blue(`Fetching available versions`));\n npmResult = await (await fetch(`https://registry.npmjs.org/${localPackageJson.name}`)).json();\n } catch (e) {\n throw new MUDError(`Could not fetch available MUD versions`);\n }\n\n if (options.tag) {\n const version = npmResult[\"dist-tags\"][options.tag];\n if (!version) {\n throw new MUDError(`Could not find npm version with tag \"${options.tag}\"`);\n }\n console.log(chalk.green(`Latest version with tag ${options.tag}: ${version}`));\n return version;\n }\n\n if (options.commit) {\n // Find a version with this commit hash\n const commit = options.commit.substring(0, 8); // changesets uses the first 8 characters of the commit hash as version for prereleases/snapshot releases\n const version = Object.keys(npmResult[\"versions\"]).find((v) => (v as string).includes(commit));\n if (!version) {\n throw new MUDError(`Could not find npm version based on commit \"${options.commit}\"`);\n }\n console.log(chalk.green(`Version from commit ${options.commit}: ${version}`));\n return version;\n }\n\n // If neither a tag nor a commit option is given, return the `mudVersion`\n return options.mudVersion;\n}\n\nfunction updatePackageJson(filePath: string, options: Options): { workspaces?: string[] } {\n const { restore, force, link } = options;\n let { backup, mudVersion } = options;\n\n const backupFilePath = path.join(path.dirname(filePath), BACKUP_FILE);\n const backupFileExists = existsSync(backupFilePath);\n\n // Create a backup file for previous MUD versions by default if linking to local MUD\n if (link && !backupFileExists) backup = true;\n\n // If `backup` is true and force not set, check if a backup file already exists and throw an error if it does\n if (backup && !force && backupFileExists) {\n throw new MUDError(\n `A backup file already exists at ${backupFilePath}.\\nUse --force to overwrite it or --restore to restore it.`\n );\n }\n\n const packageJson = readPackageJson(filePath);\n\n // Load .mudbackup if `restore` is true\n const backupJson = restore ? readPackageJson(backupFilePath) : undefined;\n\n // Find all MUD dependencies\n const mudDependencies: Record<string, string> = {};\n for (const key in packageJson.dependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n mudDependencies[key] = packageJson.dependencies[key];\n }\n }\n\n // Find all MUD devDependencies\n const mudDevDependencies: Record<string, string> = {};\n for (const key in packageJson.devDependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n mudDevDependencies[key] = packageJson.devDependencies[key];\n }\n }\n\n // Back up the current dependencies if `backup` is true\n if (backup) {\n writeFileSync(\n backupFilePath,\n JSON.stringify({ dependencies: mudDependencies, devDependencies: mudDevDependencies }, null, 2)\n );\n console.log(chalk.green(`Backed up MUD dependencies from ${filePath} to ${backupFilePath}`));\n }\n\n // Update the dependencies\n for (const key in packageJson.dependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n packageJson.dependencies[key] = resolveMudVersion(key, \"dependencies\");\n }\n }\n\n // Update the devDependencies\n for (const key in packageJson.devDependencies) {\n if (key.startsWith(MUD_PREFIX)) {\n packageJson.devDependencies[key] = resolveMudVersion(key, \"devDependencies\");\n }\n }\n\n // Write the updated package.json\n writeFileSync(filePath, JSON.stringify(packageJson, null, 2) + \"\\n\");\n\n console.log(`Updating ${filePath}`);\n logComparison(mudDependencies, packageJson.dependencies);\n logComparison(mudDevDependencies, packageJson.devDependencies);\n\n // Remove the backup file if `restore` is true and `backup` is false\n // because the old backup file is no longer needed\n if (restore && !backup) {\n rmSync(backupFilePath);\n console.log(chalk.green(`Cleaned up ${backupFilePath}`));\n }\n\n return packageJson;\n\n function resolveMudVersion(key: string, type: \"dependencies\" | \"devDependencies\") {\n if (restore && backupJson) return backupJson[type][key];\n if (link) mudVersion = resolveLinkPath(filePath, link, key);\n if (!mudVersion) return packageJson[type][key];\n return mudVersion;\n }\n}\n\nfunction readPackageJson(path: string): {\n workspaces?: string[];\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n} {\n try {\n const jsonString = readFileSync(path, \"utf8\");\n return JSON.parse(jsonString);\n } catch {\n throw new MUDError(\"Could not read JSON at \" + path);\n }\n}\n\nfunction logComparison(prev: Record<string, string>, curr: Record<string, string>) {\n for (const key in prev) {\n if (prev[key] !== curr[key]) {\n console.log(`${key}: ${chalk.red(prev[key])} -> ${chalk.green(curr[key])}`);\n }\n }\n}\n\n/**\n * Returns path of the package to link, given a path to a local MUD clone and a package\n */\nfunction resolveLinkPath(packageJsonPath: string, mudLinkPath: string, pkg: string) {\n const pkgName = pkg.replace(MUD_PREFIX, \"\");\n const packageJsonToRootPath = path.relative(path.dirname(packageJsonPath), process.cwd());\n const linkPath = path.join(packageJsonToRootPath, mudLinkPath, \"packages\", pkgName);\n return \"link:\" + linkPath;\n}\n\nexport default commandModule;\n","{\n \"name\": \"@latticexyz/cli\",\n \"version\": \"2.0.0-next.7\",\n \"description\": \"Command line interface for mud\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/latticexyz/mud.git\",\n \"directory\": \"packages/cli\"\n },\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"exports\": {\n \".\": \"./dist/index.js\"\n },\n \"types\": \"src/index.ts\",\n \"bin\": {\n \"mud\": \"./dist/mud.js\"\n },\n \"scripts\": {\n \"build\": \"pnpm run build:js && pnpm run build:test-tables\",\n \"build:js\": \"tsup && chmod +x ./dist/mud.js\",\n \"build:test-tables\": \"tsx ./scripts/generate-test-tables.ts\",\n \"clean\": \"pnpm run clean:js\",\n \"clean:js\": \"rimraf dist\",\n \"dev\": \"tsup --watch\",\n \"lint\": \"eslint . --ext .ts\",\n \"prepare\": \"mkdir -p ./dist && touch ./dist/mud.js\",\n \"test\": \"tsc --noEmit && forge test\",\n \"test:ci\": \"pnpm run test\"\n },\n \"dependencies\": {\n \"@ethersproject/abi\": \"^5.7.0\",\n \"@ethersproject/providers\": \"^5.7.2\",\n \"@improbable-eng/grpc-web\": \"^0.15.0\",\n \"@improbable-eng/grpc-web-node-http-transport\": \"^0.15.0\",\n \"@latticexyz/abi-ts\": \"workspace:*\",\n \"@latticexyz/common\": \"workspace:*\",\n \"@latticexyz/config\": \"workspace:*\",\n \"@latticexyz/gas-report\": \"workspace:*\",\n \"@latticexyz/protocol-parser\": \"workspace:*\",\n \"@latticexyz/schema-type\": \"workspace:*\",\n \"@latticexyz/services\": \"workspace:*\",\n \"@latticexyz/store\": \"workspace:*\",\n \"@latticexyz/utils\": \"workspace:*\",\n \"@latticexyz/world\": \"workspace:*\",\n \"chalk\": \"^5.0.1\",\n \"chokidar\": \"^3.5.3\",\n \"dotenv\": \"^16.0.3\",\n \"ejs\": \"^3.1.8\",\n \"ethers\": \"^5.7.2\",\n \"execa\": \"^7.0.0\",\n \"glob\": \"^8.0.3\",\n \"nice-grpc-web\": \"^2.0.1\",\n \"openurl\": \"^1.1.1\",\n \"path\": \"^0.12.7\",\n \"throttle-debounce\": \"^5.0.0\",\n \"typescript\": \"5.1.6\",\n \"yargs\": \"^17.7.1\",\n \"zod\": \"^3.21.4\",\n \"zod-validation-error\": \"^1.3.0\"\n },\n \"devDependencies\": {\n \"@types/ejs\": \"^3.1.1\",\n \"@types/glob\": \"^7.2.0\",\n \"@types/node\": \"^18.15.11\",\n \"@types/openurl\": \"^1.0.0\",\n \"@types/throttle-debounce\": \"^5.0.0\",\n \"@types/yargs\": \"^17.0.10\",\n \"ds-test\": \"https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0\",\n \"forge-std\": \"https://github.com/foundry-rs/forge-std.git#74cfb77e308dd188d2f58864aaf44963ae6b88b1\",\n \"tsup\": \"^6.7.0\",\n \"tsx\": \"^3.12.6\",\n \"vitest\": \"0.31.4\"\n },\n \"gitHead\": \"914a1e0ae4a573d685841ca2ea921435057deb8f\"\n}\n","import type { CommandModule } from \"yargs\";\nimport { anvil, forge, getRpcUrl } from \"@latticexyz/common/foundry\";\nimport chalk from \"chalk\";\nimport { rmSync, writeFileSync } from \"fs\";\nimport { yDeployOptions } from \"./deploy\";\nimport { deployHandler, DeployOptions } from \"../utils\";\n\ntype Options = DeployOptions & { port?: number; worldAddress?: string; forgeOptions?: string };\n\nconst WORLD_ADDRESS_FILE = \".mudtest\";\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"test\",\n\n describe: \"Run tests in MUD contracts\",\n\n builder(yargs) {\n return yargs.options({\n ...yDeployOptions,\n port: { type: \"number\", description: \"Port to run internal node for fork testing on\", default: 4242 },\n worldAddress: {\n type: \"string\",\n description:\n \"Address of an existing world contract. If provided, deployment is skipped and the RPC provided in the foundry.toml is used for fork testing.\",\n },\n forgeOptions: { type: \"string\", description: \"Options to pass to forge test\" },\n });\n },\n\n async handler(args) {\n // Start an internal anvil process if no world address is provided\n if (!args.worldAddress) {\n const anvilArgs = [\"--block-base-fee-per-gas\", \"0\", \"--port\", String(args.port)];\n anvil(anvilArgs);\n }\n\n const forkRpc = args.worldAddress ? await getRpcUrl(args.profile) : `http://127.0.0.1:${args.port}`;\n\n const worldAddress =\n args.worldAddress ??\n (\n await deployHandler({\n ...args,\n saveDeployment: false,\n rpc: forkRpc,\n })\n ).worldAddress;\n\n console.log(chalk.blue(\"World address\", worldAddress));\n\n // Create a temporary file to pass the world address to the tests\n writeFileSync(WORLD_ADDRESS_FILE, worldAddress);\n\n const userOptions = args.forgeOptions?.replaceAll(\"\\\\\", \"\").split(\" \") ?? [];\n try {\n const testResult = await forge([\"test\", \"--fork-url\", forkRpc, ...userOptions], {\n profile: args.profile,\n });\n console.log(testResult);\n } catch (e) {\n console.error(e);\n rmSync(WORLD_ADDRESS_FILE);\n process.exit(1);\n }\n\n rmSync(WORLD_ADDRESS_FILE);\n process.exit(0);\n },\n};\n\nexport default commandModule;\n","import { existsSync, readFileSync } from \"fs\";\nimport type { CommandModule } from \"yargs\";\nimport { ethers } from \"ethers\";\n\nimport { loadConfig } from \"@latticexyz/config/node\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { cast, getRpcUrl, getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { resolveWorldConfig, WorldConfig } from \"@latticexyz/world\";\nimport IBaseWorldData from \"@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json\" assert { type: \"json\" };\nimport worldConfig from \"@latticexyz/world/mud.config.js\";\nimport { tableIdToHex } from \"@latticexyz/common\";\nimport { getChainId, getExistingContracts } from \"../utils\";\n\n// TODO account for multiple namespaces (https://github.com/latticexyz/mud/issues/994)\nconst systemsTableId = tableIdToHex(worldConfig.namespace, worldConfig.tables.Systems.name);\n\ntype Options = {\n tx: string;\n worldAddress?: string;\n configPath?: string;\n profile?: string;\n srcDir?: string;\n rpc?: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"trace\",\n\n describe: \"Display the trace of a transaction\",\n\n builder(yargs) {\n return yargs.options({\n tx: { type: \"string\", required: true, description: \"Transaction hash to replay\" },\n worldAddress: {\n type: \"string\",\n description: \"World contract address. Defaults to the value from worlds.json, based on rpc's chainId\",\n },\n configPath: { type: \"string\", description: \"Path to the config file\" },\n profile: { type: \"string\", description: \"The foundry profile to use\" },\n srcDir: { type: \"string\", description: \"Source directory. Defaults to foundry src directory.\" },\n rpc: { type: \"string\", description: \"json rpc endpoint. Defaults to foundry's configured eth_rpc_url\" },\n });\n },\n\n async handler(args) {\n args.profile ??= process.env.FOUNDRY_PROFILE;\n const { profile } = args;\n args.srcDir ??= await getSrcDirectory(profile);\n args.rpc ??= await getRpcUrl(profile);\n const { tx, configPath, srcDir, rpc } = args;\n\n const existingContracts = getExistingContracts(srcDir);\n\n // Load the config\n const mudConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n const resolvedConfig = resolveWorldConfig(\n mudConfig,\n existingContracts.map(({ basename }) => basename)\n );\n\n // Get worldAddress either from args or from worldsFile\n const worldAddress = args.worldAddress ?? (await getWorldAddress(mudConfig.worldsFile, rpc));\n\n // Create World contract instance from deployed address\n const provider = new ethers.providers.StaticJsonRpcProvider(rpc);\n const WorldContract = new ethers.Contract(worldAddress, IBaseWorldData.abi, provider);\n\n // TODO account for multiple namespaces (https://github.com/latticexyz/mud/issues/994)\n const namespace = mudConfig.namespace;\n const names = Object.values(resolvedConfig.systems).map(({ name }) => name);\n\n // Fetch system table schema from chain\n const systemTableSchema = await WorldContract.getValueSchema(systemsTableId);\n const labels: { name: string; address: string }[] = [];\n for (const name of names) {\n const systemSelector = tableIdToHex(namespace, name);\n // Get the first field of `Systems` table (the table maps system name to its address and other data)\n const address = await WorldContract.getField(systemsTableId, [systemSelector], 0, systemTableSchema);\n labels.push({ name, address });\n }\n\n const result = await cast([\n \"run\",\n \"--label\",\n `${worldAddress}:World`,\n ...labels.map(({ name, address }) => [\"--label\", `${address}:${name}`]).flat(),\n `${tx}`,\n ]);\n console.log(result);\n\n process.exit(0);\n },\n};\n\nexport default commandModule;\n\nasync function getWorldAddress(worldsFile: string, rpc: string) {\n if (existsSync(worldsFile)) {\n const chainId = await getChainId(rpc);\n const deploys = JSON.parse(readFileSync(worldsFile, \"utf-8\"));\n\n if (!deploys[chainId]) {\n throw new MUDError(`chainId ${chainId} is missing in worldsFile \"${worldsFile}\"`);\n }\n return deploys[chainId].address as string;\n } else {\n throw new MUDError(\"worldAddress is not specified and worldsFile is missing\");\n }\n}\n","import type { CommandModule } from \"yargs\";\nimport { anvil, forge, getRpcUrl, getScriptDirectory, getSrcDirectory } from \"@latticexyz/common/foundry\";\nimport chalk from \"chalk\";\nimport chokidar from \"chokidar\";\nimport { loadConfig, resolveConfigPath } from \"@latticexyz/config/node\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { tablegen } from \"@latticexyz/store/codegen\";\nimport path from \"path\";\nimport { debounce } from \"throttle-debounce\";\nimport { worldgenHandler } from \"./worldgen\";\nimport { WorldConfig } from \"@latticexyz/world\";\nimport { deployHandler, logError, printMUD } from \"../utils\";\nimport { homedir } from \"os\";\nimport { rmSync } from \"fs\";\nimport { execa } from \"execa\";\n\ntype Options = {\n rpc?: string;\n configPath?: string;\n};\n\nconst commandModule: CommandModule<Options, Options> = {\n command: \"dev-contracts\",\n\n describe: \"Start a development server for MUD contracts\",\n\n builder(yargs) {\n return yargs.options({\n rpc: {\n type: \"string\",\n decs: \"RPC endpoint of the development node. If none is provided, an anvil instance is spawned in the background on port 8545.\",\n },\n configPath: {\n type: \"string\",\n decs: \"Path to MUD config\",\n },\n });\n },\n\n async handler(args) {\n // Initial cleanup\n await forge([\"clean\"]);\n\n const rpc = args.rpc ?? (await getRpcUrl());\n const configPath = args.configPath ?? (await resolveConfigPath(args.configPath));\n const srcDirectory = await getSrcDirectory();\n const scriptDirectory = await getScriptDirectory();\n const initialConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n // Initial run of all codegen steps before starting anvil\n // (so clients can wait for everything to be ready before starting)\n await handleConfigChange(initialConfig);\n await handleContractsChange(initialConfig);\n\n // Start an anvil instance in the background if no RPC url is provided\n if (!args.rpc) {\n console.log(chalk.gray(\"Cleaning devnode cache\"));\n const userHomeDir = homedir();\n rmSync(path.join(userHomeDir, \".foundry\", \"anvil\", \"tmp\"), { recursive: true, force: true });\n\n const anvilArgs = [\"--block-time\", \"1\", \"--block-base-fee-per-gas\", \"0\"];\n anvil(anvilArgs);\n }\n\n const changedSinceLastHandled = {\n config: false,\n contracts: false,\n };\n\n const changeInProgress = {\n current: false,\n };\n\n // Watch for changes\n const configWatcher = chokidar.watch([configPath, srcDirectory]);\n configWatcher.on(\"all\", async (_, updatePath) => {\n if (updatePath.includes(configPath)) {\n changedSinceLastHandled.config = true;\n // We trigger contract changes if the config changed here instead of\n // listening to changes in the codegen directory to avoid an infinite loop\n changedSinceLastHandled.contracts = true;\n }\n\n if (updatePath.includes(srcDirectory) || updatePath.includes(scriptDirectory)) {\n // Ignore changes to codegen files to avoid an infinite loop\n if (updatePath.includes(initialConfig.codegenDirectory)) return;\n changedSinceLastHandled.contracts = true;\n }\n\n // Trigger debounced onChange\n handleChange();\n });\n\n const handleChange = debounce(100, async () => {\n // Avoid handling changes multiple times in parallel\n if (changeInProgress.current) return;\n changeInProgress.current = true;\n\n // Reset dirty flags\n const { config, contracts } = changedSinceLastHandled;\n changedSinceLastHandled.config = false;\n changedSinceLastHandled.contracts = false;\n\n try {\n // Load latest config\n const mudConfig = (await loadConfig(configPath)) as StoreConfig & WorldConfig;\n\n // Handle changes\n if (config) await handleConfigChange(mudConfig);\n if (contracts) await handleContractsChange(mudConfig);\n\n await deploy();\n } catch (error) {\n console.error(chalk.red(\"MUD dev-contracts watcher failed to deploy config or contracts changes\\n\"));\n logError(error);\n }\n\n changeInProgress.current = false;\n if (changedSinceLastHandled.config || changedSinceLastHandled.contracts) {\n console.log(\"Detected change while handling the previous change\");\n handleChange();\n }\n\n printMUD();\n console.log(\"MUD watching for changes...\");\n });\n\n /** Codegen to run if config changes */\n async function handleConfigChange(config: StoreConfig & WorldConfig) {\n console.log(chalk.blue(\"mud.config.ts changed - regenerating tables and recs types\"));\n // Run tablegen to generate tables based on the config\n const outPath = path.join(srcDirectory, config.codegenDirectory);\n await tablegen(config, outPath);\n }\n\n /** Codegen to run if contracts changed */\n async function handleContractsChange(config: StoreConfig & WorldConfig) {\n console.log(chalk.blue(\"contracts changed - regenerating interfaces and contract types\"));\n\n // Run worldgen to generate interfaces based on the systems\n await worldgenHandler({ config, clean: true, srcDir: srcDirectory });\n\n // Build the contracts\n await forge([\"build\"]);\n\n // Generate TS-friendly ABI files\n // We rebuild into a separate dir to have a clean set of ABIs without test/script contracts\n await forge([\"build\", \"--extra-output-files\", \"abi\", \"--out\", \"abi\", \"--skip\", \"test\", \"script\", \"MudTest.sol\"]);\n await execa(\"mud\", [\"abi-ts\"]);\n }\n\n /** Run after codegen if either mud config or contracts changed */\n async function deploy() {\n console.log(chalk.blue(\"redeploying World\"));\n await deployHandler({\n configPath,\n skipBuild: true,\n priorityFeeMultiplier: 1,\n disableTxWait: true,\n pollInterval: 1000,\n saveDeployment: true,\n srcDir: srcDirectory,\n rpc,\n });\n }\n },\n};\n\nexport default commandModule;\n"],"mappings":";sDAEA,OAAOA,OAAW,QAClB,OAAS,WAAAC,OAAe,gBCDxB,OAAOC,OAAe,yBACtB,OAAOC,OAAW,qBCHlB,OAAS,UAAAC,OAAc,KACvB,OAAS,WAAAC,OAAe,KACxB,OAAOC,OAAU,OAEjB,OAAS,SAAAC,OAAa,QAMtB,IAAMC,GAAiD,CACrD,QAAS,UAET,SAAU,8CAEV,QAAQC,EAAO,CACb,OAAOA,EAAM,QAAQ,CACnB,UAAW,CAAE,KAAM,SAAU,QAAS,EAAG,KAAM,2CAA4C,CAC7F,CAAC,CACH,EAEA,MAAM,QAAQ,CAAE,UAAAC,CAAU,EAAG,CAC3B,QAAQ,IAAI,0BAA0B,EACtC,IAAMC,EAAcN,GAAQ,EAC5BD,GAAOE,GAAK,KAAKK,EAAa,WAAY,QAAS,KAAK,EAAG,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,EAE3F,IAAMC,EAAY,CAAC,KAAM,OAAOF,CAAS,EAAG,2BAA4B,GAAG,EAC3E,QAAQ,IAAI,kBAAkBE,EAAU,KAAK,GAAG,GAAG,EACnD,IAAMC,EAAQN,GAAM,QAASK,EAAW,CACtC,MAAO,CAAC,UAAW,UAAW,SAAS,CACzC,CAAC,EAED,QAAQ,GAAG,SAAU,IAAM,CACzB,QAAQ,IAAI;AAAA,8CAAiD,EAC7DC,EAAM,KAAK,EACX,QAAQ,KAAK,CACf,CAAC,EACD,MAAMA,CACR,CACF,EAEOC,EAAQN,GCxCf,OAAS,2BAAAO,OAA+B,8BACxC,OAAS,iBAAAC,GAAe,gBAAAC,OAAoB,gBAC5C,OAAOC,MAAW,QAClB,OAAS,qBAAAC,OAAyB,+CAalC,SAASC,GAAoBC,EAAa,CACxC,OAAOJ,GAAaF,GAAyBC,GAAcK,EAAKF,GAAkB,CAAC,CAAC,CACtF,CAEA,IAAMG,GAAiD,CACrD,QAAS,SAET,SAAU,6BAEV,QAAQC,EAAO,CACb,OAAOA,EAAM,QAAQ,CACnB,QAAS,CACP,KAAM,UACN,KAAM,kFACN,QAAS,EACX,EACA,UAAW,CACT,KAAM,SACN,KAAM,wBACN,QAAS,gDACX,EACA,QAAS,CACP,KAAM,SACN,KAAM,2BACN,SAAU,EACZ,CACF,CAAC,CACH,EAEA,MAAM,QAAQ,CAAE,QAAAC,EAAS,UAAAC,EAAW,QAAAC,CAAQ,EAAG,CAC7C,IAAMC,EAASP,GAAoBK,CAAS,EAExCD,IACF,QAAQ,IAAIN,EAAM,OAAO,cAAeQ,CAAO,CAAC,EAChD,MAAMC,EAAO,QAAQ,CAAE,QAAAD,CAAQ,CAAC,EAChC,QAAQ,IAAIR,EAAM,OAAO,SAAS,CAAC,GAGrC,QAAQ,KAAK,CAAC,CAChB,CACF,EAEOU,EAAQN,GCpDf,IAAMO,GAAiD,CACrD,QAAS,eAET,SAAU,0BAEV,QAAQC,EAAO,CACb,OAAOA,EACJ,QAAQ,CACP,MAAO,CAAE,KAAM,SAAU,CAC3B,CAAC,EACA,WAAW,OAAQ,CAAE,KAAM,SAAU,aAAc,EAAK,CAAC,CAC9D,EAEA,QAAQ,CAAE,KAAAC,CAAK,EAAG,CAChB,IAAMC,EAAW,OAAOD,KACxB,QAAQ,IAAIC,CAAQ,EACpB,QAAQ,KAAK,CAAC,CAChB,CACF,EAEOC,EAAQJ,GC3Bf,OAAOK,OAAU,OAEjB,OAAS,cAAAC,OAAkB,0BAE3B,OAAS,YAAAC,OAAgB,4BACzB,OAAS,mBAAAC,OAAuB,6BAMhC,IAAMC,GAAiD,CACrD,QAAS,WAET,SAAU,kEAEV,QAAQC,EAAO,CACb,OAAOA,EAAM,QAAQ,CACnB,WAAY,CAAE,KAAM,SAAU,KAAM,yBAA0B,CAChE,CAAC,CACH,EAEA,MAAM,QAAQ,CAAE,WAAAC,CAAW,EAAG,CAC5B,IAAMC,EAAU,MAAMN,GAAWK,CAAU,EACrCE,EAAS,MAAML,GAAgB,EAErC,MAAMD,GAASK,EAAQP,GAAK,KAAKQ,EAAQD,EAAO,gBAAgB,CAAC,EAEjE,QAAQ,KAAK,CAAC,CAChB,CACF,EAEOE,EAAQL,GChCf,OAAOM,MAAW,QAClB,OAAS,YAAAC,OAAgB,MACzB,OAAS,gBAAAC,GAAc,mBAAAC,OAAuB,uBAC9C,OAAS,yBAAAC,OAA6B,qBACtC,OAAS,YAAAC,OAAgB,4BAElB,SAASC,EAASC,EAAgB,CACvC,GAAIA,aAAiBJ,GACnB,QAAQ,IAAIH,EAAM,UAAUO,EAAM,OAAO,CAAC,UACjCA,aAAiBN,GAAU,CAGpC,IAAMO,EAAkBN,GAAaK,EAAO,CAC1C,gBAAiB;AAAA,IACjB,eAAgB;AAAA,GAClB,CAAC,EACD,QAAQ,IAAIP,EAAM,UAAUQ,EAAgB,OAAO,CAAC,OAC3CD,aAAiBH,IAC1B,QAAQ,IAAIJ,EAAM,IAAIO,EAAM,OAAO,CAAC,EACpC,QAAQ,IAAI,EAAE,EAGd,QAAQ,IAAIP,EAAM,KAAK,qFAAqF,CAAC,GACpGO,aAAiBF,GAC1B,QAAQ,IAAIL,EAAM,IAAIO,CAAK,CAAC,EAE5B,QAAQ,IAAIA,CAAK,CAErB,CC5BA,OAAOE,OAAW,QAEX,SAASC,GAAW,CACzB,QAAQ,IACND,GAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAOhB,CACC,CACF,CCTO,IAAME,EAAiB,CAC5B,WAAY,CAAE,KAAM,SAAU,KAAM,yBAA0B,EAC9D,MAAO,CAAE,KAAM,UAAW,KAAM,wEAAyE,EACzG,YAAa,CAAE,KAAM,UAAW,KAAM,2BAA4B,EAClE,QAAS,CAAE,KAAM,SAAU,KAAM,4BAA6B,EAC9D,MAAO,CAAE,KAAM,UAAW,KAAM,4CAA6C,EAC7E,sBAAuB,CACrB,KAAM,SACN,KAAM,6DACN,QAAS,CACX,EACA,eAAgB,CAAE,KAAM,UAAW,KAAM,qCAAsC,QAAS,EAAK,EAC7F,IAAK,CAAE,KAAM,SAAU,KAAM,yEAA0E,EACvG,aAAc,CAAE,KAAM,SAAU,KAAM,kDAAmD,EACzF,OAAQ,CAAE,KAAM,SAAU,KAAM,sDAAuD,EACvF,cAAe,CAAE,KAAM,UAAW,KAAM,oDAAqD,QAAS,EAAM,EAC5G,aAAc,CACZ,KAAM,SACN,KAAM,oFACN,QAAS,GACX,EACA,UAAW,CAAE,KAAM,UAAW,KAAM,gDAAiD,CACvF,EAEMC,GAA6D,CACjE,QAAS,SAET,SAAU,uBAEV,QAAQC,EAAO,CACb,OAAOA,EAAM,QAAQF,CAAc,CACrC,EAEA,MAAM,QAAQG,EAAM,CAClB,GAAI,CACF,MAAMC,EAAcD,CAAI,CAC1B,OAASE,EAAP,CACAC,EAASD,CAAK,EACd,QAAQ,KAAK,CAAC,CAChB,CACA,QAAQ,KAAK,CAAC,CAChB,CACF,EAEOE,EAAQN,GC/Cf,OAAS,cAAAO,OAAkB,0BAG3B,OAAS,YAAAC,OAAgB,yBACzB,OAAS,mBAAAC,OAAuB,6BAChC,OAAOC,MAAU,OACjB,OAAS,UAAAC,OAAc,KAUvB,IAAMC,GAAiD,CACrD,QAAS,WAET,SAAU,gGAEV,QAAQC,EAAO,CACb,OAAOA,EAAM,QAAQ,CACnB,WAAY,CAAE,KAAM,SAAU,KAAM,yBAA0B,EAC9D,MAAO,CACL,KAAM,UACN,KAAM,mFACN,QAAS,EACX,CACF,CAAC,CACH,EAEA,MAAM,QAAQC,EAAM,CAClB,MAAMC,EAAgBD,CAAI,EAC1B,QAAQ,KAAK,CAAC,CAChB,CACF,EAEA,eAAsBC,EAAgBD,EAAe,CACnD,IAAME,EAASF,EAAK,QAAW,MAAMG,GAAgB,EAE/CC,EAAoBC,EAAqBH,CAAM,EAG/CI,EAAYN,EAAK,QAAY,MAAMO,GAAWP,EAAK,UAAU,EAE7DQ,EAAsBC,EAAK,KAAKP,EAAQI,EAAU,gBAAgB,EAGpEN,EAAK,OAAOU,GAAOD,EAAK,KAAKD,EAAqBF,EAAU,iBAAiB,EAAG,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,EAGpH,MAAMK,GAASL,EAAWF,EAAmBI,CAAmB,CAClE,CAEA,IAAOI,EAAQd,GCxDf,OAAOe,MAAW,QAClB,OAAS,cAAAC,GAAY,gBAAAC,GAAc,UAAAC,GAAQ,iBAAAC,MAAqB,KAChE,OAAOC,MAAU,OAEjB,OAAS,YAAAC,MAAgB,4BCJzB,IAAAC,EAAA,CACE,KAAQ,kBACR,QAAW,eACX,YAAe,iCACf,WAAc,CACZ,KAAQ,MACR,IAAO,wCACP,UAAa,cACf,EACA,QAAW,MACX,KAAQ,SACR,QAAW,CACT,IAAK,iBACP,EACA,MAAS,eACT,IAAO,CACL,IAAO,eACT,EACA,QAAW,CACT,MAAS,kDACT,WAAY,iCACZ,oBAAqB,wCACrB,MAAS,oBACT,WAAY,cACZ,IAAO,eACP,KAAQ,qBACR,QAAW,yCACX,KAAQ,6BACR,UAAW,eACb,EACA,aAAgB,CACd,qBAAsB,SACtB,2BAA4B,SAC5B,2BAA4B,UAC5B,+CAAgD,UAChD,qBAAsB,cACtB,qBAAsB,cACtB,qBAAsB,cACtB,yBAA0B,cAC1B,8BAA+B,cAC/B,0BAA2B,cAC3B,uBAAwB,cACxB,oBAAqB,cACrB,oBAAqB,cACrB,oBAAqB,cACrB,MAAS,SACT,SAAY,SACZ,OAAU,UACV,IAAO,SACP,OAAU,SACV,MAAS,SACT,KAAQ,SACR,gBAAiB,SACjB,QAAW,SACX,KAAQ,UACR,oBAAqB,SACrB,WAAc,QACd,MAAS,UACT,IAAO,UACP,uBAAwB,QAC1B,EACA,gBAAmB,CACjB,aAAc,SACd,cAAe,SACf,cAAe,YACf,iBAAkB,SAClB,2BAA4B,SAC5B,eAAgB,WAChB,UAAW,kFACX,YAAa,uFACb,KAAQ,SACR,IAAO,UACP,OAAU,QACZ,EACA,QAAW,0CACb,EDpEA,OAAOC,OAAU,OAYjB,IAAMC,EAAc,aACdC,EAAa,cAEbC,GAAiD,CACrD,QAAS,cAET,SAAU,mGAEV,QAAQC,EAAO,CACb,OAAOA,EAAM,QAAQ,CACnB,OAAQ,CAAE,KAAM,UAAW,YAAa,wCAAwCH,IAAe,EAC/F,MAAO,CACL,KAAM,UACN,YAAa,sBAAsBA,8CACrC,EACA,QAAS,CAAE,KAAM,UAAW,YAAa,2CAA2CA,IAAe,EACnG,WAAY,CAAE,MAAO,IAAK,KAAM,SAAU,YAAa,8BAA+B,EACtF,IAAK,CACH,MAAO,IACP,KAAM,SACN,YAAa,2DACf,EACA,OAAQ,CACN,MAAO,IACP,KAAM,SACN,YAAa,kEACf,EACA,KAAM,CAAE,MAAO,IAAK,KAAM,SAAU,YAAa,uDAAwD,CAC3G,CAAC,CACH,EAEA,MAAM,QAAQI,EAAS,CACrB,GAAI,CACF,IAAMC,EAA2B,CAAC,aAAc,OAAQ,MAAO,SAAU,SAAS,EAC5EC,EAA8BD,EAAyB,OAC3D,CAACE,EAAKC,IAASJ,EAAQI,CAAG,EAAID,EAAM,EAAIA,EACxC,CACF,EAEA,GAAID,IAAgC,EAClC,MAAM,IAAIG,EAAS,0CAA0CJ,EAAyB,KAAK,IAAI,GAAG,EAGpG,GAAIC,EAA8B,EAChC,MAAM,IAAIG,EAAS,yCAAyCJ,EAAyB,KAAK,IAAI,GAAG,EAInGD,EAAQ,WAAa,MAAMM,GAAeN,CAAO,EAGjD,IAAMO,EAAeZ,GAAK,KAAK,iBAAiB,EAAE,OAAQa,GAAM,CAACA,EAAE,SAAS,cAAc,CAAC,EAC3F,QAAWC,KAAeF,EACxBG,GAAkBD,EAAaT,CAAO,CAE1C,OAASW,EAAP,CACAC,EAASD,CAAC,CACZ,QAAE,CACA,QAAQ,KAAK,CAAC,CAChB,CACF,CACF,EAEA,eAAeL,GAAeN,EAAkB,CAE1CA,EAAQ,aAAe,WAAUA,EAAQ,IAAM,QAEnD,IAAIa,EACJ,GAAI,CACF,QAAQ,IAAIC,EAAM,KAAK,6BAA6B,CAAC,EACrDD,EAAY,MAAO,MAAM,MAAM,8BAA8BE,EAAiB,MAAM,GAAG,KAAK,CAC9F,MAAE,CACA,MAAM,IAAIV,EAAS,wCAAwC,CAC7D,CAEA,GAAIL,EAAQ,IAAK,CACf,IAAMgB,EAAUH,EAAU,WAAW,EAAEb,EAAQ,GAAG,EAClD,GAAI,CAACgB,EACH,MAAM,IAAIX,EAAS,wCAAwCL,EAAQ,MAAM,EAE3E,eAAQ,IAAIc,EAAM,MAAM,2BAA2Bd,EAAQ,QAAQgB,GAAS,CAAC,EACtEA,EAGT,GAAIhB,EAAQ,OAAQ,CAElB,IAAMiB,EAASjB,EAAQ,OAAO,UAAU,EAAG,CAAC,EACtCgB,EAAU,OAAO,KAAKH,EAAU,QAAW,EAAE,KAAMK,GAAOA,EAAa,SAASD,CAAM,CAAC,EAC7F,GAAI,CAACD,EACH,MAAM,IAAIX,EAAS,+CAA+CL,EAAQ,SAAS,EAErF,eAAQ,IAAIc,EAAM,MAAM,uBAAuBd,EAAQ,WAAWgB,GAAS,CAAC,EACrEA,EAIT,OAAOhB,EAAQ,UACjB,CAEA,SAASU,GAAkBS,EAAkBnB,EAA6C,CACxF,GAAM,CAAE,QAAAoB,EAAS,MAAAC,EAAO,KAAAC,CAAK,EAAItB,EAC7B,CAAE,OAAAuB,EAAQ,WAAAC,CAAW,EAAIxB,EAEvByB,EAAiBC,EAAK,KAAKA,EAAK,QAAQP,CAAQ,EAAGvB,CAAW,EAC9D+B,EAAmBC,GAAWH,CAAc,EAMlD,GAHIH,GAAQ,CAACK,IAAkBJ,EAAS,IAGpCA,GAAU,CAACF,GAASM,EACtB,MAAM,IAAItB,EACR,mCAAmCoB;AAAA,wDACrC,EAGF,IAAMhB,EAAcoB,EAAgBV,CAAQ,EAGtCW,EAAaV,EAAUS,EAAgBJ,CAAc,EAAI,OAGzDM,EAA0C,CAAC,EACjD,QAAWC,KAAOvB,EAAY,aACxBuB,EAAI,WAAWnC,CAAU,IAC3BkC,EAAgBC,CAAG,EAAIvB,EAAY,aAAauB,CAAG,GAKvD,IAAMC,EAA6C,CAAC,EACpD,QAAWD,KAAOvB,EAAY,gBACxBuB,EAAI,WAAWnC,CAAU,IAC3BoC,EAAmBD,CAAG,EAAIvB,EAAY,gBAAgBuB,CAAG,GAKzDT,IACFW,EACET,EACA,KAAK,UAAU,CAAE,aAAcM,EAAiB,gBAAiBE,CAAmB,EAAG,KAAM,CAAC,CAChG,EACA,QAAQ,IAAInB,EAAM,MAAM,mCAAmCK,QAAeM,GAAgB,CAAC,GAI7F,QAAWO,KAAOvB,EAAY,aACxBuB,EAAI,WAAWnC,CAAU,IAC3BY,EAAY,aAAauB,CAAG,EAAIG,EAAkBH,EAAK,cAAc,GAKzE,QAAWA,KAAOvB,EAAY,gBACxBuB,EAAI,WAAWnC,CAAU,IAC3BY,EAAY,gBAAgBuB,CAAG,EAAIG,EAAkBH,EAAK,iBAAiB,GAK/E,OAAAE,EAAcf,EAAU,KAAK,UAAUV,EAAa,KAAM,CAAC,EAAI;AAAA,CAAI,EAEnE,QAAQ,IAAI,YAAYU,GAAU,EAClCiB,EAAcL,EAAiBtB,EAAY,YAAY,EACvD2B,EAAcH,EAAoBxB,EAAY,eAAe,EAIzDW,GAAW,CAACG,IACdc,GAAOZ,CAAc,EACrB,QAAQ,IAAIX,EAAM,MAAM,cAAcW,GAAgB,CAAC,GAGlDhB,EAEP,SAAS0B,EAAkBH,EAAaM,EAA0C,CAChF,OAAIlB,GAAWU,EAAmBA,EAAWQ,CAAI,EAAEN,CAAG,GAClDV,IAAME,EAAae,GAAgBpB,EAAUG,EAAMU,CAAG,GACrDR,GAAmBf,EAAY6B,CAAI,EAAEN,CAAG,EAE/C,CACF,CAEA,SAASH,EAAgBH,EAIvB,CACA,GAAI,CACF,IAAMc,EAAaC,GAAaf,EAAM,MAAM,EAC5C,OAAO,KAAK,MAAMc,CAAU,CAC9B,MAAE,CACA,MAAM,IAAInC,EAAS,0BAA4BqB,CAAI,CACrD,CACF,CAEA,SAASU,EAAcM,EAA8BC,EAA8B,CACjF,QAAWX,KAAOU,EACZA,EAAKV,CAAG,IAAMW,EAAKX,CAAG,GACxB,QAAQ,IAAI,GAAGA,MAAQlB,EAAM,IAAI4B,EAAKV,CAAG,CAAC,QAAQlB,EAAM,MAAM6B,EAAKX,CAAG,CAAC,GAAG,CAGhF,CAKA,SAASO,GAAgBK,EAAyBC,EAAqBC,EAAa,CAClF,IAAMC,EAAUD,EAAI,QAAQjD,EAAY,EAAE,EACpCmD,EAAwBtB,EAAK,SAASA,EAAK,QAAQkB,CAAe,EAAG,QAAQ,IAAI,CAAC,EAExF,MAAO,QADUlB,EAAK,KAAKsB,EAAuBH,EAAa,WAAYE,CAAO,CAEpF,CAEA,IAAOE,EAAQnD,GEzOf,OAAS,SAAAoD,GAAO,SAAAC,GAAO,aAAAC,OAAiB,6BACxC,OAAOC,OAAW,QAClB,OAAS,UAAAC,EAAQ,iBAAAC,OAAqB,KAMtC,IAAMC,EAAqB,WAErBC,GAAiD,CACrD,QAAS,OAET,SAAU,6BAEV,QAAQC,EAAO,CACb,OAAOA,EAAM,QAAQ,CACnB,GAAGC,EACH,KAAM,CAAE,KAAM,SAAU,YAAa,gDAAiD,QAAS,IAAK,EACpG,aAAc,CACZ,KAAM,SACN,YACE,8IACJ,EACA,aAAc,CAAE,KAAM,SAAU,YAAa,+BAAgC,CAC/E,CAAC,CACH,EAEA,MAAM,QAAQC,EAAM,CAElB,GAAI,CAACA,EAAK,aAAc,CACtB,IAAMC,EAAY,CAAC,2BAA4B,IAAK,SAAU,OAAOD,EAAK,IAAI,CAAC,EAC/EE,GAAMD,CAAS,EAGjB,IAAME,EAAUH,EAAK,aAAe,MAAMI,GAAUJ,EAAK,OAAO,EAAI,oBAAoBA,EAAK,OAEvFK,EACJL,EAAK,eAEH,MAAMM,EAAc,CAClB,GAAGN,EACH,eAAgB,GAChB,IAAKG,CACP,CAAC,GACD,aAEJ,QAAQ,IAAII,GAAM,KAAK,gBAAiBF,CAAY,CAAC,EAGrDG,GAAcZ,EAAoBS,CAAY,EAE9C,IAAMI,EAAcT,EAAK,cAAc,WAAW,KAAM,EAAE,EAAE,MAAM,GAAG,GAAK,CAAC,EAC3E,GAAI,CACF,IAAMU,EAAa,MAAMC,GAAM,CAAC,OAAQ,aAAcR,EAAS,GAAGM,CAAW,EAAG,CAC9E,QAAST,EAAK,OAChB,CAAC,EACD,QAAQ,IAAIU,CAAU,CACxB,OAASE,EAAP,CACA,QAAQ,MAAMA,CAAC,EACfC,EAAOjB,CAAkB,EACzB,QAAQ,KAAK,CAAC,CAChB,CAEAiB,EAAOjB,CAAkB,EACzB,QAAQ,KAAK,CAAC,CAChB,CACF,EAEOkB,EAAQjB,GCtEf,OAAS,cAAAkB,GAAY,gBAAAC,OAAoB,KAEzC,OAAS,UAAAC,MAAc,SAEvB,OAAS,cAAAC,OAAkB,0BAC3B,OAAS,YAAAC,MAAgB,4BACzB,OAAS,QAAAC,GAAM,aAAAC,GAAW,mBAAAC,OAAuB,6BAEjD,OAAS,sBAAAC,OAAuC,oBAChD,OAAOC,OAAoB,sDAAuD,MAAO,CAAE,KAAM,MAAO,EACxG,OAAOC,MAAiB,kCACxB,OAAS,gBAAAC,MAAoB,qBAI7B,IAAMC,EAAiBC,EAAaC,EAAY,UAAWA,EAAY,OAAO,QAAQ,IAAI,EAWpFC,GAAiD,CACrD,QAAS,QAET,SAAU,qCAEV,QAAQC,EAAO,CACb,OAAOA,EAAM,QAAQ,CACnB,GAAI,CAAE,KAAM,SAAU,SAAU,GAAM,YAAa,4BAA6B,EAChF,aAAc,CACZ,KAAM,SACN,YAAa,wFACf,EACA,WAAY,CAAE,KAAM,SAAU,YAAa,yBAA0B,EACrE,QAAS,CAAE,KAAM,SAAU,YAAa,4BAA6B,EACrE,OAAQ,CAAE,KAAM,SAAU,YAAa,sDAAuD,EAC9F,IAAK,CAAE,KAAM,SAAU,YAAa,iEAAkE,CACxG,CAAC,CACH,EAEA,MAAM,QAAQC,EAAM,CAClBA,EAAK,UAAY,QAAQ,IAAI,gBAC7B,GAAM,CAAE,QAAAC,CAAQ,EAAID,EACpBA,EAAK,SAAW,MAAME,GAAgBD,CAAO,EAC7CD,EAAK,MAAQ,MAAMG,GAAUF,CAAO,EACpC,GAAM,CAAE,GAAAG,EAAI,WAAAC,EAAY,OAAAC,EAAQ,IAAAC,CAAI,EAAIP,EAElCQ,EAAoBC,EAAqBH,CAAM,EAG/CI,EAAa,MAAMC,GAAWN,CAAU,EAExCO,EAAiBC,GACrBH,EACAF,EAAkB,IAAI,CAAC,CAAE,SAAAM,CAAS,IAAMA,CAAQ,CAClD,EAGMC,EAAef,EAAK,cAAiB,MAAMgB,GAAgBN,EAAU,WAAYH,CAAG,EAGpFU,EAAW,IAAIC,EAAO,UAAU,sBAAsBX,CAAG,EACzDY,EAAgB,IAAID,EAAO,SAASH,EAAcK,GAAe,IAAKH,CAAQ,EAG9EI,EAAYX,EAAU,UACtBY,EAAQ,OAAO,OAAOV,EAAe,OAAO,EAAE,IAAI,CAAC,CAAE,KAAAW,CAAK,IAAMA,CAAI,EAGpEC,EAAoB,MAAML,EAAc,eAAexB,CAAc,EACrE8B,EAA8C,CAAC,EACrD,QAAWF,KAAQD,EAAO,CACxB,IAAMI,EAAiB9B,EAAayB,EAAWE,CAAI,EAE7CI,GAAU,MAAMR,EAAc,SAASxB,EAAgB,CAAC+B,CAAc,EAAG,EAAGF,CAAiB,EACnGC,EAAO,KAAK,CAAE,KAAAF,EAAM,QAAAI,EAAQ,CAAC,EAG/B,IAAMC,GAAS,MAAMC,GAAK,CACxB,MACA,UACA,GAAGd,UACH,GAAGU,EAAO,IAAI,CAAC,CAAE,KAAAF,EAAM,QAAAI,CAAQ,IAAM,CAAC,UAAW,GAAGA,KAAWJ,GAAM,CAAC,EAAE,KAAK,EAC7E,GAAGnB,GACL,CAAC,EACD,QAAQ,IAAIwB,EAAM,EAElB,QAAQ,KAAK,CAAC,CAChB,CACF,EAEOE,GAAQhC,GAEf,eAAekB,GAAgBe,EAAoBxB,EAAa,CAC9D,GAAIyB,GAAWD,CAAU,EAAG,CAC1B,IAAME,EAAU,MAAMC,EAAW3B,CAAG,EAC9B4B,EAAU,KAAK,MAAMC,GAAaL,EAAY,OAAO,CAAC,EAE5D,GAAI,CAACI,EAAQF,CAAO,EAClB,MAAM,IAAII,EAAS,WAAWJ,+BAAqCF,IAAa,EAElF,OAAOI,EAAQF,CAAO,EAAE,YAExB,OAAM,IAAII,EAAS,yDAAyD,CAEhF,CC7GA,OAAS,SAAAC,GAAO,SAAAC,EAAO,aAAAC,GAAW,sBAAAC,GAAoB,mBAAAC,OAAuB,6BAC7E,OAAOC,MAAW,QAClB,OAAOC,OAAc,WACrB,OAAS,cAAAC,GAAY,qBAAAC,OAAyB,0BAE9C,OAAS,YAAAC,OAAgB,4BACzB,OAAOC,OAAU,OACjB,OAAS,YAAAC,OAAgB,oBAIzB,OAAS,WAAAC,OAAe,KACxB,OAAS,UAAAC,OAAc,KACvB,OAAS,SAAAC,OAAa,QAOtB,IAAMC,GAAiD,CACrD,QAAS,gBAET,SAAU,+CAEV,QAAQC,EAAO,CACb,OAAOA,EAAM,QAAQ,CACnB,IAAK,CACH,KAAM,SACN,KAAM,yHACR,EACA,WAAY,CACV,KAAM,SACN,KAAM,oBACR,CACF,CAAC,CACH,EAEA,MAAM,QAAQC,EAAM,CAElB,MAAMC,EAAM,CAAC,OAAO,CAAC,EAErB,IAAMC,EAAMF,EAAK,KAAQ,MAAMG,GAAU,EACnCC,EAAaJ,EAAK,YAAe,MAAMK,GAAkBL,EAAK,UAAU,EACxEM,EAAe,MAAMC,GAAgB,EACrCC,EAAkB,MAAMC,GAAmB,EAC3CC,EAAiB,MAAMC,GAAWP,CAAU,EAQlD,GAJA,MAAMQ,EAAmBF,CAAa,EACtC,MAAMG,EAAsBH,CAAa,EAGrC,CAACV,EAAK,IAAK,CACb,QAAQ,IAAIc,EAAM,KAAK,wBAAwB,CAAC,EAChD,IAAMC,EAAcpB,GAAQ,EAC5BC,GAAOoB,GAAK,KAAKD,EAAa,WAAY,QAAS,KAAK,EAAG,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,EAG3FE,GADkB,CAAC,eAAgB,IAAK,2BAA4B,GAAG,CACxD,EAGjB,IAAMC,EAA0B,CAC9B,OAAQ,GACR,UAAW,EACb,EAEMC,EAAmB,CACvB,QAAS,EACX,EAGsBC,GAAS,MAAM,CAAChB,EAAYE,CAAY,CAAC,EACjD,GAAG,MAAO,MAAOe,EAAGC,IAAe,CAQ/C,GAPIA,EAAW,SAASlB,CAAU,IAChCc,EAAwB,OAAS,GAGjCA,EAAwB,UAAY,IAGlCI,EAAW,SAAShB,CAAY,GAAKgB,EAAW,SAASd,CAAe,EAAG,CAE7E,GAAIc,EAAW,SAASZ,EAAc,gBAAgB,EAAG,OACzDQ,EAAwB,UAAY,GAItCK,EAAa,CACf,CAAC,EAED,IAAMA,EAAeC,GAAS,IAAK,SAAY,CAE7C,GAAIL,EAAiB,QAAS,OAC9BA,EAAiB,QAAU,GAG3B,GAAM,CAAE,OAAAM,EAAQ,UAAAC,CAAU,EAAIR,EAC9BA,EAAwB,OAAS,GACjCA,EAAwB,UAAY,GAEpC,GAAI,CAEF,IAAMS,EAAa,MAAMhB,GAAWP,CAAU,EAG1CqB,GAAQ,MAAMb,EAAmBe,CAAS,EAC1CD,GAAW,MAAMb,EAAsBc,CAAS,EAEpD,MAAMC,EAAO,CACf,OAASC,EAAP,CACA,QAAQ,MAAMf,EAAM,IAAI;AAAA,CAA0E,CAAC,EACnGgB,EAASD,CAAK,CAChB,CAEAV,EAAiB,QAAU,IACvBD,EAAwB,QAAUA,EAAwB,aAC5D,QAAQ,IAAI,oDAAoD,EAChEK,EAAa,GAGfQ,EAAS,EACT,QAAQ,IAAI,6BAA6B,CAC3C,CAAC,EAGD,eAAenB,EAAmBa,EAAmC,CACnE,QAAQ,IAAIX,EAAM,KAAK,4DAA4D,CAAC,EAEpF,IAAMkB,EAAUhB,GAAK,KAAKV,EAAcmB,EAAO,gBAAgB,EAC/D,MAAMQ,GAASR,EAAQO,CAAO,CAChC,CAGA,eAAenB,EAAsBY,EAAmC,CACtE,QAAQ,IAAIX,EAAM,KAAK,gEAAgE,CAAC,EAGxF,MAAMoB,EAAgB,CAAE,OAAAT,EAAQ,MAAO,GAAM,OAAQnB,CAAa,CAAC,EAGnE,MAAML,EAAM,CAAC,OAAO,CAAC,EAIrB,MAAMA,EAAM,CAAC,QAAS,uBAAwB,MAAO,QAAS,MAAO,SAAU,OAAQ,SAAU,aAAa,CAAC,EAC/G,MAAMJ,GAAM,MAAO,CAAC,QAAQ,CAAC,CAC/B,CAGA,eAAe+B,GAAS,CACtB,QAAQ,IAAId,EAAM,KAAK,mBAAmB,CAAC,EAC3C,MAAMqB,EAAc,CAClB,WAAA/B,EACA,UAAW,GACX,sBAAuB,EACvB,cAAe,GACf,aAAc,IACd,eAAgB,GAChB,OAAQE,EACR,IAAAJ,CACF,CAAC,CACH,CACF,CACF,EAEOkC,GAAQtC,GbvJR,IAAMuC,GAAsC,CACjDC,EACAC,EACAC,EACAC,GACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GACAC,GACAC,EACF,EDtBA,UAAYC,OAAY,SACxB,OAAOC,OAAW,QACX,UAAO,EAEdC,GAAMC,GAAQ,QAAQ,IAAI,CAAC,EAExB,WAAW,KAAK,EAGhB,QAAQC,EAAe,EAEvB,OAAO,EAEP,KAAK,CAACC,EAAKC,IAAQ,CAClB,QAAQ,MAAML,GAAM,IAAII,CAAG,CAAC,EACxBA,EAAI,SAAS,2BAA2B,GAC1C,QAAQ,IACNJ,GAAM,OAAO,iBAAiB,QAAQ,KAAK,CAAC,2DAA2D,CACzG,EAEF,QAAQ,IAAI,EAAE,EAEVK,GAAO,OACTC,EAASD,CAAG,EACZ,QAAQ,IAAI,EAAE,GAGhB,QAAQ,KAAK,CAAC,CAChB,CAAC,EAEA,MAAM,CAAE,EAAG,MAAO,CAAC,EAAE","names":["yargs","hideBin","gasReport","abiTs","rmSync","homedir","path","execa","commandModule","yargs","blocktime","userHomeDir","anvilArgs","child","devnode_default","FaucetServiceDefinition","createChannel","createClient","chalk","NodeHttpTransport","createFaucetService","url","commandModule","yargs","dripDev","faucetUrl","address","faucet","faucet_default","commandModule","yargs","name","greeting","hello_default","path","loadConfig","tablegen","getSrcDirectory","commandModule","yargs","configPath","config","srcDir","tablegen_default","chalk","ZodError","fromZodError","ValidationError","NotInsideProjectError","MUDError","logError","error","validationError","chalk","printMUD","yDeployOptions","commandModule","yargs","args","deployHandler","error","logError","deploy_default","loadConfig","worldgen","getSrcDirectory","path","rmSync","commandModule","yargs","args","worldgenHandler","srcDir","getSrcDirectory","existingContracts","getExistingContracts","mudConfig","loadConfig","outputBaseDirectory","path","rmSync","worldgen","worldgen_default","chalk","existsSync","readFileSync","rmSync","writeFileSync","path","MUDError","package_default","glob","BACKUP_FILE","MUD_PREFIX","commandModule","yargs","options","mutuallyExclusiveOptions","numMutuallyExclusiveOptions","acc","opt","MUDError","resolveVersion","packageJsons","p","packageJson","updatePackageJson","e","logError","npmResult","chalk","package_default","version","commit","v","filePath","restore","force","link","backup","mudVersion","backupFilePath","path","backupFileExists","existsSync","readPackageJson","backupJson","mudDependencies","key","mudDevDependencies","writeFileSync","resolveMudVersion","logComparison","rmSync","type","resolveLinkPath","jsonString","readFileSync","prev","curr","packageJsonPath","mudLinkPath","pkg","pkgName","packageJsonToRootPath","set_version_default","anvil","forge","getRpcUrl","chalk","rmSync","writeFileSync","WORLD_ADDRESS_FILE","commandModule","yargs","yDeployOptions","args","anvilArgs","anvil","forkRpc","getRpcUrl","worldAddress","deployHandler","chalk","writeFileSync","userOptions","testResult","forge","e","rmSync","test_default","existsSync","readFileSync","ethers","loadConfig","MUDError","cast","getRpcUrl","getSrcDirectory","resolveWorldConfig","IBaseWorldData","worldConfig","tableIdToHex","systemsTableId","tableIdToHex","worldConfig","commandModule","yargs","args","profile","getSrcDirectory","getRpcUrl","tx","configPath","srcDir","rpc","existingContracts","getExistingContracts","mudConfig","loadConfig","resolvedConfig","resolveWorldConfig","basename","worldAddress","getWorldAddress","provider","ethers","WorldContract","IBaseWorldData","namespace","names","name","systemTableSchema","labels","systemSelector","address","result","cast","trace_default","worldsFile","existsSync","chainId","getChainId","deploys","readFileSync","MUDError","anvil","forge","getRpcUrl","getScriptDirectory","getSrcDirectory","chalk","chokidar","loadConfig","resolveConfigPath","tablegen","path","debounce","homedir","rmSync","execa","commandModule","yargs","args","forge","rpc","getRpcUrl","configPath","resolveConfigPath","srcDirectory","getSrcDirectory","scriptDirectory","getScriptDirectory","initialConfig","loadConfig","handleConfigChange","handleContractsChange","chalk","userHomeDir","path","anvil","changedSinceLastHandled","changeInProgress","chokidar","_","updatePath","handleChange","debounce","config","contracts","mudConfig","deploy","error","logError","printMUD","outPath","tablegen","worldgenHandler","deployHandler","dev_contracts_default","commands","deploy_default","devnode_default","faucet_default","gasReport","hello_default","tablegen_default","worldgen_default","set_version_default","test_default","trace_default","dev_contracts_default","abiTs","dotenv","chalk","yargs","hideBin","commands","msg","err","logError"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@latticexyz/cli",
3
- "version": "2.0.0-next.5",
3
+ "version": "2.0.0-next.7",
4
4
  "description": "Command line interface for mud",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,7 +21,6 @@
21
21
  "@ethersproject/providers": "^5.7.2",
22
22
  "@improbable-eng/grpc-web": "^0.15.0",
23
23
  "@improbable-eng/grpc-web-node-http-transport": "^0.15.0",
24
- "@typechain/ethers-v5": "^10.2.0",
25
24
  "chalk": "^5.0.1",
26
25
  "chokidar": "^3.5.3",
27
26
  "dotenv": "^16.0.3",
@@ -33,20 +32,20 @@
33
32
  "openurl": "^1.1.1",
34
33
  "path": "^0.12.7",
35
34
  "throttle-debounce": "^5.0.0",
36
- "typechain": "^8.1.1",
37
35
  "typescript": "5.1.6",
38
36
  "yargs": "^17.7.1",
39
37
  "zod": "^3.21.4",
40
38
  "zod-validation-error": "^1.3.0",
41
- "@latticexyz/common": "2.0.0-next.5",
42
- "@latticexyz/config": "2.0.0-next.5",
43
- "@latticexyz/gas-report": "2.0.0-next.5",
44
- "@latticexyz/protocol-parser": "2.0.0-next.5",
45
- "@latticexyz/schema-type": "2.0.0-next.5",
46
- "@latticexyz/services": "2.0.0-next.5",
47
- "@latticexyz/store": "2.0.0-next.5",
48
- "@latticexyz/utils": "2.0.0-next.5",
49
- "@latticexyz/world": "2.0.0-next.5"
39
+ "@latticexyz/abi-ts": "2.0.0-next.7",
40
+ "@latticexyz/common": "2.0.0-next.7",
41
+ "@latticexyz/config": "2.0.0-next.7",
42
+ "@latticexyz/gas-report": "2.0.0-next.7",
43
+ "@latticexyz/protocol-parser": "2.0.0-next.7",
44
+ "@latticexyz/schema-type": "2.0.0-next.7",
45
+ "@latticexyz/services": "2.0.0-next.7",
46
+ "@latticexyz/store": "2.0.0-next.7",
47
+ "@latticexyz/utils": "2.0.0-next.7",
48
+ "@latticexyz/world": "2.0.0-next.7"
50
49
  },
51
50
  "devDependencies": {
52
51
  "@types/ejs": "^3.1.1",
@@ -9,9 +9,10 @@ import path from "path";
9
9
  import { debounce } from "throttle-debounce";
10
10
  import { worldgenHandler } from "./worldgen";
11
11
  import { WorldConfig } from "@latticexyz/world";
12
- import { deployHandler, logError, printMUD, worldtypes } from "../utils";
12
+ import { deployHandler, logError, printMUD } from "../utils";
13
13
  import { homedir } from "os";
14
14
  import { rmSync } from "fs";
15
+ import { execa } from "execa";
15
16
 
16
17
  type Options = {
17
18
  rpc?: string;
@@ -142,8 +143,10 @@ const commandModule: CommandModule<Options, Options> = {
142
143
  // Build the contracts
143
144
  await forge(["build"]);
144
145
 
145
- // Run typechain to rebuild typescript types for the contracts
146
- await worldtypes();
146
+ // Generate TS-friendly ABI files
147
+ // We rebuild into a separate dir to have a clean set of ABIs without test/script contracts
148
+ await forge(["build", "--extra-output-files", "abi", "--out", "abi", "--skip", "test", "script", "MudTest.sol"]);
149
+ await execa("mud", ["abi-ts"]);
147
150
  }
148
151
 
149
152
  /** Run after codegen if either mud config or contracts changed */
@@ -1,6 +1,7 @@
1
1
  import { CommandModule } from "yargs";
2
2
 
3
3
  import gasReport from "@latticexyz/gas-report";
4
+ import abiTs from "@latticexyz/abi-ts";
4
5
 
5
6
  import devnode from "./devnode";
6
7
  import faucet from "./faucet";
@@ -26,4 +27,5 @@ export const commands: CommandModule<any, any>[] = [
26
27
  test,
27
28
  trace,
28
29
  devContracts,
30
+ abiTs,
29
31
  ];
@@ -7,7 +7,6 @@ import { MUDError } from "@latticexyz/common/errors";
7
7
  import { cast, getRpcUrl, getSrcDirectory } from "@latticexyz/common/foundry";
8
8
  import { StoreConfig } from "@latticexyz/store";
9
9
  import { resolveWorldConfig, WorldConfig } from "@latticexyz/world";
10
- import { IBaseWorld } from "@latticexyz/world/types/ethers-contracts/IBaseWorld";
11
10
  import IBaseWorldData from "@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json" assert { type: "json" };
12
11
  import worldConfig from "@latticexyz/world/mud.config.js";
13
12
  import { tableIdToHex } from "@latticexyz/common";
@@ -66,7 +65,7 @@ const commandModule: CommandModule<Options, Options> = {
66
65
 
67
66
  // Create World contract instance from deployed address
68
67
  const provider = new ethers.providers.StaticJsonRpcProvider(rpc);
69
- const WorldContract = new ethers.Contract(worldAddress, IBaseWorldData.abi, provider) as IBaseWorld;
68
+ const WorldContract = new ethers.Contract(worldAddress, IBaseWorldData.abi, provider);
70
69
 
71
70
  // TODO account for multiple namespaces (https://github.com/latticexyz/mud/issues/994)
72
71
  const namespace = mudConfig.namespace;
package/src/mud.ts CHANGED
@@ -27,8 +27,11 @@ yargs(hideBin(process.argv))
27
27
  );
28
28
  }
29
29
  console.log("");
30
- logError(err);
31
- console.log("");
30
+ // Even though `.fail` type says we should get an `Error`, this can sometimes be undefined
31
+ if (err != null) {
32
+ logError(err);
33
+ console.log("");
34
+ }
32
35
 
33
36
  process.exit(1);
34
37
  })
@@ -11,15 +11,13 @@ import { encodeSchema } from "@latticexyz/schema-type/deprecated";
11
11
  import { StoreConfig } from "@latticexyz/store";
12
12
  import { resolveAbiOrUserType } from "@latticexyz/store/codegen";
13
13
  import { WorldConfig, resolveWorldConfig } from "@latticexyz/world";
14
- import { IBaseWorld } from "@latticexyz/world/types/ethers-contracts/IBaseWorld";
15
- import WorldData from "@latticexyz/world/abi/World.sol/World.json" assert { type: "json" };
16
14
  import IBaseWorldData from "@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json" assert { type: "json" };
15
+ import WorldData from "@latticexyz/world/abi/World.sol/World.json" assert { type: "json" };
17
16
  import CoreModuleData from "@latticexyz/world/abi/CoreModule.sol/CoreModule.json" assert { type: "json" };
18
17
  import KeysWithValueModuleData from "@latticexyz/world/abi/KeysWithValueModule.sol/KeysWithValueModule.json" assert { type: "json" };
19
18
  import KeysInTableModuleData from "@latticexyz/world/abi/KeysInTableModule.sol/KeysInTableModule.json" assert { type: "json" };
20
19
  import UniqueEntityModuleData from "@latticexyz/world/abi/UniqueEntityModule.sol/UniqueEntityModule.json" assert { type: "json" };
21
20
  import { tableIdToHex } from "@latticexyz/common";
22
- import { abiTypesToSchema, schemaToHex } from "@latticexyz/protocol-parser";
23
21
 
24
22
  export interface DeployConfig {
25
23
  profile?: string;
@@ -128,7 +126,7 @@ export async function deploy(
128
126
  const contractPromises: Record<string, Promise<string>> = { ...worldPromise, ...systemPromises, ...modulePromises };
129
127
 
130
128
  // Create World contract instance from deployed address
131
- const WorldContract = new ethers.Contract(await contractPromises.World, IBaseWorldData.abi, signer) as IBaseWorld;
129
+ const WorldContract = new ethers.Contract(await contractPromises.World, IBaseWorldData.abi, signer);
132
130
 
133
131
  const confirmations = disableTxWait ? 0 : 1;
134
132
 
@@ -4,4 +4,3 @@ export * from "./errors";
4
4
  export * from "./getChainId";
5
5
  export * from "./getExistingContracts";
6
6
  export * from "./printMUD";
7
- export * from "./worldtypes";
@@ -1,11 +0,0 @@
1
- import W from"chalk";import H from"path";import{MUDError as Ee}from"@latticexyz/common/errors";import{loadConfig as Oe}from"@latticexyz/config/node";import{existsSync as Ce,readFileSync as De}from"fs";import ne from"path";import i from"chalk";import{ethers as T}from"ethers";import{defaultAbiCoder as Se}from"ethers/lib/utils.js";import{getOutDirectory as Fe,getScriptDirectory as ve,cast as xe,forge as Ie}from"@latticexyz/common/foundry";import{resolveWithContext as Re}from"@latticexyz/config";import{MUDError as h}from"@latticexyz/common/errors";import{encodeSchema as re}from"@latticexyz/schema-type/deprecated";import{resolveAbiOrUserType as se}from"@latticexyz/store/codegen";import{resolveWorldConfig as Te}from"@latticexyz/world";import Me from"@latticexyz/world/abi/World.sol/World.json"assert{type:"json"};import ie from"@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json"assert{type:"json"};import ae from"@latticexyz/world/abi/CoreModule.sol/CoreModule.json"assert{type:"json"};import le from"@latticexyz/world/abi/KeysWithValueModule.sol/KeysWithValueModule.json"assert{type:"json"};import ce from"@latticexyz/world/abi/KeysInTableModule.sol/KeysInTableModule.json"assert{type:"json"};import de from"@latticexyz/world/abi/UniqueEntityModule.sol/UniqueEntityModule.json"assert{type:"json"};import{tableIdToHex as M}from"@latticexyz/common";async function pe(r,p,u){let m=Te(r,p),x=Date.now(),{worldContractName:B,namespace:a,postDeployScript:j}=r,{profile:k,rpc:f,privateKey:E,priorityFeeMultiplier:b,debug:S,worldAddress:F,disableTxWait:y,pollInterval:A}=u,ye=await Fe(k),N=new T.providers.StaticJsonRpcProvider(f);N.pollingInterval=A;let $=new T.Wallet(E,N);console.log("Deploying from",$.address);let v=await $.getTransactionCount();console.log("Initial nonce",v);let O,U,K;await L(b);let d=[],z=Number(await xe(["block-number","--rpc-url",f],{profile:k}));console.log("Start deployment at block",z);let be={World:F?Promise.resolve(F):B?J(B,y):R(ie.abi,Me.bytecode,y,"World")},we=Object.keys(m.systems).reduce((e,t)=>(e[t]=J(t,y),e),{}),Q={CoreModule:R(ae.abi,ae.bytecode,y,"CoreModule"),KeysWithValueModule:R(le.abi,le.bytecode,y,"KeysWithValueModule"),KeysInTableModule:R(ce.abi,ce.bytecode,y,"KeysInTableModule"),UniqueEntityModule:R(de.abi,de.bytecode,y,"UniqueEntityModule")},X=r.modules.filter(e=>!Q[e.name]).reduce((e,t)=>(e[t.name]=J(t.name,y),e),Q),I={...be,...we,...X},P=new T.Contract(await I.World,ie.abi,$),C=y?0:1;F||(console.log(i.blue("Installing core World modules")),await w(P,"installRootModule",[await X.CoreModule,"0x"],C),console.log(i.green("Installed core World modules"))),a&&await w(P,"registerNamespace",[V(a)],C);let Z={};d=[...d,...Object.entries(r.tables).map(async([e,{name:t,schema:o,keySchema:s}])=>{console.log(i.blue(`Registering table ${e} at ${a}/${t}`)),Z[e]=je(a,t);let c=Object.values(o).map(l=>{let{schemaType:g}=se(l,r);return g}),n=Object.values(s).map(l=>{let{schemaType:g}=se(l,r);return g});await w(P,"registerTable",[M(a,t),re(n),re(c),Object.keys(s),Object.keys(o)],C),console.log(i.green(`Registered table ${e} at ${t}`))})],d=[...d,...Object.entries(m.systems).map(async([e,{name:t,openAccess:o,registerFunctionSelectors:s}])=>{if(console.log(i.blue(`Registering system ${e} at ${a}/${t}`)),await w(P,"registerSystem",[M(a,t),await I[e],o],C),console.log(i.green(`Registered system ${e} at ${a}/${t}`)),s){let c=await he(e),n=a==="";await Promise.all(c.map(async({functionName:l,functionArgs:g})=>{let D=n?l+g:`${a}_${t}_${l}${g}`;if(console.log(i.blue(`Registering function "${D}"`)),n){let $e=ue(D===""?{functionName:e,functionArgs:g}:{functionName:l,functionArgs:g}),Pe=ue({functionName:l,functionArgs:g});await w(P,"registerRootFunctionSelector",[M(a,t),$e,Pe],C)}else await w(P,"registerFunctionSelector",[M(a,t),l,g],C);console.log(i.green(`Registered function "${D}"`))}))}})],await Promise.all(d),d=[];for(let[e,{name:t,accessListAddresses:o,accessListSystems:s}]of Object.entries(m.systems)){let c=`${a}/${t}`;d=[...d,...o.map(async n=>{console.log(i.blue(`Grant ${n} access to ${e} (${c})`)),await w(P,"grantAccess",[M(a,t),n],C),console.log(i.green(`Granted ${n} access to ${e} (${a}/${t})`))})],d=[...d,...s.map(async n=>{console.log(i.blue(`Grant ${n} access to ${e} (${c})`)),await w(P,"grantAccess",[M(a,t),await I[n]],C),console.log(i.green(`Granted ${n} access to ${e} (${c})`))})]}await Promise.all(d),d=[],d=[...d,...r.modules.map(async e=>{console.log(i.blue(`Installing${e.root?" root ":" "}module ${e.name}`));let t=await Promise.all(e.args.map(n=>Re(n,{tableIds:Z,systemAddresses:I}))),o=t.map(n=>n.value),s=t.map(n=>n.type),c=await I[e.name];if(!c)throw new Error(`Module ${e.name} not found`);await w(P,e.root?"installRootModule":"installModule",[c,Se.encode(s,o)],C),console.log(i.green(`Installed${e.root?" root ":" "}module ${e.name}`))})],await Promise.all(d);let G=await $.getTransactionCount(),_=0,ee=100;for(;G!==v&&_<ee;)console.log(i.gray(`Waiting for transactions to be included before executing ${j} (local nonce: ${v}, remote nonce: ${G}, retry number ${_}/${ee})`)),await new Promise(e=>setTimeout(e,A)),_++,G=await $.getTransactionCount();if(G!==v)throw new h("Remote nonce doesn't match local nonce, indicating that not all deploy transactions were included.");d=[];let q=ne.join(await ve(),j+".s.sol");return Ce(q)?(console.log(i.blue(`Executing post deploy script at ${q}`)),await Ie(["script",j,"--sig","run(address)",await I.World,"--broadcast","--rpc-url",f,"-vvv"],{profile:k})):console.log(`No script at ${q}, skipping post deploy hook`),console.log(i.green("Deployment completed in",(Date.now()-x)/1e3,"seconds")),{worldAddress:await I.World,blockNumber:z};async function J(e,t){console.log(i.blue("Deploying",e));let{abi:o,bytecode:s}=await oe(e);return R(o,s,t,e)}async function R(e,t,o,s,c=0){try{let n=new T.ContractFactory(e,t,$);console.log(i.gray(`executing deployment of ${s} with nonce ${v}`));let l=n.deploy({nonce:v++,maxPriorityFeePerGas:O,maxFeePerGas:U,gasPrice:K}).then(D=>o?D:D.deployed());d.push(l);let{address:g}=await l;return console.log(i.green("Deployed",s,"to",g)),g}catch(n){if(S&&console.error(n),c===0&&n?.message.includes("transaction already imported"))return L(b*1.1),R(e,t,o,s,c++);throw n?.message.includes("invalid bytecode")?new h(`Error deploying ${s}: invalid bytecode. Note that linking of public libraries is not supported yet, make sure none of your libraries use "external" functions.`):n?.message.includes("CreateContractLimit")?new h(`Error deploying ${s}: CreateContractLimit exceeded.`):n}}async function he(e){let{abi:t}=await oe(e);return t.filter(o=>["fallback","function"].includes(o.type)).map(o=>o.type==="fallback"?{functionName:"",functionArgs:""}:{functionName:o.name,functionArgs:te(o.inputs)})}function te(e){return`(${e.map(o=>{let s=o.type.match(/tuple(.*)/);return s?te(o.components)+s[1]:o.type})})`}async function w(e,t,o,s=1,c=0){let n=`${t}(${o.map(l=>`'${l}'`).join(",")})`;try{let l=await e.estimateGas[t].apply(null,o);console.log(i.gray(`executing transaction: ${n} with nonce ${v}`));let g=e[t].apply(null,[...o,{gasLimit:l,nonce:v++,maxPriorityFeePerGas:O,maxFeePerGas:U,gasPrice:K}]).then(D=>s===0?D:D.wait(s));return d.push(g),g}catch(l){if(S&&console.error(l),c===0&&l?.message.includes("transaction already imported"))return L(b*1.1),w(e,t,o,s,c++);throw new h(`Gas estimation error for ${n}: ${l?.reason}`)}}async function oe(e){let t,o=ne.join(ye,e+".sol",e+".json");try{t=JSON.parse(De(o,"utf8"))}catch{throw new h(`Error reading file at ${o}`)}let s=t?.bytecode?.object;if(!s)throw new h(`No bytecode found in ${o}`);let c=t?.abi;if(!c)throw new h(`No ABI found in ${o}`);return{abi:c,bytecode:s}}async function L(e){let t=await N.getFeeData();if(t.lastBaseFeePerGas){if(!t.lastBaseFeePerGas.eq(0)&&(await $.getBalance()).eq(0))throw new h(`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 $.getAddress()}'`);O=t.lastBaseFeePerGas.eq(0)?0:Math.floor(15e8*e),U=t.lastBaseFeePerGas.mul(2).add(O)}else if(t.gasPrice){if(!t.gasPrice.eq(0)&&(await $.getBalance()).eq(0))throw new h("Attempting to deploy to a chain with non-zero gas price with an account that has no balance.");K=t.gasPrice}else throw new h("Can not fetch fee data from RPC")}}function V(r){if(r.length>16)throw new Error("String does not fit into 16 bytes");let p=new Uint8Array(16);for(let u=0;u<r.length;u++)p[u]=r.charCodeAt(u);for(let u=r.length;u<16;u++)p[u]=0;return p}function je(r,p){let u=V(r),m=V(p),x=new Uint8Array(32);return x.set(u),x.set(m,16),x}function ue({functionName:r,functionArgs:p}){let u=r+p;return u===""?"0x":ke(u)}function ke(r){return T.utils.hexDataSlice(T.utils.keccak256(T.utils.toUtf8Bytes(r)),0,4)}import{forge as fe,getRpcUrl as Ge,getSrcDirectory as Ne}from"@latticexyz/common/foundry";import{existsSync as Ue,mkdirSync as Ke,readFileSync as _e,writeFileSync as Y}from"fs";import{ethers as Ae}from"ethers";async function ge(r){let{result:p}=await Ae.utils.fetchJson(r,'{ "id": 42, "jsonrpc": "2.0", "method": "eth_chainId", "params": [ ] }');return Number(p)}import We from"glob";import{basename as Be}from"path";function me(r){return We.sync(`${r}/**/*.sol`).map(p=>({path:p,basename:Be(p,".sol")}))}async function It(r){r.profile??=process.env.FOUNDRY_PROFILE;let{configPath:p,printConfig:u,profile:m,clean:x,skipBuild:B}=r,a=r.rpc??await Ge(m);console.log(W.bgBlue(W.whiteBright(`
3
- Deploying MUD contracts${m?" with profile "+m:""} to RPC ${a}
4
- `))),x&&await fe(["clean"],{profile:m}),B||await fe(["build"],{profile:m});let j=r?.srcDir??await Ne(),k=me(j).map(({basename:S})=>S),f=await Oe(p);u&&console.log(W.green(`
5
- Resolved config:
6
- `),JSON.stringify(f,null,2));let E=process.env.PRIVATE_KEY;if(!E)throw new Ee(`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 b=await pe(f,k,{...r,rpc:a,privateKey:E});if(r.saveDeployment){let S=await ge(a),F=H.join(f.deploysDirectory,S.toString());Ke(F,{recursive:!0}),Y(H.join(F,"latest.json"),JSON.stringify(b,null,2)),Y(H.join(F,Date.now()+".json"),JSON.stringify(b,null,2));let y=[1337,31337],A=Ue(f.worldsFile)?JSON.parse(_e(f.worldsFile,"utf-8")):{};A[S]={address:b.worldAddress,blockNumber:y.includes(S)?void 0:b.blockNumber},Y(f.worldsFile,JSON.stringify(A,null,2)),console.log(W.bgGreen(W.whiteBright(`
9
- Deployment result (written to ${f.worldsFile} and ${F}):
10
- `)))}return console.log(b),b}export{ge as a,me as b,It as c};
11
- //# sourceMappingURL=chunk-YDUX555R.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/deployHandler.ts","../src/utils/deploy.ts","../src/utils/getChainId.ts","../src/utils/getExistingContracts.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 { getChainId } from \"../utils/getChainId\";\nimport { getExistingContracts } from \"./getExistingContracts\";\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) await forge([\"clean\"], { profile });\n\n // Run forge build\n if (!skipBuild) await forge([\"build\"], { profile });\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 { existsSync, readFileSync } from \"fs\";\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport { BigNumber, ContractInterface, ethers } from \"ethers\";\nimport { defaultAbiCoder as abi, Fragment, ParamType } from \"ethers/lib/utils.js\";\n\nimport { getOutDirectory, getScriptDirectory, cast, forge } from \"@latticexyz/common/foundry\";\nimport { resolveWithContext } from \"@latticexyz/config\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { encodeSchema } from \"@latticexyz/schema-type/deprecated\";\nimport { StoreConfig } from \"@latticexyz/store\";\nimport { resolveAbiOrUserType } from \"@latticexyz/store/codegen\";\nimport { WorldConfig, resolveWorldConfig } from \"@latticexyz/world\";\nimport { IBaseWorld } from \"@latticexyz/world/types/ethers-contracts/IBaseWorld\";\nimport WorldData from \"@latticexyz/world/abi/World.sol/World.json\" assert { type: \"json\" };\nimport IBaseWorldData from \"@latticexyz/world/abi/IBaseWorld.sol/IBaseWorld.json\" assert { type: \"json\" };\nimport CoreModuleData from \"@latticexyz/world/abi/CoreModule.sol/CoreModule.json\" assert { type: \"json\" };\nimport KeysWithValueModuleData from \"@latticexyz/world/abi/KeysWithValueModule.sol/KeysWithValueModule.json\" assert { type: \"json\" };\nimport KeysInTableModuleData from \"@latticexyz/world/abi/KeysInTableModule.sol/KeysInTableModule.json\" assert { type: \"json\" };\nimport UniqueEntityModuleData from \"@latticexyz/world/abi/UniqueEntityModule.sol/UniqueEntityModule.json\" assert { type: \"json\" };\nimport { tableIdToHex } from \"@latticexyz/common\";\nimport { abiTypesToSchema, schemaToHex } from \"@latticexyz/protocol-parser\";\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 resolvedConfig = resolveWorldConfig(mudConfig, existingContractNames);\n\n const startTime = Date.now();\n const { worldContractName, namespace, postDeployScript } = mudConfig;\n const { profile, rpc, privateKey, priorityFeeMultiplier, debug, worldAddress, disableTxWait, pollInterval } =\n deployConfig;\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 // Manual nonce handling to allow for faster sending of transactions without waiting for previous transactions\n let nonce = await signer.getTransactionCount();\n console.log(\"Initial nonce\", nonce);\n\n // Compute maxFeePerGas and maxPriorityFeePerGas like ethers, but allow for a multiplier to allow replacing pending transactions\n let maxPriorityFeePerGas: number | undefined;\n let maxFeePerGas: BigNumber | undefined;\n let gasPrice: BigNumber | undefined;\n\n await setInternalFeePerGas(priorityFeeMultiplier);\n\n // Catch all to await any promises before exiting the script\n let promises: Promise<unknown>[] = [];\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 World\n const worldPromise = {\n World: worldAddress\n ? Promise.resolve(worldAddress)\n : worldContractName\n ? deployContractByName(worldContractName, disableTxWait)\n : deployContract(IBaseWorldData.abi, WorldData.bytecode, disableTxWait, \"World\"),\n };\n\n // Deploy Systems\n const systemPromises = Object.keys(resolvedConfig.systems).reduce<Record<string, Promise<string>>>(\n (acc, systemName) => {\n acc[systemName] = deployContractByName(systemName, disableTxWait);\n return acc;\n },\n {}\n );\n\n // Deploy default World modules\n const defaultModules: Record<string, Promise<string>> = {\n // TODO: these only need to be deployed once per chain, add a check if they exist already\n CoreModule: deployContract(CoreModuleData.abi, CoreModuleData.bytecode, disableTxWait, \"CoreModule\"),\n KeysWithValueModule: deployContract(\n KeysWithValueModuleData.abi,\n KeysWithValueModuleData.bytecode,\n disableTxWait,\n \"KeysWithValueModule\"\n ),\n KeysInTableModule: deployContract(\n KeysInTableModuleData.abi,\n KeysInTableModuleData.bytecode,\n disableTxWait,\n \"KeysInTableModule\"\n ),\n UniqueEntityModule: deployContract(\n UniqueEntityModuleData.abi,\n UniqueEntityModuleData.bytecode,\n disableTxWait,\n \"UniqueEntityModule\"\n ),\n };\n\n // Deploy user Modules\n const modulePromises = mudConfig.modules\n .filter((module) => !defaultModules[module.name]) // Only deploy user modules here, not default modules\n .reduce<Record<string, Promise<string>>>((acc, module) => {\n acc[module.name] = deployContractByName(module.name, disableTxWait);\n return acc;\n }, defaultModules);\n\n // Combine all contracts into one object\n const contractPromises: Record<string, Promise<string>> = { ...worldPromise, ...systemPromises, ...modulePromises };\n\n // Create World contract instance from deployed address\n const WorldContract = new ethers.Contract(await contractPromises.World, IBaseWorldData.abi, signer) as IBaseWorld;\n\n const confirmations = disableTxWait ? 0 : 1;\n\n // Install core Modules\n if (!worldAddress) {\n console.log(chalk.blue(\"Installing core World modules\"));\n await fastTxExecute(WorldContract, \"installRootModule\", [await modulePromises.CoreModule, \"0x\"], confirmations);\n console.log(chalk.green(\"Installed core World modules\"));\n }\n\n // Register namespace\n if (namespace) await fastTxExecute(WorldContract, \"registerNamespace\", [toBytes16(namespace)], confirmations);\n\n // Register tables\n const tableIds: { [tableName: string]: Uint8Array } = {};\n promises = [\n ...promises,\n ...Object.entries(mudConfig.tables).map(async ([tableName, { name, schema, keySchema }]) => {\n console.log(chalk.blue(`Registering table ${tableName} at ${namespace}/${name}`));\n\n // Store the tableId for later use\n tableIds[tableName] = toResourceSelector(namespace, name);\n\n // Register table\n const schemaTypes = Object.values(schema).map((abiOrUserType) => {\n const { schemaType } = resolveAbiOrUserType(abiOrUserType, mudConfig);\n return schemaType;\n });\n\n const keyTypes = Object.values(keySchema).map((abiOrUserType) => {\n const { schemaType } = resolveAbiOrUserType(abiOrUserType, mudConfig);\n return schemaType;\n });\n\n await fastTxExecute(\n WorldContract,\n \"registerTable\",\n [\n tableIdToHex(namespace, name),\n encodeSchema(keyTypes),\n encodeSchema(schemaTypes),\n Object.keys(keySchema),\n Object.keys(schema),\n ],\n confirmations\n );\n\n console.log(chalk.green(`Registered table ${tableName} at ${name}`));\n }),\n ];\n\n // Register systems (using forEach instead of for..of to avoid blocking on async calls)\n promises = [\n ...promises,\n ...Object.entries(resolvedConfig.systems).map(\n async ([systemName, { name, openAccess, registerFunctionSelectors }]) => {\n // Register system at route\n console.log(chalk.blue(`Registering system ${systemName} at ${namespace}/${name}`));\n await fastTxExecute(\n WorldContract,\n \"registerSystem\",\n [tableIdToHex(namespace, name), await contractPromises[systemName], openAccess],\n confirmations\n );\n console.log(chalk.green(`Registered system ${systemName} at ${namespace}/${name}`));\n\n // Register function selectors for the system\n if (registerFunctionSelectors) {\n const functionSignatures: FunctionSignature[] = await loadFunctionSignatures(systemName);\n const isRoot = namespace === \"\";\n // Using Promise.all to avoid blocking on async calls\n await Promise.all(\n functionSignatures.map(async ({ functionName, functionArgs }) => {\n const functionSignature = isRoot\n ? functionName + functionArgs\n : `${namespace}_${name}_${functionName}${functionArgs}`;\n\n console.log(chalk.blue(`Registering function \"${functionSignature}\"`));\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 await fastTxExecute(\n WorldContract,\n \"registerRootFunctionSelector\",\n [tableIdToHex(namespace, name), worldFunctionSelector, systemFunctionSelector],\n confirmations\n );\n } else {\n await fastTxExecute(\n WorldContract,\n \"registerFunctionSelector\",\n [tableIdToHex(namespace, name), functionName, functionArgs],\n confirmations\n );\n }\n console.log(chalk.green(`Registered function \"${functionSignature}\"`));\n })\n );\n }\n }\n ),\n ];\n\n // Wait for resources to be registered before granting access to them\n await Promise.all(promises); // ----------------------------------------------------------------------------------------------\n promises = [];\n\n // Grant access to systems\n for (const [systemName, { name, accessListAddresses, accessListSystems }] of Object.entries(resolvedConfig.systems)) {\n const resourceSelector = `${namespace}/${name}`;\n\n // Grant access to addresses\n promises = [\n ...promises,\n ...accessListAddresses.map(async (address) => {\n console.log(chalk.blue(`Grant ${address} access to ${systemName} (${resourceSelector})`));\n await fastTxExecute(WorldContract, \"grantAccess\", [tableIdToHex(namespace, name), address], confirmations);\n console.log(chalk.green(`Granted ${address} access to ${systemName} (${namespace}/${name})`));\n }),\n ];\n\n // Grant access to other systems\n promises = [\n ...promises,\n ...accessListSystems.map(async (granteeSystem) => {\n console.log(chalk.blue(`Grant ${granteeSystem} access to ${systemName} (${resourceSelector})`));\n await fastTxExecute(\n WorldContract,\n \"grantAccess\",\n [tableIdToHex(namespace, name), await contractPromises[granteeSystem]],\n confirmations\n );\n console.log(chalk.green(`Granted ${granteeSystem} access to ${systemName} (${resourceSelector})`));\n }),\n ];\n }\n\n // Wait for access to be granted before installing modules\n await Promise.all(promises); // ----------------------------------------------------------------------------------------------\n promises = [];\n\n // Install modules\n promises = [\n ...promises,\n ...mudConfig.modules.map(async (module) => {\n console.log(chalk.blue(`Installing${module.root ? \" root \" : \" \"}module ${module.name}`));\n // Resolve arguments\n const resolvedArgs = await Promise.all(\n module.args.map((arg) => resolveWithContext(arg, { tableIds, systemAddresses: contractPromises }))\n );\n const values = resolvedArgs.map((arg) => arg.value);\n const types = resolvedArgs.map((arg) => arg.type);\n const moduleAddress = await contractPromises[module.name];\n if (!moduleAddress) throw new Error(`Module ${module.name} not found`);\n\n // Send transaction to install module\n await fastTxExecute(\n WorldContract,\n module.root ? \"installRootModule\" : \"installModule\",\n [moduleAddress, abi.encode(types, values)],\n confirmations\n );\n\n console.log(chalk.green(`Installed${module.root ? \" root \" : \" \"}module ${module.name}`));\n }),\n ];\n\n // Await all promises before executing PostDeploy script\n await Promise.all(promises); // ----------------------------------------------------------------------------------------------\n\n // Confirm the current nonce is the expected nonce to make sure all transactions have been included\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 promises = [];\n\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 [\n \"script\",\n postDeployScript,\n \"--sig\",\n \"run(address)\",\n await contractPromises.World,\n \"--broadcast\",\n \"--rpc-url\",\n rpc,\n \"-vvv\",\n ],\n {\n profile,\n }\n );\n } else {\n console.log(`No script at ${postDeployPath}, skipping post deploy hook`);\n }\n\n console.log(chalk.green(\"Deployment completed in\", (Date.now() - startTime) / 1000, \"seconds\"));\n\n return { worldAddress: await contractPromises.World, blockNumber };\n\n // ------------------- INTERNAL FUNCTIONS -------------------\n // (Inlined to avoid having to pass around nonce, signer and forgeOutDir)\n\n /**\n * Deploy a contract and return the address\n * @param contractName Name of the contract to deploy (must exist in the file system)\n * @param disableTxWait Disable waiting for contract deployment\n * @returns Address of the deployed contract\n */\n async function deployContractByName(contractName: string, disableTxWait: boolean): Promise<string> {\n console.log(chalk.blue(\"Deploying\", contractName));\n\n const { abi, bytecode } = await getContractData(contractName);\n return deployContract(abi, bytecode, disableTxWait, contractName);\n }\n\n /**\n * Deploy a contract and return the address\n * @param abi The contract interface\n * @param bytecode The contract bytecode\n * @param disableTxWait Disable waiting for contract deployment\n * @param contractName The contract name (optional, used for logs)\n * @param retryCount\n * @returns Address of the deployed contract\n */\n async function deployContract(\n abi: ContractInterface,\n bytecode: string | { object: string },\n disableTxWait: boolean,\n contractName?: string,\n retryCount = 0\n ): Promise<string> {\n try {\n const factory = new ethers.ContractFactory(abi, bytecode, signer);\n console.log(chalk.gray(`executing deployment of ${contractName} with nonce ${nonce}`));\n const deployPromise = factory\n .deploy({\n nonce: nonce++,\n maxPriorityFeePerGas,\n maxFeePerGas,\n gasPrice,\n })\n .then((c) => (disableTxWait ? c : c.deployed()));\n\n promises.push(deployPromise);\n const { address } = await deployPromise;\n\n console.log(chalk.green(\"Deployed\", contractName, \"to\", address));\n return address;\n } catch (error: any) {\n if (debug) console.error(error);\n if (retryCount === 0 && error?.message.includes(\"transaction already imported\")) {\n // If the deployment failed because the transaction was already imported,\n // retry with a higher priority fee\n setInternalFeePerGas(priorityFeeMultiplier * 1.1);\n return deployContract(abi, bytecode, disableTxWait, contractName, retryCount++);\n } else if (error?.message.includes(\"invalid bytecode\")) {\n throw new MUDError(\n `Error deploying ${contractName}: 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 ${contractName}: CreateContractLimit exceeded.`);\n } else throw error;\n }\n }\n\n /**\n * Deploy a contract and return the address\n * @param contractName Name of the contract to deploy (must exist in the file system)\n * @returns Address of the deployed contract\n *\n * NOTE: Forge deploy seems to be slightly slower than ethers\n * (probably due to the extra overhead spawning a child process to run forge),\n * so we mostly use ethersDeployContract here.\n * However, for contracts not in the user directory (eg. the vanilla World contract),\n * using forge is more convenient because it automatically finds the contract in the @latticexyz/world package.\n */\n // async function forgeDeployContract(contractName: string): Promise<string> {\n // console.log(chalk.blue(\"Deploying\", contractName));\n\n // const { deployedTo } = JSON.parse(\n // await forge(\n // [\"create\", contractName, \"--rpc-url\", rpc, \"--private-key\", privateKey, \"--json\", \"--nonce\", String(nonce++)],\n // { profile, silent: true }\n // )\n // );\n // return deployedTo;\n // }\n\n async function loadFunctionSignatures(contractName: string): Promise<FunctionSignature[]> {\n const { abi } = await getContractData(contractName);\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 /**\n * Recursively turn (nested) structs in signatures into tuples\n */\n function 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 /**\n * Only await gas estimation (for speed), only execute if gas estimation succeeds (for safety)\n */\n async function fastTxExecute<C extends { estimateGas: any; [key: string]: any }, F extends keyof C>(\n contract: C,\n func: F,\n args: Parameters<C[F]>,\n confirmations = 1,\n retryCount = 0\n ): Promise<Awaited<ReturnType<Awaited<ReturnType<C[F]>>[\"wait\"]>>> {\n const functionName = `${func as string}(${args.map((arg) => `'${arg}'`).join(\",\")})`;\n try {\n const gasLimit = await contract.estimateGas[func].apply(null, args);\n console.log(chalk.gray(`executing transaction: ${functionName} with nonce ${nonce}`));\n const txPromise = contract[func]\n .apply(null, [...args, { gasLimit, nonce: nonce++, maxPriorityFeePerGas, maxFeePerGas, gasPrice }])\n .then((tx: any) => (confirmations === 0 ? tx : tx.wait(confirmations)));\n promises.push(txPromise);\n return txPromise;\n } catch (error: any) {\n if (debug) console.error(error);\n if (retryCount === 0 && error?.message.includes(\"transaction already imported\")) {\n // If the deployment failed because the transaction was already imported,\n // retry with a higher priority fee\n setInternalFeePerGas(priorityFeeMultiplier * 1.1);\n return fastTxExecute(contract, func, args, confirmations, retryCount++);\n } else throw new MUDError(`Gas estimation error for ${functionName}: ${error?.reason}`);\n }\n }\n\n /**\n * Load the contract's abi and bytecode from the file system\n * @param contractName: Name of the contract to load\n */\n async function getContractData(contractName: string): Promise<{ 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\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 */\n async function setInternalFeePerGas(multiplier: number) {\n // Compute maxFeePerGas and maxPriorityFeePerGas like ethers, but allow for a multiplier to allow replacing pending transactions\n const feeData = await provider.getFeeData();\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 }\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)\nfunction 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\n// TODO: use TableId from utils as soon as utils are usable inside cli\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\ninterface FunctionSignature {\n functionName: string;\n functionArgs: string;\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 toFunctionSelector({ functionName, functionArgs }: FunctionSignature): string {\n const functionSignature = functionName + functionArgs;\n if (functionSignature === \"\") return \"0x\";\n return sigHash(functionSignature);\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 { 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","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"],"mappings":"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","names":["chalk","path","MUDError","loadConfig","existsSync","readFileSync","path","chalk","ethers","abi","getOutDirectory","getScriptDirectory","cast","forge","resolveWithContext","MUDError","encodeSchema","resolveAbiOrUserType","resolveWorldConfig","WorldData","IBaseWorldData","CoreModuleData","KeysWithValueModuleData","KeysInTableModuleData","UniqueEntityModuleData","tableIdToHex","deploy","mudConfig","existingContractNames","deployConfig","resolvedConfig","startTime","worldContractName","namespace","postDeployScript","profile","rpc","privateKey","priorityFeeMultiplier","debug","worldAddress","disableTxWait","pollInterval","forgeOutDirectory","provider","signer","nonce","maxPriorityFeePerGas","maxFeePerGas","gasPrice","setInternalFeePerGas","promises","blockNumber","worldPromise","deployContractByName","deployContract","systemPromises","acc","systemName","defaultModules","modulePromises","module","contractPromises","WorldContract","confirmations","fastTxExecute","toBytes16","tableIds","tableName","name","schema","keySchema","toResourceSelector","schemaTypes","abiOrUserType","schemaType","keyTypes","openAccess","registerFunctionSelectors","functionSignatures","loadFunctionSignatures","isRoot","functionName","functionArgs","functionSignature","worldFunctionSelector","toFunctionSelector","systemFunctionSelector","accessListAddresses","accessListSystems","resourceSelector","address","granteeSystem","resolvedArgs","arg","values","types","moduleAddress","remoteNonce","retryCount","maxRetries","resolve","postDeployPath","contractName","bytecode","getContractData","factory","deployPromise","c","error","item","parseComponents","params","param","tupleMatch","contract","func","args","gasLimit","txPromise","tx","data","contractDataPath","multiplier","feeData","input","result","i","file","namespaceBytes","fileBytes","sigHash","signature","forge","getRpcUrl","getSrcDirectory","existsSync","mkdirSync","readFileSync","writeFileSync","ethers","getChainId","rpc","chainId","glob","basename","getExistingContracts","srcDir","path","deployHandler","args","configPath","printConfig","profile","clean","skipBuild","rpc","getRpcUrl","chalk","forge","srcDir","getSrcDirectory","existingContractNames","getExistingContracts","basename","mudConfig","loadConfig","privateKey","MUDError","deploymentInfo","deploy","chainId","getChainId","outputDir","path","mkdirSync","writeFileSync","localChains","deploys","existsSync","readFileSync"]}
@@ -1,21 +0,0 @@
1
- import { getOutDirectory } from "@latticexyz/common/foundry";
2
- import path from "path";
3
- import { runTypeChain } from "typechain";
4
-
5
- /**
6
- * Generate IWorld typescript bindings
7
- */
8
- export async function worldtypes() {
9
- const cwd = process.cwd();
10
- const forgeOurDir = await getOutDirectory();
11
- const IWorldPath = path.join(process.cwd(), forgeOurDir, "IWorld.sol/IWorld.json");
12
-
13
- await runTypeChain({
14
- cwd,
15
- filesToProcess: [IWorldPath],
16
- allFiles: [IWorldPath],
17
- target: "ethers-v5",
18
- });
19
-
20
- console.log("Typechain generated IWorld interface");
21
- }