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