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