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