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