@latticexyz/cli 2.1.1-main-542ea540329fce74d85c74368e26386682e39cce → 2.1.1-main-91028bf231c1c427306750d09a1064f13bf6115a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands-VAQQMCRZ.js +41 -0
- package/dist/commands-VAQQMCRZ.js.map +1 -0
- package/dist/mud.js +1 -1
- package/package.json +11 -10
- package/dist/commands-4MYO23UW.js +0 -39
- package/dist/commands-4MYO23UW.js.map +0 -1
@@ -0,0 +1,41 @@
|
|
1
|
+
import{a as V}from"./chunk-JXC4VYGI.js";import Ys from"@latticexyz/gas-report";import Gs from"@latticexyz/abi-ts";import{loadConfig as Vo,resolveConfigPath as Uo}from"@latticexyz/config/node";import{tablegen as Fo}from"@latticexyz/store/codegen";import{worldgen as zo}from"@latticexyz/world/node";import{forge as No}from"@latticexyz/common/foundry";import{execa as Lo}from"execa";async function U({rootDir:e,config:o,foundryProfile:r=process.env.FOUNDRY_PROFILE}){await Promise.all([Fo({rootDir:e,config:o}),zo({rootDir:e,config:o})]),await No(["build"],{profile:r}),await Lo("mud",["abi-ts"],{stdio:"inherit"})}import _o from"node:path";var Ko={command:"build",describe:"Build contracts and generate MUD artifacts (table libraries, world interface, ABI)",builder(e){return e.options({configPath:{type:"string",desc:"Path to the MUD config file"},profile:{type:"string",desc:"The foundry profile to use"}})},async handler(e){let o=await Uo(e.configPath),r=await Vo(o);await U({rootDir:_o.dirname(o),config:r,foundryProfile:e.profile}),process.exit(0)}},Ce=Ko;import{rmSync as Jo}from"fs";import{homedir as qo}from"os";import Yo from"path";import{execa as Go}from"execa";var Qo={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=qo();Jo(Yo.join(o,".foundry","anvil","tmp"),{recursive:!0,force:!0});let r=["-b",String(e),"--block-base-fee-per-gas","0"];console.log(`Running: anvil ${r.join(" ")}`);let n=Go("anvil",r,{stdio:["inherit","inherit","inherit"]});process.on("SIGINT",()=>{console.log(`
|
2
|
+
gracefully shutting down from SIGINT (Crtl-C)`),n.kill(),process.exit()}),await n}},Se=Qo;var Zo={command:"hello <name>",describe:"Greet <name> with Hello",builder(e){return e.options({upper:{type:"boolean"}}).positional("name",{type:"string",demandOption:!0})},handler({name:e}){let o=`Gm, ${e}!`;console.log(o),process.exit(0)}},De=Zo;import{loadConfig as Xo,resolveConfigPath as et}from"@latticexyz/config/node";import{tablegen as ot}from"@latticexyz/store/codegen";import tt from"node:path";var rt={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 MUD config file"}})},async handler(e){let o=await et(e.configPath),r=await Xo(o);await ot({rootDir:tt.dirname(o),config:r}),process.exit(0)}},Ae=rt;import ie from"node:path";import{existsSync as hn,mkdirSync as wn,readFileSync as xn,writeFileSync as ge}from"node:fs";import{getBalance as lt,sendRawTransaction as ct,sendTransaction as Te,waitForTransactionReceipt as ke}from"viem/actions";var v={gasPrice:1e11,gasLimit:1e5,signerAddress:"3fab184622dc19b6109349b94811493bf2a45362",transaction:"f8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222",address:"4e59b44847b379578588920ca78fbf26c0b4956c",creationCode:"604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"};import ve from"debug";var _=ve("mud:cli"),st=ve("mud:cli");_.log=console.debug.bind(console);st.log=console.error.bind(console);var m=_.extend("deploy"),at=_.extend("deploy");m.log=console.debug.bind(console);at.log=console.error.bind(console);import{sliceHex as it}from"viem";import{getBytecode as dt}from"viem/actions";var K=`0x${v.address}`;async function J(e){let o=await dt(e,{address:K});if(o)return m("found CREATE2 deployer at",K),o!==it(`0x${v.creationCode}`,14)&&console.warn(`
|
3
|
+
\u26A0\uFE0F Bytecode for deployer at ${K} did not match the expected CREATE2 bytecode. You may have unexpected results.
|
4
|
+
`),K}var de=`0x${v.address}`;async function Pe(e){let o=await J(e);if(o!==void 0)return o;let r=BigInt(v.gasLimit)*BigInt(v.gasPrice),n=await lt(e,{address:`0x${v.signerAddress}`}),t=r-n;if(t>0){m("sending gas for CREATE2 deployer to signer at",v.signerAddress);let a=await Te(e,{chain:e.chain??null,to:`0x${v.signerAddress}`,value:t}),p=await ke(e,{hash:a});if(p.status!=="success")throw console.error("failed to send gas to deployer signer",p),new Error("failed to send gas to deployer signer")}m("deploying CREATE2 deployer at",de);let s=await ct(e,{serializedTransaction:`0x${v.transaction}`}).catch(a=>{if(String(a).includes("only replay-protected (EIP-155) transactions allowed over RPC"))return console.warn(`
|
5
|
+
\u26A0\uFE0F Your chain or RPC does not allow for non EIP-155 signed transactions, so your deploys will not be determinstic and contract addresses may change between deploys.
|
6
|
+
|
7
|
+
We recommend running your chain's node with \`--rpc.allow-unprotected-txs\` to enable determinstic deployments.
|
8
|
+
`),m("deploying CREATE2 deployer"),Te(e,{chain:e.chain??null,data:`0x${v.creationCode}`});throw a}),i=await ke(e,{hash:s});if(!i.contractAddress)throw new Error("Deploy receipt did not have contract address, was the deployer not deployed?");return i.contractAddress!==de&&console.warn(`
|
9
|
+
\u26A0\uFE0F CREATE2 deployer created at ${i.contractAddress} does not match the CREATE2 determinstic deployer we expected (${de})`),i.contractAddress}import{waitForTransactionReceipt as Ht}from"viem/actions";import{waitForTransactionReceipt as Ct}from"viem/actions";import{concatHex as ut,getCreate2Address as gt}from"viem";import{getBytecode as bt}from"viem/actions";import{padHex as pt}from"viem";import mt from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import{helloStoreEvent as ft}from"@latticexyz/store";import{helloWorldEvent as yt}from"@latticexyz/world";var x=pt("0x",{size:32}),E=parseInt("6000",16),q=[ft,yt],S=mt,Me=["2.0.0","2.0.1","2.0.2"],Oe=["2.0.0","2.0.1","2.0.2"];import{sendTransaction as ht}from"@latticexyz/common";import wt from"p-retry";import{wait as xt}from"@latticexyz/common/utils";async function Be({client:e,deployerAddress:o,bytecode:r,deployedBytecodeSize:n,debugLabel:t="contract"}){if(r.includes("__$"))throw new Error(`Found unlinked public library in ${t} bytecode`);let s=gt({from:o,salt:x,bytecode:r});return await bt(e,{address:s,blockTag:"pending"})?(m("found",t,"at",s),[]):(n>E?console.warn(`
|
10
|
+
Bytecode for ${t} (${n} bytes) is over the contract size limit (${E} bytes). Run \`forge build --sizes\` for more info.
|
11
|
+
`):n>E*.95&&console.warn(`
|
12
|
+
Bytecode for ${t} (${n} bytes) is almost over the contract size limit (${E} bytes). Run \`forge build --sizes\` for more info.
|
13
|
+
`),m("deploying",t,"at",s),[await wt(()=>ht(e,{chain:e.chain??null,to:o,data:ut([x,r])}),{retries:3,onFailedAttempt:async a=>{let p=a.attemptNumber*500;m(`failed to deploy ${t}, retrying in ${p}ms...`),await xt(p)}})])}import{uniqueBy as St}from"@latticexyz/common/utils";async function k({client:e,deployerAddress:o,contracts:r}){let n=St(r,s=>s.bytecode),t=(await Promise.all(n.map(s=>Be({client:e,deployerAddress:o,...s})))).flat();if(t.length){m("waiting for contracts");for(let s of t)await Ct(e,{hash:s})}return t}import He from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.json"assert{type:"json"};import vt from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"assert{type:"json"};import{getCreate2Address as Tt,encodeDeployData as kt,size as Pt}from"viem";import Ie from"@latticexyz/world/out/AccessManagementSystem.sol/AccessManagementSystem.json"assert{type:"json"};import We from"@latticexyz/world/out/BalanceTransferSystem.sol/BalanceTransferSystem.json"assert{type:"json"};import Re from"@latticexyz/world/out/BatchCallSystem.sol/BatchCallSystem.json"assert{type:"json"};import je from"@latticexyz/world/out/RegistrationSystem.sol/RegistrationSystem.json"assert{type:"json"};import $e from"@latticexyz/world/out/InitModule.sol/InitModule.json"assert{type:"json"};import Dt from"@latticexyz/world/out/InitModule.sol/InitModule.abi.json"assert{type:"json"};import{getCreate2Address as F,encodeDeployData as At,size as z}from"viem";function Y(e){let o=z(Ie.deployedBytecode.object),r=Ie.bytecode.object,n=F({from:e,bytecode:r,salt:x}),t=z(We.deployedBytecode.object),s=We.bytecode.object,i=F({from:e,bytecode:s,salt:x}),a=z(Re.deployedBytecode.object),p=Re.bytecode.object,d=F({from:e,bytecode:p,salt:x}),l=z(je.deployedBytecode.object),f=je.bytecode.object,y=F({from:e,bytecode:f,salt:x}),h=z($e.deployedBytecode.object),w=At({bytecode:$e.bytecode.object,abi:Dt,args:[n,i,d,y]}),u=F({from:e,bytecode:w,salt:x});return{AccessManagementSystem:{bytecode:r,deployedBytecodeSize:o,debugLabel:"access management system",address:n},BalanceTransferSystem:{bytecode:s,deployedBytecodeSize:t,debugLabel:"balance transfer system",address:i},BatchCallSystem:{bytecode:p,deployedBytecodeSize:a,debugLabel:"batch call system",address:d},RegistrationSystem:{bytecode:f,deployedBytecodeSize:l,debugLabel:"core registration system",address:y},InitModule:{bytecode:w,deployedBytecodeSize:h,debugLabel:"core module",address:u}}}function G(e){let o=Y(e),r=Pt(He.deployedBytecode.object),n=kt({bytecode:He.bytecode.object,abi:vt,args:[o.InitModule.address]}),t=Tt({from:e,bytecode:n,salt:x});return{...o,WorldFactory:{bytecode:n,deployedBytecodeSize:r,debugLabel:"world factory",address:t}}}import Ee from"@latticexyz/world/out/WorldProxyFactory.sol/WorldProxyFactory.json"assert{type:"json"};import Mt from"@latticexyz/world/out/WorldProxyFactory.sol/WorldProxyFactory.abi.json"assert{type:"json"};import{getCreate2Address as Ot,encodeDeployData as Bt,size as It}from"viem";function Q(e){let o=Y(e),r=It(Ee.deployedBytecode.object),n=Bt({bytecode:Ee.bytecode.object,abi:Mt,args:[o.InitModule.address]}),t=Ot({from:e,bytecode:n,salt:x});return{...o,WorldProxyFactory:{bytecode:n,deployedBytecodeSize:r,debugLabel:"world proxy factory",address:t}}}async function Z(e,o,r){if(r){let t=Q(o);return await k({client:e,deployerAddress:o,contracts:Object.values(t)}),t.WorldProxyFactory.address}let n=G(o);return await k({client:e,deployerAddress:o,contracts:Object.values(n)}),n.WorldFactory.address}import Et from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"assert{type:"json"};import{writeContract as Ft}from"@latticexyz/common";import{AbiEventSignatureNotFoundError as Wt,decodeEventLog as Rt,hexToString as Fe,parseAbi as jt}from"viem";import{isDefined as $t}from"@latticexyz/common/utils";function X(e){let o=e.map(i=>{try{return{...i,...Rt({strict:!0,abi:jt(q),topics:i.topics,data:i.data})}}catch(a){if(a instanceof Wt)return;throw a}}).filter($t),{address:r,deployBlock:n,worldVersion:t,storeVersion:s}=o.reduce((i,a)=>({...i,address:a.address,deployBlock:a.blockNumber,...a.eventName==="HelloWorld"?{worldVersion:Fe(a.args.worldVersion).replace(/\0+$/,"")}:null,...a.eventName==="HelloStore"?{storeVersion:Fe(a.args.storeVersion).replace(/\0+$/,"")}:null}),{});if(r==null)throw new Error("could not find world address");if(n==null)throw new Error("could not find world deploy block number");if(t==null)throw new Error("could not find world version");if(s==null)throw new Error("could not find store version");return{address:r,deployBlock:n,worldVersion:t,storeVersion:s}}async function ze(e,o,r,n){let t=await Z(e,o,n);m("deploying world");let s=await Ft(e,{chain:e.chain??null,address:t,abi:Et,functionName:"deployWorld",args:[r]});m("waiting for world deploy");let i=await Ht(e,{hash:s});if(i.status!=="success")throw console.error("world deploy failed",i),new Error("world deploy failed");let a=X(i.logs);return m("deployed world to",a.address,"at block",a.deployBlock),{...a,stateBlock:a.deployBlock}}import{resourceToLabel as ce,writeContract as qt}from"@latticexyz/common";import{valueSchemaToFieldLayoutHex as Yt,keySchemaToHex as Gt,valueSchemaToHex as Qt,getSchemaTypes as Ke,getValueSchema as Zt,getKeySchema as Xt}from"@latticexyz/protocol-parser/internal";import{parseAbiItem as zt,decodeAbiParameters as Ne,parseAbiParameters as Le}from"viem";import{hexToResource as Nt}from"@latticexyz/common";import{storeSetRecordEvent as Lt}from"@latticexyz/store";import{getLogs as Vt}from"viem/actions";import{decodeKey as Ut,decodeValueArgs as _t,getKeySchema as Kt,getSchemaTypes as Ve,getValueSchema as Jt,hexToSchema as Ue}from"@latticexyz/protocol-parser/internal";import le from"@latticexyz/store/mud.config";async function _e({client:e,worldDeploy:o}){m("looking up tables for",o.address);let n=(await Vt(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:zt(Lt),args:{tableId:le.namespaces.store.tables.Tables.tableId}})).map(t=>{let{tableId:s}=Ut(Ve(Kt(le.namespaces.store.tables.Tables)),t.args.keyTuple),{type:i,namespace:a,name:p}=Nt(s),d=_t(Ve(Jt(le.namespaces.store.tables.Tables)),t.args),l=Ue(d.keySchema),f=Ue(d.valueSchema),y=Ne(Le("string[]"),d.abiEncodedKeyNames)[0],h=Ne(Le("string[]"),d.abiEncodedFieldNames)[0],w=[...f.staticFields,...f.dynamicFields],u=Object.fromEntries(l.staticFields.map((g,A)=>[y[A],{type:g,internalType:g}])),C=Object.fromEntries(w.map((g,A)=>[h[A],{type:g,internalType:g}]));return{type:i,namespace:a,name:p,tableId:s,schema:{...u,...C},key:Object.keys(u)}});return m("found",n.length,"tables for",o.address),n}import er from"p-retry";import{wait as or}from"@latticexyz/common/utils";async function Je({client:e,worldDeploy:o,tables:r}){let t=(await _e({client:e,worldDeploy:o})).map(a=>a.tableId),s=r.filter(a=>t.includes(a.tableId));s.length&&m("existing tables:",s.map(ce).join(", "));let i=r.filter(a=>!t.includes(a.tableId));return i.length?(m("registering tables:",i.map(ce).join(", ")),await Promise.all(i.map(a=>{let p=Ke(Xt(a)),d=Ke(Zt(a));return er(()=>qt(e,{chain:e.chain??null,address:o.address,abi:S,functionName:"registerTable",args:[a.tableId,Yt(d),Gt(p),Qt(d),Object.keys(p),Object.keys(d)]}),{retries:3,onFailedAttempt:async l=>{let f=l.attemptNumber*500;m(`failed to register table ${ce(a)}, retrying in ${f}ms...`),await or(f)}})}))):[]}import{getAddress as O}from"viem";import{writeContract as me,resourceToLabel as N}from"@latticexyz/common";import{hexToResource as xr,resourceToLabel as Cr}from"@latticexyz/common";import{getFunctions as Sr}from"@latticexyz/world/internal";import{parseAbiItem as tr,HttpRequestError as rr}from"viem";import{getLogs as nr}from"viem/actions";import{storeSpliceStaticDataEvent as sr}from"@latticexyz/store";import ar from"p-retry";import ir from"@latticexyz/store/mud.config";async function ee({client:e,worldDeploy:o}){m("looking up resource IDs for",o.address);let n=(await ar(()=>nr(e,{strict:!0,address:o.address,fromBlock:o.deployBlock,toBlock:o.stateBlock,event:tr(sr),args:{tableId:ir.namespaces.store.tables.ResourceIds.tableId}}),{retries:3,onFailedAttempt:async t=>{if(!(t instanceof rr&&t.status===400&&t.message.includes("block is out of range")))throw t}})).map(t=>t.args.keyTuple[0]);return m("found",n.length,"resource IDs for",o.address),n}import{decodeValueArgs as dr,encodeKey as lr,getKeySchema as cr,getSchemaTypes as qe,getValueSchema as pr}from"@latticexyz/protocol-parser/internal";import{readContract as mr}from"viem/actions";async function M({client:e,worldDeploy:o,table:r,key:n}){let[t,s,i]=await mr(e,{blockNumber:o.stateBlock,address:o.address,abi:S,functionName:"getRecord",args:[r.tableId,lr(qe(cr(r)),n)]});return dr(qe(pr(r)),{staticData:t,encodedLengths:s,dynamicData:i})}import{parseAbiItem as fr,getAddress as yr}from"viem";import{storeSpliceStaticDataEvent as ur}from"@latticexyz/store";import{getLogs as gr}from"viem/actions";import{decodeKey as br,getKeySchema as hr,getSchemaTypes as wr}from"@latticexyz/protocol-parser/internal";import pe from"@latticexyz/world/mud.config";async function oe({client:e,worldDeploy:o}){m("looking up resource access for",o.address);let n=(await gr(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:fr(ur),args:{tableId:pe.namespaces.world.tables.ResourceAccess.tableId}})).map(s=>br(wr(hr(pe.namespaces.world.tables.ResourceAccess)),s.args.keyTuple)),t=(await Promise.all(n.map(async s=>[s,await M({client:e,worldDeploy:o,table:pe.namespaces.world.tables.ResourceAccess,key:s})]))).filter(([,s])=>s.access).map(([s])=>({resourceId:s.resourceId,address:yr(s.caller)}));return m("found",t.length,"resource<>address access pairs"),t}import Dr from"@latticexyz/world/mud.config";async function Ye({client:e,worldDeploy:o}){let[r,n,t]=await Promise.all([ee({client:e,worldDeploy:o}),Sr({client:e,worldAddress:o.address,fromBlock:o.deployBlock,toBlock:o.stateBlock}),oe({client:e,worldDeploy:o})]),s=r.map(xr).filter(i=>i.type==="system");return m("looking up systems:",s.map(Cr).join(", ")),await Promise.all(s.map(async i=>{let{system:a,publicAccess:p}=await M({client:e,worldDeploy:o,table:Dr.namespaces.world.tables.Systems,key:{systemId:i.resourceId}}),d=n.filter(l=>l.systemId===i.resourceId);return{address:a,namespace:i.namespace,name:i.name,systemId:i.resourceId,allowAll:p,allowedAddresses:t.filter(({resourceId:l})=>l===i.resourceId).map(({address:l})=>l),worldFunctions:d}}))}import{wait as fe}from"@latticexyz/common/utils";import ye from"p-retry";async function Ge({client:e,deployerAddress:o,libraries:r,worldDeploy:n,systems:t}){let[s,i]=await Promise.all([Ye({client:e,worldDeploy:n}),oe({client:e,worldDeploy:n})]),a=t.filter(c=>s.some(b=>b.systemId===c.systemId&&O(b.address)===O(c.prepareDeploy(o,r).address)));a.length&&m("existing systems:",a.map(N).join(", "));let p=a.map(c=>c.systemId),d=t.filter(c=>!p.includes(c.systemId));if(!d.length)return[];let l=d.filter(c=>s.some(b=>b.systemId===c.systemId&&O(b.address)!==O(c.prepareDeploy(o,r).address)));l.length&&m("upgrading systems:",l.map(N).join(", "));let f=d.filter(c=>!s.some(b=>b.systemId===c.systemId));f.length&&m("registering new systems:",f.map(N).join(", ")),await k({client:e,deployerAddress:o,contracts:d.map(c=>({bytecode:c.prepareDeploy(o,r).bytecode,deployedBytecodeSize:c.deployedBytecodeSize,debugLabel:`${N(c)} system`}))});let y=await Promise.all(d.map(c=>ye(()=>me(e,{chain:e.chain??null,address:n.address,abi:S,functionName:"registerSystem",args:[c.systemId,c.prepareDeploy(o,r).address,c.allowAll]}),{retries:3,onFailedAttempt:async b=>{let D=b.attemptNumber*500;m(`failed to register system ${N(c)}, retrying in ${D}ms...`),await fe(D)}}))),h=t.map(c=>c.systemId),w=i.filter(({resourceId:c})=>h.includes(c)),u=[...t.flatMap(c=>c.allowedAddresses.map(b=>({resourceId:c.systemId,address:b}))),...t.flatMap(c=>c.allowedSystemIds.map(b=>({resourceId:c.systemId,address:s.find(D=>D.systemId===b)?.address??t.find(D=>D.systemId===b)?.prepareDeploy(o,r).address})).filter(b=>b.address!=null))],C=u.filter(c=>!w.some(({resourceId:b,address:D})=>b===c.resourceId&&O(D)===O(c.address))),g=w.filter(c=>!u.some(({resourceId:b,address:D})=>b===c.resourceId&&O(D)===O(c.address)));g.length&&m("revoking",g.length,"access grants"),C.length&&m("adding",C.length,"access grants");let A=await Promise.all([...g.map(c=>ye(()=>me(e,{chain:e.chain??null,address:n.address,abi:S,functionName:"revokeAccess",args:[c.resourceId,c.address]}),{retries:3,onFailedAttempt:async b=>{let D=b.attemptNumber*500;m(`failed to revoke access, retrying in ${D}ms...`),await fe(D)}})),...C.map(c=>ye(()=>me(e,{chain:e.chain??null,address:n.address,abi:S,functionName:"grantAccess",args:[c.resourceId,c.address]}),{retries:3,onFailedAttempt:async b=>{let D=b.attemptNumber*500;m(`failed to grant access, retrying in ${D}ms...`),await fe(D)}}))]);return[...y,...A]}import{waitForTransactionReceipt as mo}from"viem/actions";import{getAddress as Ar,parseAbi as vr}from"viem";import{getBlockNumber as Tr,getLogs as kr}from"viem/actions";var Qe=new Map;async function Ze(e,o){let r=Ar(o),n=Qe.get(r);if(n!=null)return n;m("looking up world deploy for",r);let t=await Tr(e),s=await kr(e,{strict:!0,address:r,events:vr(q),fromBlock:"earliest",toBlock:t});return n={...X(s),stateBlock:t},Qe.set(r,n),m("found world deploy for",r,"at block",n.deployBlock),n}import{hexToResource as Pr,writeContract as Xe}from"@latticexyz/common";import{getFunctions as Mr}from"@latticexyz/world/internal";import eo from"p-retry";import{wait as oo}from"@latticexyz/common/utils";async function to({client:e,worldDeploy:o,functions:r}){let n=await Mr({client:e,worldAddress:o.address,fromBlock:o.deployBlock,toBlock:o.stateBlock}),t=Object.fromEntries(n.map(a=>[a.selector,a])),s=r.filter(a=>t[a.selector]),i=r.filter(a=>!s.includes(a));if(s.length){m("functions already registered:",s.map(p=>p.signature).join(", "));let a=s.filter(p=>p.systemId!==t[p.selector]?.systemId);a.length&&console.warn("found",a.length,"functions already registered but pointing at a different system ID:",a.map(p=>p.signature).join(", "))}return i.length?(m("registering functions:",i.map(a=>a.signature).join(", ")),Promise.all(i.map(a=>{let{namespace:p}=Pr(a.systemId);return p===""?eo(()=>Xe(e,{chain:e.chain??null,address:o.address,abi:S,functionName:"registerRootFunctionSelector",args:[a.systemId,a.systemFunctionSignature,a.systemFunctionSignature]}),{retries:3,onFailedAttempt:async d=>{let l=d.attemptNumber*500;m(`failed to register function ${a.signature}, retrying in ${l}ms...`),await oo(l)}}):eo(()=>Xe(e,{chain:e.chain??null,address:o.address,abi:S,functionName:"registerFunctionSelector",args:[a.systemId,a.systemFunctionSignature]}),{retries:3,onFailedAttempt:async d=>{let l=d.attemptNumber*500;m(`failed to register function ${a.signature}, retrying in ${l}ms...`),await oo(l)}})}))):[]}import{BaseError as ro}from"viem";import{writeContract as no}from"@latticexyz/common";import{isDefined as Or,wait as Br}from"@latticexyz/common/utils";import Ir from"p-retry";async function so({client:e,deployerAddress:o,libraries:r,worldDeploy:n,modules:t}){return t.length?(await k({client:e,deployerAddress:o,contracts:t.map(s=>({bytecode:s.prepareDeploy(o,r).bytecode,deployedBytecodeSize:s.deployedBytecodeSize,debugLabel:`${s.name} module`}))}),m("installing modules:",t.map(s=>s.name).join(", ")),(await Promise.all(t.map(s=>Ir(async()=>{try{let i=[...S,...s.abi],a=s.prepareDeploy(o,r).address;return s.installAsRoot?await no(e,{chain:e.chain??null,address:n.address,abi:i,functionName:"installRootModule",args:[a,s.installData]}):await no(e,{chain:e.chain??null,address:n.address,abi:i,functionName:"installModule",args:[a,s.installData]})}catch(i){if(s.optional){m(`optional module ${s.name} install failed, skipping
|
14
|
+
${i instanceof ro?i.shortMessage:i}`);return}if(i instanceof ro&&i.message.includes("Module_AlreadyInstalled")){m(`module ${s.name} already installed`);return}throw i}},{retries:3,onFailedAttempt:async i=>{let a=i.attemptNumber*500;m(`failed to install module ${s.name}, retrying in ${a}ms...`),await Br(a)}})))).filter(Or)):[]}import{getAddress as ao}from"viem";import{hexToResource as io,resourceToHex as lo,writeContract as Wr}from"@latticexyz/common";import Rr from"@latticexyz/world/mud.config";async function co({client:e,worldDeploy:o,resourceIds:r}){let n=Array.from(new Set(r.map(f=>io(f).namespace))),t=await ee({client:e,worldDeploy:o}),s=new Set(t.map(f=>io(f).namespace));s.size&&m("found",s.size,"existing namespaces:",Array.from(s).map(f=>f===""?"<root>":f).join(", "));let i=n.filter(f=>s.has(f)),p=(await Promise.all(i.map(async f=>{let{owner:y}=await M({client:e,worldDeploy:o,table:Rr.namespaces.world.tables.NamespaceOwner,key:{namespaceId:lo({type:"namespace",namespace:f,name:""})}});return[f,y]}))).filter(([,f])=>ao(f)!==ao(e.account.address)).map(([f])=>f);if(p.length)throw new Error(`You are attempting to deploy to namespaces you do not own: ${p.join(", ")}`);let d=n.filter(f=>!s.has(f));return d.length>0&&m("registering namespaces:",Array.from(d).join(", ")),Promise.all(d.map(f=>Wr(e,{chain:e.chain??null,address:o.address,abi:S,functionName:"registerNamespace",args:[lo({namespace:f,type:"namespace",name:""})]})))}import{resourceToLabel as Lr}from"@latticexyz/common";import{randomBytes as Vr}from"crypto";import{stringToHex as ue,BaseError as jr,hexToString as $r}from"viem";import{hexToResource as Hr,writeContract as Er}from"@latticexyz/common";import{isDefined as Fr}from"@latticexyz/common/utils";import zr from"@latticexyz/world-module-metadata/mud.config";import Nr from"@latticexyz/world-module-metadata/out/IMetadataSystem.sol/IMetadataSystem.abi.json"assert{type:"json"};async function po({client:e,worldDeploy:o,resources:r}){let n=await Promise.all(r.map(async s=>{let{value:i}=await M({client:e,worldDeploy:o,table:zr.tables.metadata__ResourceTag,key:{resource:s.resourceId,tag:ue("label",{size:32})}});return $r(i)})),t=r.filter((s,i)=>s.label!==n[i]);return t.length===0?[]:(m(`setting ${r.length} resource labels`),(await Promise.all(t.map(async({resourceId:s,label:i})=>{let a=Hr(s),p=`${a.type}:${a.namespace}:${a.name}`;m(`setting resource label for ${p} to ${i}`);try{return await Er(e,{chain:e.chain??null,address:o.address,abi:Nr,functionName:"metadata__setResourceTag",args:[s,ue("label",{size:32}),ue(i)]})}catch(d){m(`failed to set resource label for ${p}, skipping
|
15
|
+
${d instanceof jr?d.shortMessage:d}`)}}))).filter(Fr))}async function fo({client:e,tables:o,systems:r,libraries:n,modules:t=[],salt:s,worldAddress:i,deployerAddress:a,withWorldProxy:p}){let d=a??await Pe(e);await Z(e,d,p),await k({client:e,deployerAddress:d,contracts:[...n.map(c=>({bytecode:c.prepareDeploy(d,n).bytecode,deployedBytecodeSize:c.deployedBytecodeSize,debugLabel:`${c.path}:${c.name} library`})),...r.map(c=>({bytecode:c.prepareDeploy(d,n).bytecode,deployedBytecodeSize:c.deployedBytecodeSize,debugLabel:`${Lr(c)} system`})),...t.map(c=>({bytecode:c.prepareDeploy(d,n).bytecode,deployedBytecodeSize:c.deployedBytecodeSize,debugLabel:`${c.name} module`}))]});let l=i?await Ze(e,i):await ze(e,d,s??`0x${Vr(32).toString("hex")}`,p);if(!Me.includes(l.storeVersion))throw new Error(`Unsupported Store version: ${l.storeVersion}`);if(!Oe.includes(l.worldVersion))throw new Error(`Unsupported World version: ${l.worldVersion}`);let f=[...o.map(c=>({resourceId:c.tableId,label:c.label})),...r.map(c=>({resourceId:c.systemId,label:c.label}))],y=await co({client:e,worldDeploy:l,resourceIds:f.map(({resourceId:c})=>c)});m("waiting for all namespace registration transactions to confirm");for(let c of y)await mo(e,{hash:c});let h=await Je({client:e,worldDeploy:l,tables:o}),w=await Ge({client:e,deployerAddress:d,libraries:n,worldDeploy:l,systems:r}),u=await to({client:e,worldDeploy:l,functions:r.flatMap(c=>c.worldFunctions)}),C=await so({client:e,deployerAddress:d,libraries:n,worldDeploy:l,modules:t}),g=await po({client:e,worldDeploy:l,resources:f}),A=[...h,...w,...u,...C,...g];m("waiting for all transactions to confirm");for(let c of A)await mo(e,{hash:c});return m("deploy complete"),l}import{createWalletClient as Cn,http as Sn,isHex as Dn}from"viem";import{privateKeyToAccount as An}from"viem/accounts";import{loadConfig as vn,resolveConfigPath as Tn}from"@latticexyz/config/node";import{getOutDirectory as kn,getRpcUrl as Pn}from"@latticexyz/common/foundry";import j from"chalk";import{MUDError as be}from"@latticexyz/common/errors";import Zr from"path";import{resolveSystems as Xr}from"@latticexyz/world/node";import{isHex as go,toFunctionSelector as bo,toFunctionSignature as ho}from"viem";import{readFileSync as Ur}from"fs";import _r from"path";import{MUDError as re}from"@latticexyz/common/errors";import{size as Kr}from"viem";function te(e){return Object.entries(e).flatMap(([o,r])=>Object.entries(r).flatMap(([n,t])=>t.map(s=>({path:o,name:n,start:s.start,length:s.length}))))}function W(e,o,r){let n,t=_r.join(r,e,o+".json");try{n=JSON.parse(Ur(t,"utf8"))}catch{throw new re(`Error reading file at ${t}`)}let s=n?.bytecode?.object;if(!s)throw new re(`No bytecode found in ${t}`);let i=n?.deployedBytecode?.object;if(!i)throw new re(`No deployed bytecode found in ${t}`);let a=n?.abi;if(!a)throw new re(`No ABI found in ${t}`);let p=te(n?.bytecode?.linkReferences??{});return{abi:a,bytecode:s,placeholders:p,deployedBytecodeSize:Kr(i)}}import{groupBy as en}from"@latticexyz/common/utils";import{readFileSync as qr}from"fs";import{globSync as Yr}from"glob";import Jr from"toposort";function yo(e,o,r){let n=Jr(e.flatMap(t=>r(t).map(s=>[o(t),s])));return[...e].sort((t,s)=>n.indexOf(o(t))-n.indexOf(o(s)))}function uo(e){let r=Yr(`${e}/**/*.json`,{ignore:"**/*.abi.json"}).sort().map(n=>JSON.parse(qr(n,"utf8"))).flatMap(n=>{if(!n.metadata)return[];let t=Object.keys(n.metadata.settings.compilationTarget)[0],s=n.metadata.settings.compilationTarget[t],i=n.bytecode.linkReferences;return Object.entries(i).flatMap(([a,p])=>Object.keys(p).map(d=>({path:a,name:d,dependentPath:t,dependentName:s})))});return yo(r,n=>`${n.path}:${n.name}`,n=>[`${n.dependentPath}:${n.dependentName}`])}import{spliceHex as Gr}from"@latticexyz/common";import{getCreate2Address as Qr}from"viem";function R(e,o){return function(n,t){let s=e;for(let i of o){let a=t.find(p=>p.path===i.path&&p.name===i.name);if(!a)throw new Error(`Could not find library for bytecode placeholder ${i.path}:${i.name}`);s=Gr(s,i.start,i.length,a.prepareDeploy(n,t).address)}return{bytecode:s,address:Qr({from:n,bytecode:s,salt:x})}}}async function wo({rootDir:e,config:o,forgeOutDir:r}){let n=uo(r).map(l=>{let f=W(Zr.basename(l.path),l.name,r);return{path:l.path,name:l.name,abi:f.abi,prepareDeploy:R(f.bytecode,f.placeholders),deployedBytecodeSize:f.deployedBytecodeSize}}),s=W("System.sol","System",r).abi.filter(l=>l.type==="function").map(ho),i=await Xr({rootDir:e,config:o}),a=i.filter(l=>!l.deploy.disabled).map(l=>{let f=W(`${l.label}.sol`,l.label,r),y=l.deploy.registerWorldFunctions?f.abi.filter(u=>u.type==="function").map(ho).filter(u=>!s.includes(u)).map(u=>{let C=l.namespace===""?u:`${l.namespace}__${u}`;return{signature:C,selector:bo(C),systemId:l.systemId,systemFunctionSignature:u,systemFunctionSelector:bo(u)}}):[],h=l.accessList.filter(u=>go(u)),w=l.accessList.filter(u=>!go(u)).map(u=>i.find(g=>g.label===u).systemId);return{...l,allowAll:l.openAccess,allowedAddresses:h,allowedSystemIds:w,prepareDeploy:R(f.bytecode,f.placeholders),deployedBytecodeSize:f.deployedBytecodeSize,abi:f.abi,worldFunctions:y}}),p=en(a,l=>l.systemId),d=Array.from(p.values()).filter(l=>l.length>1).flat();if(d.length){let l=d.map(f=>f.name);throw new Error(`Found systems with overlapping system ID: ${l.join(", ")}.
|
16
|
+
|
17
|
+
System IDs are generated from the first 16 bytes of the name, so you may need to rename them to avoid the overlap.`)}return{systems:a,libraries:n}}import{getChainId as Mn}from"viem/actions";import{existsSync as on}from"fs";import tn from"path";import rn from"chalk";import{getScriptDirectory as nn,forge as sn}from"@latticexyz/common/foundry";async function xo(e,o,r,n,t,s){let i=t?.replaceAll("\\","").split(" ")??[],a=tn.join(await nn(),e+".s.sol");if(!on(a)){console.log(`No script at ${a}, skipping post deploy hook`);return}console.log(rn.blue(`Executing post deploy script at ${a}`)),await sn(["script",e,"--broadcast","--sig","run(address)",o,"--rpc-url",r,"-vvv",s?"--aws":"",...i],{profile:n})}import{kmsKeyToAccount as On}from"@latticexyz/common/kms";import Do from"node:path";import{encodeField as fn}from"@latticexyz/protocol-parser/internal";import{bytesToHex as yn}from"viem";import{isHex as an,size as dn}from"viem";import{z as P}from"zod";import{Abi as ln}from"abitype/zod";var Co=P.object({object:P.string().refine(an),linkReferences:P.record(P.record(P.array(P.object({start:P.number(),length:P.number()}))))}),cn=P.object({bytecode:Co,deployedBytecode:Co,abi:ln});function ne(e){let o=cn.parse(e),r=te(o.bytecode.linkReferences);return{abi:o.abi,bytecode:o.bytecode.object,placeholders:r,deployedBytecodeSize:dn(o.deployedBytecode.object)}}import{createRequire as pn}from"node:module";import{findUp as mn}from"find-up";async function So({packageJsonPath:e,artifactPath:o}){let r;try{let n=e??await mn("package.json",{cwd:process.cwd()});if(!n)throw new Error("Could not find package.json to import relative to.");r=pn(n)(o)}catch(n){throw console.error(),console.error("Could not import contract artifact at",o),console.error(),n}return ne(r)}import{resolveWithContext as un}from"@latticexyz/world/internal";import gn from"@latticexyz/world-module-metadata/out/MetadataModule.sol/MetadataModule.json"assert{type:"json"};var bn={KeysWithValueModule:"@latticexyz/world-modules/out/KeysWithValueModule.sol/KeysWithValueModule.json",KeysInTableModule:"@latticexyz/world-modules/out/KeysInTableModule.sol/KeysInTableModule.json",UniqueEntityModule:"@latticexyz/world-modules/out/UniqueEntityModule.sol/UniqueEntityModule.json",Unstable_CallWithSignatureModule:"@latticexyz/world-modules/out/Unstable_CallWithSignatureModule.sol/Unstable_CallWithSignatureModule.json"},se=ne(gn);async function ae(e,o){let r=[{optional:!0,name:"MetadataModule",installAsRoot:!1,installData:"0x",prepareDeploy:R(se.bytecode,se.placeholders),deployedBytecodeSize:se.deployedBytecodeSize,abi:se.abi}],n=await Promise.all(e.modules.map(async t=>{let s=t.artifactPath;if(!s)if(t.name)s=bn[t.name]??Do.join(o,`${t.name}.sol`,`${t.name}.json`),console.warn(["","\u26A0\uFE0F Your `mud.config.ts` is using a module with a `name`, but this option is deprecated.","","To resolve this, you can replace this:","",` name: ${JSON.stringify(t.name)}`,"","with this:","",` artifactPath: ${JSON.stringify(s)}`,""].join(`
|
18
|
+
`));else throw new Error("No `artifactPath` provided for module.");let i=Do.basename(s,".json"),a=await So({artifactPath:s}),p=t.args.map(d=>un(d,{config:e})).map(d=>{let l=d.value instanceof Uint8Array?yn(d.value):d.value;return fn(d.type,l)});if(p.length>1)throw new Error(`${i} module should only have 0-1 args, but had ${p.length} args.`);return{name:i,installAsRoot:t.root,installData:p.length===0?"0x":p[0],prepareDeploy:R(a.bytecode,a.placeholders),deployedBytecodeSize:a.deployedBytecodeSize,abi:a.abi}}));return[...r,...n]}var T={configPath:{type:"string",desc:"Path to the MUD config file"},printConfig:{type:"boolean",desc:"Print the resolved config"},profile:{type:"string",desc:"The foundry profile to use"},saveDeployment:{type:"boolean",desc:"Save the deployment info to a file",default:!0},rpc:{type:"string",desc:"The RPC URL to use. Defaults to the RPC url from the local foundry.toml"},rpcBatch:{type:"boolean",desc:"Enable batch processing of RPC requests in viem client (defaults to batch size of 100 and wait of 1s)"},deployerAddress:{type:"string",desc:"Deploy using an existing deterministic deployer (https://github.com/Arachnid/deterministic-deployment-proxy)"},worldAddress:{type:"string",desc:"Deploy to an existing World at the given address"},skipBuild:{type:"boolean",desc:"Skip rebuilding the contracts before deploying"},alwaysRunPostDeploy:{type:"boolean",desc:"Always run PostDeploy.s.sol after each deploy (including during upgrades). By default, PostDeploy.s.sol is only run once after a new world is deployed."},forgeScriptOptions:{type:"string",description:"Options to pass to forge script PostDeploy.s.sol"},salt:{type:"string",desc:"The deployment salt to use. Defaults to a random salt."},kms:{type:"boolean",desc:"Deploy the World with an AWS KMS key instead of local private key."}};async function $(e){let o=e.salt;if(o!=null&&!Dn(o))throw new be("Expected hex string for salt");let r=e.profile??process.env.FOUNDRY_PROFILE,n=await Tn(e.configPath),t=await vn(n),s=ie.dirname(n);e.printConfig&&console.log(j.green(`
|
19
|
+
Resolved config:
|
20
|
+
`),JSON.stringify(t,null,2));let i=await kn(r),a=e.rpc??await Pn(r);console.log(j.bgBlue(j.whiteBright(`
|
21
|
+
Deploying MUD contracts${r?" with profile "+r:""} to RPC ${a}
|
22
|
+
`))),e.skipBuild||await U({rootDir:s,config:t,foundryProfile:r});let{systems:p,libraries:d}=await wo({rootDir:s,config:t,forgeOutDir:i}),l=await ae(t,i),f=await(async()=>{if(e.kms){let g=process.env.AWS_KMS_KEY_ID;if(!g)throw new be("Missing `AWS_KMS_KEY_ID` environment variable. This is required when using with `--kms` option.");return await On({keyId:g})}else{let g=process.env.PRIVATE_KEY;if(!g)throw new be(`Missing PRIVATE_KEY environment variable.
|
23
|
+
Run 'echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env'
|
24
|
+
in your contracts directory to use the default anvil private key.`);return An(g)}})(),y=Cn({transport:Sn(a,{batch:e.rpcBatch?{batchSize:100,wait:1e3}:void 0}),account:f});console.log("Deploying from",y.account.address);let h=Object.values(t.namespaces).flatMap(g=>Object.values(g.tables)).filter(g=>!g.deploy.disabled),w=Date.now(),u=await fo({deployerAddress:e.deployerAddress,salt:o,worldAddress:e.worldAddress,client:y,tables:h,systems:p,libraries:d,modules:l,withWorldProxy:t.deploy.upgradeableWorldImplementation});(e.worldAddress==null||e.alwaysRunPostDeploy)&&await xo(t.deploy.postDeployScript,u.address,a,r,e.forgeScriptOptions,!!e.kms),console.log(j.green("Deployment completed in",(Date.now()-w)/1e3,"seconds"));let C={worldAddress:u.address,blockNumber:Number(u.deployBlock)};if(e.saveDeployment){let g=await Mn(y),A=ie.join(t.deploy.deploysDirectory,g.toString());wn(A,{recursive:!0}),ge(ie.join(A,"latest.json"),JSON.stringify(C,null,2)),ge(ie.join(A,Date.now()+".json"),JSON.stringify(C,null,2));let c=[1337,31337],b=hn(t.deploy.worldsFile)?JSON.parse(xn(t.deploy.worldsFile,"utf-8")):{};b[g]={address:C.worldAddress,blockNumber:c.includes(g)?void 0:C.blockNumber},ge(t.deploy.worldsFile,JSON.stringify(b,null,2)),console.log(j.bgGreen(j.whiteBright(`
|
25
|
+
Deployment result (written to ${t.deploy.worldsFile} and ${A}):
|
26
|
+
`)))}return console.log(C),u}var Bn={command:"deploy",describe:"Deploy MUD contracts",builder(e){return e.options(T)},async handler(e){try{await $(e)}catch(o){V(o),process.exit(1)}process.exit(0)}},Ao=Bn;import In from"node:path";import{loadConfig as Wn,resolveConfigPath as Rn}from"@latticexyz/config/node";import{worldgen as jn}from"@latticexyz/world/node";var $n={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 MUD config file"},clean:{type:"boolean",desc:"Clear the worldgen directory before generating new interfaces (defaults to true)",default:!0}})},async handler(e){await Hn(e),process.exit(0)}};async function Hn(e){let o=await Rn(e.configPath),r=await Wn(o),n=In.dirname(o);await jn({rootDir:n,config:r,clean:e.clean})}var vo=$n;import L from"chalk";import{readFileSync as Ln,writeFileSync as Vn}from"fs";import we from"path";import{MUDError as H}from"@latticexyz/common/errors";var To={name:"@latticexyz/cli",version:"2.1.0",description:"Command line interface for mud",repository:{type:"git",url:"https://github.com/latticexyz/mud.git",directory:"packages/cli"},license:"MIT",type:"module",exports:{".":"./dist/index.js"},typesVersions:{"*":{index:["./dist/index.d.ts"]}},bin:{mud:"./dist/mud.js"},files:["dist"],scripts:{build:"pnpm run build:js && pnpm run build:test-tables","build:js":"tsup && chmod +x ./dist/mud.js","build:test-tables":"tsx ./scripts/generate-test-tables.ts",clean:"pnpm run clean:js && pnpm run clean:test-tables","clean:js":"rimraf dist","clean:test-tables":"rimraf src/codegen",dev:"tsup --watch",lint:"eslint . --ext .ts",prepare:"mkdir -p ./dist && touch ./dist/mud.js",test:"tsc --noEmit && forge test","test:ci":"pnpm run test"},dependencies:{"@aws-sdk/client-kms":"^3.556.0","@latticexyz/abi-ts":"workspace:*","@latticexyz/common":"workspace:*","@latticexyz/config":"workspace:*","@latticexyz/gas-report":"workspace:*","@latticexyz/protocol-parser":"workspace:*","@latticexyz/schema-type":"workspace:*","@latticexyz/store":"workspace:*","@latticexyz/utils":"workspace:*","@latticexyz/world":"workspace:*","@latticexyz/world-module-metadata":"workspace:*",abitype:"1.0.0","asn1.js":"^5.4.1",chalk:"^5.0.1",chokidar:"^3.5.3",debug:"^4.3.4",dotenv:"^16.0.3",execa:"^7.0.0","find-up":"^6.3.0",glob:"^10.4.2",openurl:"^1.1.1","p-queue":"^7.4.1","p-retry":"^5.1.2",path:"^0.12.7",rxjs:"7.5.5","throttle-debounce":"^5.0.0",toposort:"^2.0.2",typescript:"5.4.2",viem:"2.9.20",yargs:"^17.7.1",zod:"3.23.8","zod-validation-error":"^1.3.0"},devDependencies:{"@types/debug":"^4.1.7","@types/ejs":"^3.1.1","@types/node":"^18.15.11","@types/openurl":"^1.0.0","@types/throttle-debounce":"^5.0.0","@types/toposort":"^2.0.6","@types/yargs":"^17.0.10","ds-test":"https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0","forge-std":"https://github.com/foundry-rs/forge-std.git#74cfb77e308dd188d2f58864aaf44963ae6b88b1",tsup:"^6.7.0",tsx:"^3.12.6",vitest:"0.34.6"}};import{globSync as Un}from"glob";import{ZodError as Fn,z as ko}from"zod";var zn=ko.object({MUD_PACKAGES:ko.string().transform(e=>JSON.parse(e))});function Nn(){try{return zn.parse({MUD_PACKAGES:'{"@latticexyz/abi-ts":{"localPath":"packages/abi-ts"},"@latticexyz/block-logs-stream":{"localPath":"packages/block-logs-stream"},"@latticexyz/cli":{"localPath":"packages/cli"},"@latticexyz/common":{"localPath":"packages/common"},"@latticexyz/config":{"localPath":"packages/config"},"create-mud":{"localPath":"packages/create-mud"},"@latticexyz/dev-tools":{"localPath":"packages/dev-tools"},"@latticexyz/faucet":{"localPath":"packages/faucet"},"@latticexyz/gas-report":{"localPath":"packages/gas-report"},"@latticexyz/protocol-parser":{"localPath":"packages/protocol-parser"},"@latticexyz/query":{"localPath":"packages/query"},"@latticexyz/react":{"localPath":"packages/react"},"@latticexyz/recs":{"localPath":"packages/recs"},"@latticexyz/schema-type":{"localPath":"packages/schema-type"},"solhint-config-mud":{"localPath":"packages/solhint-config-mud"},"solhint-plugin-mud":{"localPath":"packages/solhint-plugin-mud"},"@latticexyz/store-indexer":{"localPath":"packages/store-indexer"},"@latticexyz/store-sync":{"localPath":"packages/store-sync"},"@latticexyz/store":{"localPath":"packages/store"},"@latticexyz/utils":{"localPath":"packages/utils"},"@latticexyz/world-module-metadata":{"localPath":"packages/world-module-metadata"},"@latticexyz/world-modules":{"localPath":"packages/world-modules"},"@latticexyz/world":{"localPath":"packages/world"}}'})}catch(e){if(e instanceof Fn){let{...o}=e.format();console.error(`
|
27
|
+
Missing or invalid environment variables:
|
28
|
+
|
29
|
+
${Object.keys(o).join(`
|
30
|
+
`)}
|
31
|
+
`),process.exit(1)}throw e}}var he=Nn().MUD_PACKAGES;var _n={command:"set-version",describe:"Set MUD version in all package.json files and optionally backup the previously installed version",builder(e){return e.options({mudVersion:{alias:"v",type:"string",description:"Set MUD to the given version"},tag:{alias:"t",type:"string",description:"Set MUD to the latest version with the given tag from npm"},commit:{alias:"c",type:"string",description:"Set MUD to the version based on a given git commit hash from npm"},link:{alias:"l",type:"string",description:"Relative path to the local MUD root directory to link"}})},async handler(e){try{let o=["mudVersion","link","tag","commit","restore"],r=o.reduce((t,s)=>e[s]?t+1:t,0);if(r===0)throw new H(`You need to provide one these options: ${o.join(", ")}`);if(r>1)throw new H(`These options are mutually exclusive: ${o.join(", ")}`);e.link||(e.mudVersion=await Kn(e));let n=Un("**/package.json").sort().filter(t=>!t.includes("node_modules"));for(let t of n)Jn(t,e)}catch(o){V(o)}finally{process.exit(0)}}};async function Kn(e){e.mudVersion==="canary"&&(e.tag="main");let o;try{console.log(L.blue("Fetching available versions")),o=await(await fetch(`https://registry.npmjs.org/${To.name}`)).json()}catch{throw new H("Could not fetch available MUD versions")}if(e.tag){let r=o["dist-tags"][e.tag];if(!r)throw new H(`Could not find npm version with tag "${e.tag}"`);return console.log(L.green(`Latest version with tag ${e.tag}: ${r}`)),r}if(e.commit){let r=e.commit.substring(0,8),n=Object.keys(o.versions).find(t=>t.includes(r));if(!n)throw new H(`Could not find npm version based on commit "${e.commit}"`);return console.log(L.green(`Version from commit ${e.commit}: ${n}`)),n}return e.mudVersion}function Jn(e,o){let{link:r}=o,{mudVersion:n}=o,t=qn(e),s=Object.keys(he),i={};for(let d in t.dependencies)s.includes(d)&&(i[d]=t.dependencies[d]);let a={};for(let d in t.devDependencies)s.includes(d)&&(a[d]=t.devDependencies[d]);for(let d in t.dependencies)s.includes(d)&&(t.dependencies[d]=p(d,"dependencies"));for(let d in t.devDependencies)s.includes(d)&&(t.devDependencies[d]=p(d,"devDependencies"));return Vn(e,JSON.stringify(t,null,2)+`
|
32
|
+
`),console.log(`Updating ${e}`),Po(i,t.dependencies),Po(a,t.devDependencies),t;function p(d,l){return r&&(n=Yn(e,r,d)),n||t[l][d]}}function qn(e){try{let o=Ln(e,"utf8");return JSON.parse(o)}catch{throw new H("Could not read JSON at "+e)}}function Po(e,o){for(let r in e)e[r]!==o[r]&&console.log(`${r}: ${L.red(e[r])} -> ${L.green(o[r])}`)}function Yn(e,o,r){let n=we.relative(we.dirname(e),process.cwd());return"link:"+we.join(n,o,he[r].localPath)}var Mo=_n;import{anvil as Gn,forge as Qn,getRpcUrl as Zn}from"@latticexyz/common/foundry";import Xn from"chalk";var es={...T,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"}},os={command:"test",describe:"Run tests in MUD contracts",builder(e){return e.options(es)},async handler(e){if(!e.worldAddress){let t=["--block-base-fee-per-gas","0","--port",String(e.port)];Gn(t)}let o=e.worldAddress?await Zn(e.profile):`http://127.0.0.1:${e.port}`,r=e.worldAddress??(await $({...e,saveDeployment:!1,rpc:o})).address;console.log(Xn.blue("World address",r));let n=e.forgeOptions?.replaceAll("\\","").split(" ")??[];try{await Qn(["test","--fork-url",o,...n],{profile:e.profile,env:{WORLD_ADDRESS:r}}),process.exit(0)}catch(t){console.error(t),process.exit(1)}}},Oo=os;import ts from"node:path";import Bo from"node:fs";import{loadConfig as rs,resolveConfigPath as ns}from"@latticexyz/config/node";import{MUDError as Io}from"@latticexyz/common/errors";import{cast as ss,getRpcUrl as as}from"@latticexyz/common/foundry";import is from"@latticexyz/world/mud.config";import{createClient as ds,http as ls}from"viem";import{getChainId as cs,readContract as ps}from"viem/actions";import{resolveSystems as ms}from"@latticexyz/world/node";var fs=is.namespaces.world.tables.Systems.tableId;function ys(e,o){if(!Bo.existsSync(e))throw new Io(`Missing expected worlds.json file at "${e}"`);let r=JSON.parse(Bo.readFileSync(e,"utf-8"));if(!r[o])throw new Io(`Missing chain ID ${o} in "${e}"`);return r[o].address}var us={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 MUD config file"},profile:{type:"string",description:"The foundry profile to use"},rpc:{type:"string",description:"json rpc endpoint. Defaults to foundry's configured eth_rpc_url"}})},async handler(e){let o=await ns(e.configPath),r=ts.dirname(o),n=e.profile??process.env.FOUNDRY_PROFILE,t=e.rpc??await as(n),s=await rs(o),i=ds({transport:ls(t)}),a=await cs(i),p=e.worldAddress??ys(s.deploy.worldsFile,a),d=await ms({rootDir:r,config:s}),l=await Promise.all(d.map(async y=>({label:y.label,address:await ps(i,{abi:S,address:p,functionName:"getField",args:[fs,[y.systemId],0]})}))),f=await ss(["run","--label",`${p}:World`,...l.map(({label:y,address:h})=>["--label",`${h}:${y}`]).flat(),`${e.tx}`]);console.log(f),process.exit(0)}},Wo=us;import{anvil as gs,getScriptDirectory as bs,getSrcDirectory as hs}from"@latticexyz/common/foundry";import B from"chalk";import ws from"chokidar";import{loadConfig as xs,resolveConfigPath as Cs}from"@latticexyz/config/node";import Ss from"path";import{homedir as Ds}from"os";import{rmSync as As}from"fs";import{BehaviorSubject as vs,debounceTime as Ts,exhaustMap as ks,filter as Ps}from"rxjs";import{isDefined as Ms}from"@latticexyz/common/utils";var Os={rpc:T.rpc,configPath:T.configPath,alwaysRunPostDeploy:T.alwaysRunPostDeploy,forgeScriptOptions:T.forgeScriptOptions,worldAddress:T.worldAddress},Bs={command:"dev-contracts",describe:"Start a development server for MUD contracts",builder(e){return e.options(Os)},async handler(e){let o=e.rpc,r=e.configPath??await Cs(e.configPath),n=await hs(),t=await bs(),s=await xs(r);if(!e.rpc){console.log(B.gray("Cleaning devnode cache"));let d=Ds();As(Ss.join(d,".foundry","anvil","tmp"),{recursive:!0,force:!0}),gs(["--block-time","1","--block-base-fee-per-gas","0"]),o="http://127.0.0.1:8545"}let i=new vs(Date.now());ws.watch([r,n,t],{ignoreInitial:!0}).on("all",async(d,l)=>{l.includes(r)&&(console.log(B.blue("Config changed, queuing deploy\u2026")),i.next(Date.now())),(l.includes(n)||l.includes(t))&&(l.includes(s.codegen.outputDirectory)||(console.log(B.blue("Contracts changed, queuing deploy\u2026")),i.next(Date.now())))});let a=e.worldAddress;i.pipe(Ts(200),ks(async d=>{a&&console.log(B.blue("Rebuilding and upgrading world\u2026"));try{let l=await $({...e,configPath:r,rpc:o,rpcBatch:!1,skipBuild:!1,printConfig:!1,profile:void 0,saveDeployment:!0,deployerAddress:void 0,worldAddress:a,salt:"0x",kms:void 0});return a=l.address,d<i.value?i.next(i.value):console.log(B.gray(`
|
33
|
+
Waiting for file changes\u2026
|
34
|
+
`)),l}catch(l){console.error(B.bgRed(B.whiteBright(`
|
35
|
+
Error while attempting deploy
|
36
|
+
`))),console.error(l),console.log(B.gray(`
|
37
|
+
Waiting for file changes\u2026
|
38
|
+
`))}}),Ps(Ms)).subscribe()}},Ro=Bs;import{getCreate2Address as jo,sliceHex as Ws,zeroHash as Rs}from"viem";import{forge as Is}from"@latticexyz/common/foundry";async function I(e){let o=["verify-contract",e.address,e.name,"--rpc-url",e.rpc];e.verifier&&o.push("--verifier",e.verifier),e.verifierUrl&&o.push("--verifier-url",e.verifierUrl),await Is(o,{cwd:e.cwd})}import js from"p-queue";import{MUDError as $s}from"@latticexyz/common/errors";import{getStorageAt as Hs}from"viem/actions";import{execa as xe}from"execa";var Es="0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";async function $o({client:e,rpc:o,systems:r,modules:n,worldAddress:t,deployerAddress:s,verifier:i,verifierUrl:a}){let p=s??await J(e);if(!p)throw new $s("No deployer address provided or found.");let d=await Hs(e,{address:t,slot:Es}),l=d&&d!==Rs,f=new js({concurrency:4});if(r.map(({name:y,bytecode:h})=>f.add(()=>I({name:y,rpc:o,verifier:i,verifierUrl:a,address:jo({from:p,bytecode:h,salt:x})}).catch(w=>{console.error(`Error verifying system contract ${y}:`,w)}))),i==="sourcify")if(await xe("npm",["install"],{cwd:"node_modules/@latticexyz/store"}),await xe("npm",["install"],{cwd:"node_modules/@latticexyz/world"}),await xe("npm",["install"],{cwd:"node_modules/@latticexyz/world-modules"}),Object.entries(l?Q(p):G(p)).map(([y,{bytecode:h}])=>f.add(()=>I({cwd:"node_modules/@latticexyz/world",name:y,rpc:o,verifier:i,verifierUrl:a,address:jo({from:p,bytecode:h,salt:x})}).catch(w=>{console.error(`Error verifying world factory contract ${y}:`,w)}))),n.map(({name:y,prepareDeploy:h})=>{let{address:w}=h(p,[]);return f.add(()=>I({cwd:"node_modules/@latticexyz/world-modules",name:y,rpc:o,verifier:i,verifierUrl:a,address:w}).catch(u=>{console.error(`Error verifying module contract ${y}:`,u)}))}),l){let y=Ws(d,-20);f.add(()=>I({cwd:"node_modules/@latticexyz/world",name:"WorldProxy",rpc:o,verifier:i,verifierUrl:a,address:t}).catch(h=>{console.error("Error verifying WorldProxy contract:",h)})),f.add(()=>I({cwd:"node_modules/@latticexyz/world",name:"World",rpc:o,verifier:i,verifierUrl:a,address:y}).catch(h=>{console.error("Error verifying World contract:",h)}))}else f.add(()=>I({cwd:"node_modules/@latticexyz/world",name:"World",rpc:o,verifier:i,verifierUrl:a,address:t}).catch(y=>{console.error("Error verifying World contract:",y)}));else console.log(""),console.log(`Note: MUD is currently unable to verify store, world, and world-modules contracts with ${i}. We are planning to expand support in a future version.`),console.log("")}import{loadConfig as Fs,resolveConfigPath as zs}from"@latticexyz/config/node";import{resolveSystems as Ns}from"@latticexyz/world/node";import{getOutDirectory as Ls,getRpcUrl as Vs}from"@latticexyz/common/foundry";import{createWalletClient as Us,http as _s}from"viem";import Ho from"chalk";import Ks from"node:path";var Js={deployerAddress:{type:"string",desc:"Deploy using an existing deterministic deployer (https://github.com/Arachnid/deterministic-deployment-proxy)"},worldAddress:{type:"string",required:!0,desc:"Verify an existing World at the given address"},configPath:{type:"string",desc:"Path to the MUD config file"},profile:{type:"string",desc:"The foundry profile to use"},rpc:{type:"string",desc:"The RPC URL to use. Defaults to the RPC url from the local foundry.toml"},rpcBatch:{type:"boolean",desc:"Enable batch processing of RPC requests in viem client (defaults to batch size of 100 and wait of 1s)"},verifier:{type:"string",desc:"The verifier to use. Defaults to blockscout",default:"blockscout"},verifierUrl:{type:"string",desc:"The verification provider."}},qs={command:"verify",describe:"Verify contracts",builder(e){return e.options(Js)},async handler(e){let o=e.profile??process.env.FOUNDRY_PROFILE,r=await zs(e.configPath),n=Ks.dirname(r),t=await Fs(r),s=await Ls(o),i=e.rpc??await Vs(o);console.log(Ho.bgBlue(Ho.whiteBright(`
|
39
|
+
Verifying MUD contracts${o?" with profile "+o:""} to RPC ${i}
|
40
|
+
`)));let a=Us({transport:_s(i,{batch:e.rpcBatch?{batchSize:100,wait:1e3}:void 0})}),d=(await Ns({rootDir:n,config:t})).map(f=>{let y=W(`${f.name}.sol`,f.name,s);return{name:f.name,bytecode:y.bytecode}}),l=await ae(t,s);await $o({client:a,rpc:i,systems:d,modules:l,deployerAddress:e.deployerAddress,worldAddress:e.worldAddress,verifier:e.verifier,verifierUrl:e.verifierUrl})}},Eo=qs;var _f=[Ce,Ao,Se,Ys,De,Ae,vo,Mo,Oo,Wo,Ro,Gs,Eo];export{_f as commands};
|
41
|
+
//# sourceMappingURL=commands-VAQQMCRZ.js.map
|