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