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