{"_id":"@latticexyz/network","_rev":"486-260783d42b34d5a4ca0f0c59a16f895e","name":"@latticexyz/network","dist-tags":{"latest":"1.43.0","main":"2.0.0-main-162ca7d3","next":"2.0.0-next.2"},"versions":{"0.9.0":{"name":"@latticexyz/network","license":"MIT","version":"0.9.0","main":"src/index.ts","type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"jest --forceExit","build":"rimraf dist && rollup -c rollup.config.js","link":"yarn link","docs":"typedoc src"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.9.0","@latticexyz/solecs":"^0.9.0","@latticexyz/utils":"^0.9.0","@rollup/plugin-commonjs":"^21.0.2","@rollup/plugin-node-resolve":"^13.1.3","@rollup/plugin-typescript":"^8.3.1","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.6.6","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","rimraf":"^3.0.2","rollup":"^2.70.0","rollup-plugin-peer-deps-external":"^2.2.4","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@latticexyz/recs":"^0.7.0","@latticexyz/solecs":"^0.7.0","@latticexyz/utils":"^0.7.0","async-mutex":"^0.3.2","mobx":"^6.5.0","rxjs":"^7.5.5"},"dependencies":{"@latticexyz/services":"^0.9.0","observable-webworker":"^4.0.1"},"gitHead":"40718ea9955e61196942d040189adec464500446","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.9.0","_nodeVersion":"16.15.1","_npmVersion":"8.11.0","dist":{"integrity":"sha512-bpzmXmbi/i4Sjr82OA3qEDHF29Po10HETYX46stmQSbVHH27Jx9XlkbK+/vrXRQTBGWd11VJ5uNNXOvviocOVA==","shasum":"b94ca6f515d9671ec7e620a9e0b59a6920502b70","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.9.0.tgz","fileCount":35,"unpackedSize":138916,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCWyHvlUHfgZBARUNkr9Jn4JzDiXQTyXHvuK03BSvZIQQIhAKZCl+WH3CJo+Fc5tBu8ZTfuaxWx0bWTnIWmtxmhBCfC"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjIDNlACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmogiw//fOl8U5DIob+WkS/7HZbZr64FRcBd7hSwDIABneCf0sehn+y5\r\n+iKu0NWtQcOytSCVvhxcgiFZnu5HbVA9UdSxE+tFaGioUDtd189plY/Bm22l\r\n/h56DFtsxZSge59pq7l4lzQdhEWMNggA00AFNI/LIsAPhXQu87egUtfty1t0\r\nPrZcU6TS83hR5MeW0fyT7IefM5g/09iE8PmquY/9jUw/89kBeo64/i6Yb1UW\r\naSSJkIDSNfUOCNWbbQGzhdebBdeg5GndVRSOu4rUTUA4y32XjRF+bH9y2GHz\r\nzOufleU0muhXKRQk2aZvNuTBUGBinc7ys5OEb1aKJIjbeYvBvGVI7b5uBox8\r\nmczKCX9z1GIo/uaMFL7QFa1QKO80AnFF2DnHTqj5wzQiivTwjH61HFgVyGrl\r\nWDB/qPwk8fciq7gUNdYiraC4tU8dRSA7QVoY27ziVRZcYYI8sfdKcP4LL8Tp\r\nN5LyEqXHJNB8HiFiCnApjnBpEbYILsiit2LoeSDJNAwf5b32UNkXJdOSSVm1\r\nETMgp2L/8qQ6KskS5B/EqgSSBdl3IkXSwRqlYOf1VugmP1h6MbsQOlzMHSpD\r\nsvSQ7W/ztpU/PLmRNnQr4/QyTVavyPWSMyHl3XxEDOuX7eKzYJsq9Zmb5ZBI\r\np4AxnRx11XHI5suY7YwZomm5WFKF1gZ/taM=\r\n=N6Oy\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.9.0_1663054693508_0.5940536943521586"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.10.0":{"name":"@latticexyz/network","license":"MIT","version":"0.10.0","main":"src/index.ts","type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"jest --forceExit","build":"rimraf dist && rollup -c rollup.config.js","link":"yarn link","docs":"typedoc src"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@rollup/plugin-commonjs":"^21.0.2","@rollup/plugin-node-resolve":"^13.1.3","@rollup/plugin-typescript":"^8.3.1","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.6.6","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","rimraf":"^3.0.2","rollup":"^2.70.0","rollup-plugin-peer-deps-external":"^2.2.4","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@latticexyz/recs":"^0.7.0","@latticexyz/solecs":"^0.7.0","@latticexyz/utils":"^0.7.0","async-mutex":"^0.3.2","mobx":"^6.5.0","rxjs":"^7.5.5"},"dependencies":{"@latticexyz/services":"^0.10.0","observable-webworker":"^4.0.1"},"gitHead":"724f4545c36989b25e47046bfaa0903e9b8d4bab","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.10.0","_nodeVersion":"16.15.1","_npmVersion":"8.11.0","dist":{"integrity":"sha512-1Crl7IzdScgaS4bQ77E11g107U1QqI2EsycHIz/nBpIrUsR4P3zccHbf/9ZIBpYm9FEAfFnPMPcfTV6vumkmIQ==","shasum":"576ca9e8de0f2d5253d06d48f91781964888db85","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.10.0.tgz","fileCount":35,"unpackedSize":146230,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCWN9Bq+ntkRUDDaNDpQqxLWohEmAqo9ehaHfTXxvyangIgSqx9ksbi2qEqwqD6sbCQSbdsUYdX2dLPgAwVTIoaDCs="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjIbggACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp6IQ/+I/UYbo+ciSNP4pc9XBo1FwrMpLk2eNDC/grR4HmXz7LdJDyi\r\n56CjAAmfPzv8WuD+M1GxCuTBFdmEog8RB8T//tB4Pw3dGZoLoI17KOYrx1Ll\r\nrSh2KLvUQ2qiTvHyzUagrhwCMsx3WK6v80rpHpBLnShHmoXG/Lv+HNB81Fza\r\nZeID/qFkEIJ7gQaz3T3opcSOx55XhcTNOGzdZ92+ehqo5h8Ea9NH09Ugqb5M\r\nNkzSzuJlHGdgfZmyM0m4ADuXa5JiNiVftI+1dffiFJHjzgq6udKTojjjdLkG\r\nklrXYFDLHrHMj/2Nu1nSvMJN43RDJRkvOSbPXUZugwH+sE/m72XSmJ/y3Rp8\r\nZPlbcqYj2dVVLVhxk8SzSvlmFzQqjImqtKwVH5NwFYS1INoc5gPHGRrvZpTI\r\nQajECX+t3EucWWe859QAoil1yQYnDL0MY+Q9pzvhHTYgfVgiLEMMiPX2hBY1\r\nq6vxo6Z5g2ZOidZFa0ykzkRl5nHz2no2aPS9kfnQhC+QuxlTORgpnvXCZs/X\r\nRUTGh/SDyckxqI9ZARB9P/YHGMqaPnntFgTN0A5o5mUHRnfsbdJXjs5fxYcC\r\naaFFPLNacWQ7mI9m4L4PpYdFjsZlVjyuG4+yfqoZR1zQXJ7+1BMfWqX++FJx\r\nFZ6HlGY7MOzFDMcq2g4O5obhirolpuy1BjU=\r\n=OQWh\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.10.0_1663154208187_0.03917152611500763"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.11.1":{"name":"@latticexyz/network","license":"MIT","version":"0.11.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.11.1","@latticexyz/services":"^0.11.1","@latticexyz/solecs":"^0.11.1","@latticexyz/utils":"^0.11.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"43b26a1c0311605a3f91e630e57487a8e4faa58f","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.11.1","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-DDk63saX7Bz9+4K3Jcm2DGVCY+50j5vnfLTvd5K0BF7EExbGflZi4c8ZSldknXlfWMHAZKtBHhGj38Vlo1CD9w==","shasum":"14093d380f025450f97fda10a59130a9ea4423a3","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.11.1.tgz","fileCount":29,"unpackedSize":425035,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCrckgyBws327ermDPUBQBe+02v1VpRIVPhNfc7hiv8tgIgJFRadsjhxK4MtFGv7aUrnkhCRklek+9KFzO/MRbuczU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjIv3hACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqVKhAAmHbbKafXzilBlEeGZT61LCa1j669RHVix0lv/ZTFvN95Llgo\r\nqNAL71Kuw5O1W2WoKO9j84Pkrt5GCiq0EqQFj9vPibGW/bdipkw6FQpCI2gQ\r\ntHPNWHsoRG8TIM3GT6Ulu50i45q2WNbl2i+lTX0eignuIxeXr8jw6dQ8Wgla\r\nmVk459Lh5IgghA+KDhyt9P6ysiITxkOJVENHFWeW8xDWB3TIIGjDSfjSBZku\r\nmbC7d3x8FlSPAjC0N28W09QAJ8ojm6fJohoZTyPHCubToTC/DS1R5Y5V2RoC\r\npdG5P6QNAMNpYD5C1qAdHm1sC4gGflZAR5oC1xtnggk5Ns27kZWn0BB275Mo\r\nDW+0wUR5Kh7GC2qhsKsRj/DP2b6K/uDC0AhligZXJkHLG4d3uLlutXUIXIma\r\npKDHAEoMuERY9BQRzaLXO/f7Px+qL4J4cwrvY3Th3q5l2rvXSj9WEco3jN1e\r\nsSe4R+FG23TkCN8JaXCTbT2Iok8Tt4dtpkiY9ZVmdwLFcR6em2nY/mAilpR0\r\nP1B4em2b4sLTiwoYO0lgaxHg4306xkncNAZHfdHeYV04Vl5bfj8gf+ftbJLu\r\nE+WxoEX4r+oksKAxOuuU450xAKUYe6NYQQiKn7mSyQq8LowYCPnlxR9RmTrR\r\nlTEIMogfVIvZWqpJVOqNCj86vo9AWbOddWU=\r\n=W+7B\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.11.1_1663237601707_0.8567257586657009"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.12.0":{"name":"@latticexyz/network","license":"MIT","version":"0.12.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.12.0","@latticexyz/services":"^0.12.0","@latticexyz/solecs":"^0.12.0","@latticexyz/utils":"^0.12.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"218f56893d268b0c5157a3e4c603b859e287a343","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.12.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-d60TikPtWDjgFcYLUpkZ7kAw1HYm8OEAvPr/ePHbjh+8BjcJV0Qvw7ZmKD+tnG/hs+kJ4WPlnXysKMdCsr9O/Q==","shasum":"f95412f4a695474f4938dd85f79f349c0ca4aa19","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.12.0.tgz","fileCount":29,"unpackedSize":425332,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG3NncBZI8AGyDOQCGSMLuUcB6vJprErJAo4yaMzShwIAiAti/OU75fIo5PWEYsrWWu39ZUhATekS8a3VFOA0577Lw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjJLU7ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpVSA/9Gmglo8CepjKk3iFfdPNNvC8BWaoN+ifKaW1rmsNQKbSU+a9z\r\nM6GFJjGkK09dIpNiWUft2jvdEMTAFAZKay7aHQ5cBeXJoC9tbL56R1bbF2k4\r\nUMf+OONvtevMuSnY44qG2jgPEDyhsLL5rs8duihbGVVSGat0KsDwiLTWygu3\r\nqx0SGbTmzNy4AwzE2PhotHMDL4SV6DaUxRS59+Pvpoo0VEt9rU3FXbKgKtOV\r\nAftNrKWHOgTcswYYcLn3xIu4E/t/0F9evVwFgOscwSr3xG7+rypNnsMeGvY1\r\nclWyi+ejgX4zCmydNBCxaiYXd+Q4t6ahiRATHmyeTyOrTpnDo+LsB0aARYzT\r\nPCUSR32zpyL+4WJMFv0Otsu+WdaJKYTDDPL9TwAzxe8LrUZB3MV6v0vmAsG0\r\naDiFmCf/+5Tcp5mjVqn6swlr6kK2quaRlf/I/WWEIn8cha+2Nc9GRluzhFC7\r\n35YWgeEIhaHr/xiuvYJMUMPBal7loVqTeubT13aL3c3wTG7JYTEq7zbgBOTz\r\nOsvCUzDWw37G+nfAw+uNyHAbZBU3VHtmaWnB8+86TUM3/Pljgz8KQf8HvWTi\r\ne373aEwDoRLSnrgEVE2CaWkWoDg+b3p+3K/YVhxYZa5CwrYw+Ud8dP1ttb5X\r\nFp75R+oBKb24YeNEHh8jKZixIDcHz4sTKVA=\r\n=PsoO\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.12.0_1663350074879_0.5999075310741204"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.13.0":{"name":"@latticexyz/network","license":"MIT","version":"0.13.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.13.0","@latticexyz/services":"^0.13.0","@latticexyz/solecs":"^0.13.0","@latticexyz/utils":"^0.13.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"d4f7761040185d9d4b65c286e774e15fb8207f81","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.13.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-n2RFoQLIoN/cibGoX0AnTMmHrd7tfN2XhEm5WLVhVIA6Zfm01OPwqTNZ3pGdPijd8B3MmSjpBmolKE1gCIk2lQ==","shasum":"bd05ac3457cd53a2658c3e355449ba0e985c111f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.13.0.tgz","fileCount":29,"unpackedSize":425545,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGl+cy7v7wH652CdzEPO12tNmYSGSD71mEa3xuDjT150AiEAza1EVRgwJGMfYusYItUQauIRDVvui/9NORs5oqNF+Ko="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjKPIzACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqotQ//R/ScadAO6qO/98XWgQVOEUX4455mVFRNBLrNTI56WYwrzgpO\r\n2fdm4SbliOD2juxkEzGlIwGMJnKjG/mrx/GIOYk+/gMLhUPWNTyIWBrDLZEv\r\n1BfAt4tPvun3tUMfmH7Qw+3tQk01kOmigr64oiPY1VfiZuTtXMLT32M/yVCO\r\nbkshTbECCgt+2YZ8QnLb15A5rKt5qtgcfKMwRJJmY3WBcgDFG7xON0yxcXxL\r\nWzKoZsv2WCGEWrJgVl78MTxaLeAoJhoCBPD4wQ2RgmUT6F8gM7tdOmYSJxC9\r\n6XfyJtCixDwCGKKWS34QObkuR2nBoiOr+uzJX5X/xp4versvFuJMeXfuX8SX\r\nYC4z4FoVm3DgB4k/X00mUXJlZ0bBhSd95QjFThpDQAe9haJB6TTFeW2KLMns\r\ng9m5YFCSi78xXnMxr0KdSxjR0pwke6T4Osl6K/CeRva+G2CEFN5j9GL+gMJr\r\nSYL5tcEmBjjA0iqhLvk9YrxnNuRpN2+LU4BFER9MoTt8K2Y3MDY4uXQ3fYO1\r\nmgXWD2EVZM+Wsd0ydy3CjDGW6V/lJi7Bq4bN0RBbQZTezUhItBfmCmRcZuob\r\nLMUHcXIROqA4fO3dX/0WFih0sFTjCKnLiusSGcQ6W5Lf6YuQSFIDNJzwtipf\r\nti317muFwAQN3bGEYOyKeWFj/88Vozn+3D8=\r\n=Afzk\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.13.0_1663627827441_0.5999091649416446"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.14.0":{"name":"@latticexyz/network","license":"MIT","version":"0.14.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.14.0","@latticexyz/services":"^0.14.0","@latticexyz/solecs":"^0.14.0","@latticexyz/utils":"^0.14.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"b04610a3eb977f4fa5d90329876c4031bbd2824d","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.14.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-B6HC5Kaaw+fe5W+wlWJeq+OgNUUd89Iq7ZNeMuJSuWtr+GJRj9wC3YPXNC1Ppf3Rnl95pZGuHRD8g3dcv2gjgA==","shasum":"5330891490bfc3112d6da1c3d3d9ac8a7eb225ba","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.14.0.tgz","fileCount":29,"unpackedSize":425692,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICZmeEtR9ek44mdpamwtwvf7+P1fFigVyg5kQuHSJTO3AiAFQ1pZasZXP9fKqVR9MEvVxU3eC1X5gIzXHBuPoGUpIQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjKdFzACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqcZA/+I7BSJySKRPbW9JxNfHk71F3GcQW+cFoVsBzYQQhGSM3gjG9c\r\nIdZZrZ5jGDY6w3bjapXyV8xYxbFErPg+pPWpu0myGX2R7cInbVhEaZjN9+RT\r\n57eMU+hikRk9dcSft+Jy55pV/I2rQejhLUKtaozqkhrE808cPktI9ke3c5zC\r\n2/SRY0hyFJI8fT3y/kfcInpn4tK5V6QmO8wybzEPDQzBWyBMtT1oaAK99yaR\r\noZG/RyBW7jkYJBURzFWMqCl4/Hifl+bMH83xROZZZjs0K92H5KZjVf/FGJJj\r\nqed/UFyq8jp6mqNIu4g9NZtFnwQlnXdzMO75+AaoyEUkRx1nyntxvQic9rz2\r\nyQfIpOWKTnf2PThC3gYOAPtzZ2iGV0IVD1/+tQM/kruWLOZgba5/wAqrPtQd\r\nQ3Silrs31mlMAnFaL5VTAsxnjeJcnZ1uKLU9DGsRJNAMbhAEVHXXfJsV7ZkR\r\nchWNk/Muezi6CDMcU5qlkHh9g03SJn/9Qqdi2EFysnzH21XuZB9XUdgeHbj/\r\n1wtNYMCSRvfLlKXAueFDqwlrzNtsJtzjCwDnEPEEi2W07zLgQCetUXHT0jPq\r\nzMVfVVdVNZ7vu+WjFjgby9p1vD/8jtNVGRaOSrrqIz6vBdTdj0F2DpPeolH0\r\nzzmS7VE6Jkup5RSoyc8AeKKyi8J31Le6apI=\r\n=CTYw\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.14.0_1663684979491_0.34604101905607765"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.14.1":{"name":"@latticexyz/network","license":"MIT","version":"0.14.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.14.1","@latticexyz/services":"^0.14.1","@latticexyz/solecs":"^0.14.1","@latticexyz/utils":"^0.14.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"80fc2312ab974b98e91452060487d9200cf56965","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.14.1","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-r++JsDc6U6v+AoPCfJzrbERq7esB9UiroJz54V7v+BEBKVlWA/CZiDjgoS/0HokcaIx2OslqOdYRxIXxqjhSUg==","shasum":"23711dfd8eadba7fd669ff5fc5f55b0991e9bf48","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.14.1.tgz","fileCount":29,"unpackedSize":425973,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCefQ2jWtHR0Ew7cHI/vj7azrM3mjDUT24ymy/20wCNJwIgXWO+bVkS30X8qhlvrPRBXCSWtNpwDETKlzH505cRnvo="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjKtb/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrO0A/7B9qDQirFzN1iy13j5lbxnzyXGI3SoPSBIVyrzzrp/AQoQlQ4\r\n70U/X04ClgepJ1DiCoguTWtWlgTfr7A94ImT9JhGN4YGU1jXoBBz9zPxkdRJ\r\nSLMpMPxZqLJw6PUeQUXIgXwdVphzXrJXRmzOj/nvgIBQOjHg0uZgwz60qoa8\r\npeQkaFhbCnHANcN12hoIhYZACXoKFLspenGyCYiq0RcKoibMfNvYR4VX0l9N\r\n67IqPPbmEKH6DyDyAQGh5kTuD8gOAZ2dVflbiMupzvZa4djS4brJze2AZBpH\r\nDJoplPbRcDTjzU12viyAzlUPifhgBEA4fG6v575m6wf9SQZrsJk8JJa8TiH1\r\nUvtNvs3/k+cROQImN4VFoQeuhH/BqGId0uzob4h64aXHCX3g77O+ZgY2Sp8i\r\nH7albpkMguItj6CDXDBSGej54M1yl4bvNjpNAcZR+fX2V1yRaF8VARMmDp9O\r\nY6ig91anZuCaS4C5hrm0vWVj3YUzzINTgO40MLXMR8IBgKNeIeKIYgrD+KzX\r\n/EXDLYEINn+OsZ/RZgSlXyhxmvWtcEOVH2ee2vNITXcVeBqyAvb7oKQvvqI0\r\npqt3Jr805BpgAn8lafaeO0Yco/QL678DY2OM6LUmZL/LKRxQX5jJ5jFcKCmS\r\nZVrBnLGiuQWs9Q2BM+82hMOF9iUXLKNGLYA=\r\n=cK/8\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.14.1_1663751935294_0.9549982330250555"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.14.2":{"name":"@latticexyz/network","license":"MIT","version":"0.14.2","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.14.2","@latticexyz/services":"^0.14.2","@latticexyz/solecs":"^0.14.2","@latticexyz/utils":"^0.14.2","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"a0ce913a171f3d7346ecbc7e54da54904936756b","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.14.2","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-sPrYYKoPMBIXgT5+bV+X8t3Wn8ixMynYYyumXaFiqUaYg31hadq+taFS0mXZsohbNzDOpO2+y5k80WXuARSsDw==","shasum":"36382143d48d8fb11628ce7da2dee5e0c98bc14f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.14.2.tgz","fileCount":29,"unpackedSize":435245,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHK/GZFW+6C8E1fSwGNpLGfn3YiifrSRjceULsqN82fPAiASHbMamifIF0/oHoOrzb8Hlfn9p2VdafcrET0dY+FDCQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjKvZwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqIDw/+OpQsdKp45NeLxEFhC4Llfyvvk51RnYc8I4RwRLWiPEpvHLMa\r\ngkt56EQck0dJrsXltoNnZPlkQ1KqJzq1hspdIeeBeu7GqsngCqxN19lYFwRC\r\nKNPUD/+I3KuvmNsZo6RbBdUlP7rhVSdoRF8r7Lp4NpmJPgrnd7eudPdZD/n2\r\nvaKBZkmca3fBZ6G1XqFRTfKTd/Usb4E2RgGc6hS/Y1TGmDTN6NeOV/v1QqIq\r\n5w9NSbbGOUtRtmflg/ygVDC672O+ficDVztrX/kOlYSY24TaeAilsEnj1l/5\r\nHhR/P6GfIlP5v41KPbGx3AC6B4on6oKLsag/AY6Kzf91jQF4j6cyDku6qZLn\r\ne02fNkV+opT4V2nRTpuQj5WV6vsnFCM3SGhG6TUSN/bbUq0R5UW+oT14TIIa\r\navgDuCi2JO6283traWBPS+2iifc1W9My6MrwJ55f1Gb07e88hO8gicXgbI5H\r\noDYcL4VwFQdkeMwDAds1w6n7S51978wCVFWJTHRLeQL4VzKmRhm8Jn80+fDl\r\n6kYMBThTXIn0bzXwKnWpC+ASbsrkN7jKqtwrKaXR1ILTQGrbqRulkLzrCk2F\r\nT24PQNr3Z8NKg1/oVcKbpghiHDq0d4ZNwhwFRXGlzGbnFdT/8i/sJSErWexf\r\nXkFPGohufsM5SydUT8G2cQqnOkP/hIEKdNA=\r\n=hXIQ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.14.2_1663759983954_0.7552432661365294"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.15.0":{"name":"@latticexyz/network","license":"MIT","version":"0.15.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.15.0","@latticexyz/services":"^0.15.0","@latticexyz/solecs":"^0.15.0","@latticexyz/utils":"^0.15.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"57db2b1270e0faa62330afd44baf0103cd5ef11c","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.15.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-QCY0gGvm+9XaIFBQGo5Onsa89NPbg9oiGkTkBDLxEwgHc5VV41wNkE6XGmUJdeJTIGpNELdyaJmupj66IiECUw==","shasum":"910e7ea01af5dc0963a61b3b3ebf812d89385d19","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.15.0.tgz","fileCount":29,"unpackedSize":435392,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHJZzGVXkNG/0lqAH3YVzYhi6XyVz3+Ax7z7RyEU7VgUAiB8J2HO3kM8pyJtY7pytbr0B52HAI/0tDvOMpECCXJMoA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjKyGrACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmoe5A//RzYKxaRLnXwR6fKdA/gXIy7oprmIkTVzgcI/9165oWoAMt3m\r\nHhMjJpdBXaB0+Tb8u9XB7X2rnS8LvDcmk74QEkHX+9C8klRtRGXfHiCbjwEH\r\nfqiYqzxK9uISMpH0BYApBvgPDaBqPJLMnSktqOmJiJ3/6L577n1ReFbMEJav\r\nJQINwT8/QtPdemQgjzVwvXkmT2HHDA8kA38Ny4T3H9slEJgtOOw50i2x9EeM\r\nRxnqr7UVckrFB3TUM84Wdymrcmo4OUTArUNOGT8a1X/5Rw7uetHP940PIiHL\r\n6x3MwzeDAh2JpcqWshU8HwUJ1aC/tFYHzPbMqnRdyWq1a4YiPwr+0zWXet3v\r\nVoMsE07g4nielZnW7AovlbgB1uTqcs+qrVFCeNkLZg5G8ufmfGklN6ks1slU\r\nZrMaVHM+BgWJ4xhQrTTOobDhGyqLXAbV9qcda0dHncBbSSX7Yjx9+q8ccxFn\r\n5WKRF897q442A5zxcNamOuKLd6+GPjIE2/2Y6j27zpC3pnMHksHiEnoTmpxA\r\nXGFwWgF9rbLR43BIOzKb4Iy/9/y4rbVWAhqjEU/gxw63+yj3Kmjv+tNXFivv\r\nkh8w1MJhODFfU6CMJLd1w6u7i2fekE7vvtCdVBR8uQBEimfRk0wXQzx0Ex8L\r\nck3KWZL45ROEnaY9P+aCX3gYp8BKs3S+0pQ=\r\n=SSVO\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.15.0_1663771051583_0.8504647444518683"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.15.1":{"name":"@latticexyz/network","license":"MIT","version":"0.15.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.15.1","@latticexyz/services":"^0.15.1","@latticexyz/solecs":"^0.15.1","@latticexyz/utils":"^0.15.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"34790d151082faf5b6f16fcbe76164c01d3ef90f","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.15.1","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-R0kqV08HrkVbb/XBEl0GeSGdFqiFWVFDiif+zwm6N2Ts5M5EFvZkYCIYL+cYf64MfEKGVFV+LMMeoz0QieNoGQ==","shasum":"daace284040288de6199650b1508c6b81e9dda86","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.15.1.tgz","fileCount":29,"unpackedSize":435540,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD1XQJv85iTSwo4yeQ6HJ18VtGmN3ttkUNwVhD4A824CwIgEazsWZc3RpB9P/bo5hVtlI1EQrj6R/cM6xVhdTyRyGg="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjLcDwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqOnw//YPHqC7x5UYAxAE5GoKWJBsOiV6Uv7chZaRFBRKa2Ss3ZvHQd\r\nB2wasJ2T/egUFFBQQvaZv2f1wShGMSG5g+bL8rvtwP7Mo09l7FqWVINopLLj\r\naJ6xnqQNnKM6fztboLO2Yswhn6Yv5zoWAzKx/ndM9jJakFxIfdVMZ4x8IjyE\r\nXS7Gdw4U4iN/i4nF6iXeNyCniSBSeN16qT1O1NZjg9dgbfkAKW+F/cNo3x7c\r\nfiPAzdpplsVC4Pxz1tgmw8tS8fxNoFwidHLqYClgYFxGK/vKNOYbWzDn1VsG\r\naquQRlwlD02kBVG8n67mifZPCq+whwNOz5/fx2EVEQqLdYjZfW+8bciW1C/O\r\ns+NzidtBKBF45WLjD7bty47jw/PDBia+ppALYbw2/PJdFM8XYOdC5XQUD53M\r\naeqe438z0Y4kKI378Zvt9Wehim7m8ZW8Naa64Qg8f6Ybk/p/oBZ8hYAUCsYX\r\noknNNNaoOx3lpb29SwZoShmXL0hBLbulsx/ErUsbc8EzhG4zw1V+NBHVRrk0\r\n+RMfPRxFprH74A5Xu8xwPbp2ZjBD3P3UBxpA0Hu4KUnXgXLznkb/16feoQtD\r\n7gUlN1q0+jYr7itHkeFelSpv9PStOUB1inrWQln0iqXzL8E7pEiqfvT65Hae\r\nYdnstQGPfkBdojuLiUuEwhIs0owywAwsNjY=\r\n=oSv8\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.15.1_1663942896421_0.887920401583125"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.16.0":{"name":"@latticexyz/network","license":"MIT","version":"0.16.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.16.0","@latticexyz/services":"^0.16.0","@latticexyz/solecs":"^0.16.0","@latticexyz/utils":"^0.16.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"c12760f7d6aac1aab7b14b634a41292ef3559667","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.16.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-xb0xqVM90Kq4372n+k9DAECZtLuLrW/7g94zi3WkOokgwcXnsHH/pjNc8rPDcLEBDQFzkx2DclbmDM3y0hrZ+w==","shasum":"580185648e4e5cce95327c09918c67014606963b","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.16.0.tgz","fileCount":29,"unpackedSize":461360,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCvDbjz0jLJWKZresfXYFJEHt/V8HVtMhdEqoGwCj7lwQIhAPF97G7wEVxHv3shSR5hNYxH6GX0gTPYpeIl7didiy/Q"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjMeNMACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrXpA//b29iEDOJXWwxZxGOYglIFdCQz9cXWZIu0a1FAPlMOfMXxjIB\r\nBPhVwzaz85UC/L0zh9nDUDIYyHWyTg7WQvJY2Wc9/dfX7pDZVp96T0CswLSx\r\ntY9mtUqrSclpm36DBpz4i4e7u/8PzTEwlst1Cg2sPfgZTVEpUp9by31eT9IB\r\nNYIpsDyQCLYGM8QrcAUraObDdar2QxBpl3mUypmxlR8uYYgOf01JQiuBJQuB\r\nfXFstUmwHPMflt2cFa6TVbFPoxpFyX7dm5E6Ckq/gx6I+NmLfxFq5IUFoWp2\r\nx18QSaPhBgYKThCqLRcZ6DGEoo4GoFI/hTcAySJZ3GmkdCVhf04lgomTLan+\r\n6wRFRmaIm8uW6SMeOmH9zIejqKId+4zVFBk625N1/jW64SK+1ntINqzw9fth\r\nzq621zafwF33UEY/4BYtQ8ah2oPLaCahNShiDjU+XjFeeI0EeI+V/zhevY+F\r\nG1Wagvvgb1+K2biL8f0sP5Z4fZPF0W9l30/C8/MNov+po+d+xqjvi+Xi/SUs\r\n77qdq7Mw/jHCNl45/I9cdMGSUjTTX3K00/ceL/qFzBBv+ysReDdV5S2hRGeM\r\nXB/2SbjTe46BGktCYdOm81STv76n3zcHyfNELhrxXgEKqMrqMVT4IygTVFl6\r\nesZVyHxDyfZ7ZVwAPE/u1Nkgg2h3WISm1Uc=\r\n=ZorV\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.16.0_1664213836575_0.23289051840502317"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.16.1":{"name":"@latticexyz/network","license":"MIT","version":"0.16.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.16.1","@latticexyz/services":"^0.16.1","@latticexyz/solecs":"^0.16.1","@latticexyz/utils":"^0.16.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"c13a4cac7fc8e181fb07874cd148b100abcd0d13","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.16.1","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-8QdOooNnhMA0jHxU7TS8CluaFmn8zhF3ClSVwjvtToQfJ5edQvQoRozQuJes1sQ9hyQYTST/xApFj1FITKkzTA==","shasum":"5a6ac29cf7d500bd54ca2b949c70784590909450","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.16.1.tgz","fileCount":29,"unpackedSize":461508,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDid55JWfGugcHQFnglAqqyTDMjpqn6EXexYIRTru57SgIgCGPdrQXECExnbs0ChtV2XbY2qJshNFgKFqXW9YC8jeU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjMfieACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrJPw/+K6pahqV24Iqflj5SCkVFSoUHDdP43Za6PESPh2ZMqfIt6SvX\r\n+mZT1TsS6VoiGvJhNh2xzX12gxqapHvRF12SF1A6CcJp3z3A10Pj90iZWLJz\r\n3Y/gpHZtLahEHGHAd2ICW8Htm4aVzdhvYu0/fyyN/X2D+IrRw+aHwfyE/8id\r\nyyGUuobTY8lZidwjHJDTjQ57EG+SWApy9UYbwesq6bOR7uPxbkBVxZeN8CMn\r\nOnMg/nqJjSftVIs5+ecFGrGtyIiVniS6amrj/rCM6O6Jq6R2MBbK576WYrFt\r\nM0+3OhZVy7pJr0f4Wa300fHfSyqQwuU06UFQzIR4TDUmIJRyng3+mUXa2Yt3\r\ne4cPJXSQZavT2XBQX7zgkF7OPrW1yAHfzF2Mdy0eFaWu/1Q3F05VBwV8LUBh\r\nLYQtUC0lfVHo3nzdK3oqOelXIvkMse3JZ9XfmwAqUBE+J2zeRT9ZU61o2GMO\r\nM4+Jb1ZfcMDwyUi8whPgP9zBm2reejRIH2iKWL7fV36X5OopWvRUfgpMyL8q\r\nkjYiXgLkiMXOnXO2vmIUnqRlXAoUB45UBgukzATFlBjS3IxVKuvLeach318b\r\nAEcyrxRvTX6NaXoRNL6pLl4SYdVvAN5pqNojVQ7fYW2/9t4mUFrArAUtqso5\r\nZhyPCAsUEKK2RMN2wtGZYgnEkC7EYtr+MkA=\r\n=Xqus\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.16.1_1664219294113_0.41305081567760893"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.16.2":{"name":"@latticexyz/network","license":"MIT","version":"0.16.2","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.16.2","@latticexyz/services":"^0.16.2","@latticexyz/solecs":"^0.16.2","@latticexyz/utils":"^0.16.2","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"8dd36ad93e8b6442a3697619af2bb2fa565a7802","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.16.2","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-wrVmXQLXVk+ApsSbj0MiHGdATwKZ8+OP/4XmQU8bQ5MPSfOw8llI7ubrHydGFqPNm/uIlWeKSxhA+q5p9YJG6Q==","shasum":"6e67b5554a5e01d6de615ba354d11f951a6f9ec6","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.16.2.tgz","fileCount":29,"unpackedSize":461656,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG4TGE9Y6BVXlw4dDsyQ+GE5/XJwfH8iFJARt+wsouLXAiBn0JH6yxwJmDvnhVu6k6lsL61VfWQdarD6QrxEJT3ABw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjMgnKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqfkw//XZuypm5OAEUADF+25ZTlcgcL1Obnd0E2XUlu+FZpBuIQcB2e\r\nJevrEMjNyMAoRHbauk6hiV7b9h/FiLXUfyh8wBrrQqGm/FLlQ5L75AxZIL9V\r\nE/ZWUcDtuNBUV+jGuv/2wWrDb43iXQTwTjAdf4bgdwCsYE3K2GpAjkba7JTY\r\nt7aioYVI4F8yk1US1pZc8FzKk7TXGdwUnZegCyaLsmciWYLQrjfPMIzm68dr\r\np+X3yw6GGAbVWno52IL3pnPpFnyLXYCxX6AnAccJyM2B4KQooa9Jwyys4xj6\r\nzcwQKS+GqtHlNlAJ2qQoT75XmJPQdx0mbxmHjsYqWtImfq/gwGXZ8AqoB5aR\r\nLpJmYkosrHWVQBcL2wR2Tw0nMMGy1r11rMEvEegUK9H+kEEkopLIWOoAyIvM\r\ncRvKStyti1G+Yy+/e1GCrISnaf+iRSZXvGujRJNAOdHLVyfe4GeXR4iCH8HU\r\nHZ0l3E8lWLAgRupR8bnW83gEQoQO+eG8e0v7zzkLqyxWn+6Cw4jdrvw24NHg\r\naZu7R7MnvuunP4l1FX5025+PDS5nU/bUc1FLQWr0LtniblITmpShbgi66emy\r\nC9Crp460HDitiLTXbN4w83xATdPAhzgsXHjjMZnlrCnvxDF/dQD3yShMr1xf\r\nezBEmPI58Xa7Kp50b2XC+H6g5jEe3x3ITdk=\r\n=mRS3\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.16.2_1664223690049_0.030268802829694907"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.16.3":{"name":"@latticexyz/network","license":"MIT","version":"0.16.3","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.16.3","@latticexyz/services":"^0.16.3","@latticexyz/solecs":"^0.16.3","@latticexyz/utils":"^0.16.3","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"204945e3aaa5818931dad68c8a853d91975fa603","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.16.3","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-B1ZyZHTHgcT/5mhTf0FF0qybqDL0uFd17q8ae6zW3zHPbC+O7R5kZIavesTixltjSs86Wq8KYIfEM2GZr8Bzqg==","shasum":"8b423374f712faba26ee54fefd0578c022f38401","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.16.3.tgz","fileCount":29,"unpackedSize":461289,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDC+vAUbuCRL9ZE/QrflXmHqNrVgQEMEv0WIailg5tp2gIgP8XSKyCfyQ0tOKLsVTKGF60L84lw4jR2cg+G7NO+vHw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjMh66ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrodQ//ZlWYJpQIyIWL7mq7uBBm0CIowhCUYlorEYmWGEThdFFl+3cf\r\n3vtIMbFp4p7fIwhVmgxvvIndqusG0bP2hOZroV0bib+OnqoKn4SIoiwtrZY5\r\nrbx0mZgKF8l/+aFZggYv8TE8mw8Nmz/HTv6N6JFlQTd4X/uEY0oag98y0V1k\r\nVv35uzBLvJYwCW9DFMFerM0mdzLu18rT3jYgz95RRXii6wikHXYgHHeapF0f\r\nSYpyrVgYredFIArT3+1kAwuxGZLU0VASXvDASFxu3qxrN1iul4w+AVzJ82Ck\r\natxr0psJkVbUClGWjB/vxQXkv9vWY8NdJL1Gy9gwrXdzCZ7UsC/ZNS3oVQpD\r\n9Sm7pZ+yGS+IuSL4ZcxHaFIP56F371RyG9N78FJ2SLu3MC9hpb+CK4obU/7L\r\nRuYdm2iGfW0WEBZAQUNTTz1KQMW2gR8Jz9EjtpqRjlgyTpgp5heIFicMtYty\r\n0WtF8DVuIsnDIN0MRW2hvYP3wFYUWhW9w5mXsxm7s24LczkxV29f0jfVUbPi\r\nzSE3JIHq581KMW9hLQbpOXYUzSSm3kxQftark8xtthYdWqYafhnnGRz6GJbc\r\nAf6nCkHt9jqEgMNXeyif6D68XG+KSe66VGQuE3BlK0ODigXVxa7FN08OFSNG\r\nPSTKFWBfUqq2JgjsfiM5aAleSGR7BWzmQtY=\r\n=CmP7\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.16.3_1664229049858_0.0627637064760238"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.16.4":{"name":"@latticexyz/network","license":"MIT","version":"0.16.4","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.16.4","@latticexyz/services":"^0.16.4","@latticexyz/solecs":"^0.16.4","@latticexyz/utils":"^0.16.4","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^0.10.0","@latticexyz/services":"^0.10.0","@latticexyz/solecs":"^0.10.0","@latticexyz/utils":"^0.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"578442f0e2c0e5715bef8b6430fe8656727e5dbe","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.16.4","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-EkMGOoT3YqrSGZMOrhqxTWDX/gJkyhOuompzM/w2S8PpZDu0GFGmZKmEUmEYIuETjzSVgGuNI73mlC13cH3XXw==","shasum":"0dbad77a2c044b3c2e3d30364f4c8d901b84570b","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.16.4.tgz","fileCount":29,"unpackedSize":462031,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAJNWA/UbKZ8sA/m56c6hysSyiKBNemmr6H8KzSQqYtNAiAFWYblOWUadevhcA4k20/OUyn287RjehC8Jwek+5xApA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjMjn/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmojKw//ZyRoIgy/zGKH2K5ixyjcTvU9MhW8mF0gydkSJOHaSXv1bF0J\r\n65t8VKibpPUwsWTtTMf6aeUP6Ncy9udP+XZ1gGHqpwT/rHcRYZ+D9JL+g0KA\r\nWvvcwcah49eAde34LsWj55iqTxZkqoU9mzzNUiV8P+QwFbvHIPBVHg9ZFdAG\r\nEyk2yt1ul9KtBwL6xLiBTYfqI6ys9pQm9S6vVcrRmSc9AB6pXZtOQzWese2Y\r\nmj8ofiOZ8yDO10BLRo/kFOLyrzPVLo6wwpM853IXX/ouR5CPLC5O5JhIdOkF\r\ncKTo2ZsjTe0IyNcN7blVW/FoUMoJ4/Zh7A8Dhd/sc4QAK8NGPMIyXb4HO3TF\r\nnkOznQJ/C7M+aplcFE4ngPV9IbrJ+dYNl0EoZGcEK6UeRjepfME1D4BAiYOo\r\naGTc/fLHfijem0DMk9L7zXjNdmpnGMPTO5dJBo3piAwxISgMgNp58qzeEf42\r\ncZ1/FzKuQPO3jorxUQ7wvl1za7B7CnXDJH359YwDtIUbKk+D9Grvpfp+yifj\r\nTaTDqGW2aGDKZzxmup7puDQvpd0qr2lEdVWK1ZeoLNQ27guRvlmoBR+IUSiY\r\nHBZUY4AVDVz256f4ck+qOsBXAtcOvjp8uoZVfuU7rwFLO+dJLp+tXoiZcYr6\r\n6si8w6v9B0P4k0sYOk4PpDD+oTTh/HcBWGU=\r\n=TE3o\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.16.4_1664236031055_0.8079849190529136"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0":{"name":"@latticexyz/network","license":"MIT","version":"1.0.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1.0.0","@latticexyz/services":"^1.0.0","@latticexyz/solecs":"^1.0.0","@latticexyz/utils":"^1.0.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"b46c4f5256c8a2bb82671ecccf6c927f0c8141e0","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.0.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-7OcZ1DoSCU/1W/wbvXOdtPxhzMIXsxcTbh8M16TNO1IgngjR1LmfrsqoZN4fUg6nPR1VEovhRR/k6B3+wZJbQg==","shasum":"750a3118fd9821c323e9fa93888b0f1391065682","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.0.0.tgz","fileCount":29,"unpackedSize":462151,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICVsk9Q9xi86HSRTKtbRW38SN9/xve+uDa1D7fj8ll0HAiEAykXYT68T3yMP5I3iKZZjwZPYYAlvyxHlJPhkP1UhgTA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjMwDtACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpWQhAAnHe3WMhPI2ShJChzrzq1B55n5GFxcuDp0lbRWl9rX8MHEiNx\r\nHNjloyPSyWqFfmDA4/RLWf2Xdaf1h6Ergv76Lv03oVW8g0cbmFrbkr1Yb5ja\r\nj8fAcftVWOaBY9Ej5cylab39OH5IqVZ38sHFxHk1rK0Vgsql2N9IYRp+0Ais\r\na/m/5Rc/GSaQC4NWS29tHce8gGxlQBWfSmr4LvXDwuxytZ0OyoQM30v/5nOV\r\nSxkhOQC+qaLXMyYuUGsi2J04ladMX7mLz+ICeADykGf7GPnTh3vUETQes1VD\r\nEc/7a7vWn0f7ir4hMb/gVze7U4Mu9KUvv2RwqTIvHtcda76c1XpgwHeDkxO9\r\n9Q+pcKsDf2QCIT7se8sJR2pZSYEcBrf4jTgJfmx0oY0M78VbHPyVMy6JqOUT\r\nfAtjWMvIMWc9CiBt8W987MS6Mcnn2JPnkIA1EqtIS4VK3EkPXb54WYBWfquD\r\nPGPTFQtCXlVmOHxcDqZ+nTUgCkjbRwlZXRknKuPhbZ3UV+8xpATQEOV6ZUzK\r\nnpwCDqq7WgwiVf3aHqrcCTXaVdeeSlhLVLd2ew+BOGYeh49TPsD30920dAKJ\r\nFzFg5oE7NptId7RUtDDA5YI0vD7VeJijPldbvWs35WTtyBUbNTyz80z7ifCk\r\nm0aN7fBk70C7a5fwchvVC9swn3v/p6efmcs=\r\n=jNyK\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.0.0_1664286957302_0.8453144300319264"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.0":{"name":"@latticexyz/network","license":"MIT","version":"1.1.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1.1.0","@latticexyz/services":"^1.1.0","@latticexyz/solecs":"^1.1.0","@latticexyz/utils":"^1.1.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"549636cc1815c2fe88ce9514c03bfd119195a460","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.1.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-jv/V91GH6y3Ln6UdNIbEd0S9vSW8JNdCYYODZlxk7CtoKTeCz9aXg4uEzVXfW4UWtC49tNV6shGfp3i/54F1PQ==","shasum":"055067d66dbfe35443dba11a5cc316ea71301806","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.1.0.tgz","fileCount":30,"unpackedSize":469118,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB4Br7KV4fPp4YT/zZo49+Tu/tTVqvsqi8jBWoNy7z8tAiAuGszoq0SnjL/6HuJ1ccYvlBZpzOE7rxlRWWXHIKi22g=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjNJ/MACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqe7w//V+DQx5tdlDp3qWKBKrniY3J6l0LRyy50gFinbIN9TwaMTNTc\r\nfZUYB21fLBnQfMQlumHhk9ER0DDN7mDbIsuho8PC2F4L1tFwki6DCuO+5Sqa\r\nG1qh8Wlr26YlnZb2RtdEcRqC+n57FKncFKteC7BNA/ID8LwcJ8neFFnuOSfS\r\nVhtm55f6FUOzGhCoB6z58f99OmNo3Xz5kjDvgFIFwkw0ZJla1kkXJxTZiTPq\r\nHbK76a4AuPTz9s1g1ZmtjrBEgZrOaY8qjjSVduwaLuZB3+3A+q3NcZdrs/4D\r\n/DP5Kjl6/lLpntsT0bEw6uaRBvAoj1Anf3SzQLTDuRRResvAB2HdPMCRNkNx\r\nqVkz3N3X+ULhPbT1tKxTnJ5xEUkgJ3+eBnCTkK8DqRbEXB/5puAdNEpINvGG\r\n9JAZ4nrGvA4rp8QM+jYu8ukifMAapfZwJC5sDSyHF27bh65+LvYsZmAzon9H\r\np3DJHIDAa3eMLW14xeBVQ4gtcs2zJAJ/ZY9JkFcYg2OQNvsyG8Ku2EmD737o\r\nRWr/A570K/A+XFdJbpPv741ELFjG3vEPByOHFUSI7//tFIrqNTsGniSxWOVp\r\nEIMBleXUvmhQP/hSI3fK/dOGCYrwzPH5wzioZeiHdwHBc4M8gR6Xni84s8Ka\r\nN8WLLwDiOgE+cEeV7Rn92SwvS4UP5xeDKNA=\r\n=235b\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.1.0_1664393163850_0.5942768050267344"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.2.0":{"name":"@latticexyz/network","license":"MIT","version":"1.2.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1.2.0","@latticexyz/services":"^1.2.0","@latticexyz/solecs":"^1.2.0","@latticexyz/utils":"^1.2.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"2fe2f76c83d25b21a2a4537f9ffd69baf7eb9dee","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.2.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-ZRzcJVzP10TeHq8gr2OgXLmlWbwkCnJABqY/ql0cV92S3A1fywLyPKAh9x0ib4wKTv6qW4BEnWd9NeSj5GrhVA==","shasum":"df3191a4cdd852be3148c25a4067ed2efd4ed88c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.2.0.tgz","fileCount":31,"unpackedSize":479848,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDhjzjDPDhBGLTgL7f8WQXg2Utgz09n8kk0Bhe9vHpXXQIgDOSK+UPif0jm/HlxW5Dwh76ZLWJ894TaAPHuz4e0Qxk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjNXe7ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqy8Q/+JCov8G8DV+1OT+ghgGABFptK649dawHVLzLjFaVBa2jc5bQr\r\n7jSMH+Is/J9y7cxJyHdyL9vE2RsP2CJ2Jy2WV4jWXmS9130BmYxVoUFocDgY\r\nvzgR3joD2MIa21RstShirBVf9QGrvcbHmmHgnW8HTy+oNROwryDBnSwySiYU\r\niekURED6VIkxjoOLRHuOHMJP6rGpVFzw2ChKlCy0oa03+IDVq+BY8ggbTe83\r\n3LtlK0QWjCF2j/BKgQ9QBpPWOoIzEV4wVVr9jKZBpOmbNNtUffv2mw4c2YL5\r\nYbqQAeZg5pO/USb9yMZk5heaByY3o61lkuRdScsvduD4o5qh3gd15T5hMRW0\r\nu5IHVlFZEYjtlyFK1TkDvd6bEtV2xnerksefPUIFax41H2WjILknn6VprTyY\r\nsriJiSvk9skq+hL+4uZ1yf7DtTUUK/yOoKnTe6s2bwH9z7RCYxBBvCHKFu7a\r\nsS0huasYqQHxLpJiUBq6IuGIadogE0yDZYL1W/TIiQzP931tDlFtGjuv14ox\r\nXY7Q47xIs29SKG+od196Sd7y5qZeaK8nHqyGwA0L+AkhvKOxuq6C3I5QYw4U\r\neR1yVt5+iSCuLrbIBBXNDMLcht05HJ5x6TKp0PUIFYiwKjuMtstMoDEfYvog\r\nTx7y+4gk/g4X2LY4uNt8jg5idbIhflKDcGU=\r\n=IlPv\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.2.0_1664448442816_0.5881525078113305"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.3.0":{"name":"@latticexyz/network","license":"MIT","version":"1.3.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1.3.0","@latticexyz/services":"^1.3.0","@latticexyz/solecs":"^1.3.0","@latticexyz/utils":"^1.3.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5"},"gitHead":"2d8de46c22981fac660a40c3e2fef40a63d338d5","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.3.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-owRscWhjMVh0DULS/RK8QZMY8o0no7H4b9Ty+RaPU76p+4HZZ17zxGRlJoqjj45K1gpkf1X//2Ez8hcT2WvhhQ==","shasum":"42aeb941ad683c7c970c8e47bb44dba842355422","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.3.0.tgz","fileCount":31,"unpackedSize":479992,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDy4Lxtr3WaE0gR7tgUs7OfkkAMfb+3HxXxa2/iPZNZ4AIgH63UmT9gmAuZDJkVt3OXlza8z21HHMRYxnXv7/nm0ak="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjNxuvACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoJZA/+O7UPXf9cKMXefmB2mA4aR/xk0sFnxWNvWvlqFS9EPiMteNJK\r\n0G9CdNSVR0bwzk6V6rzu1t3KmWMWPqZ0ZvsTBQJg9zlKgt8strgL5k3jea1D\r\nk4fGg4AD4ecjbJaxh1hJd1IeNNfIo6n6l9HVamflmcCJwK0Gh6s72FgT/R24\r\n/0RbCKBKZJS9oZUBGQMrSbBNZ1ljEA8dlHtusgPeZYjGcXErhyV85Lxx3C0t\r\nwB5/F8kMIIAU4iw9yr78zopsbOOQhcsZTixDQZt6vh7ho7JZMNMsTAKO7EnZ\r\nVwwJz3vvI/j0tfV1Ckknn4TRnDFH3ZFcLXv4TarRLEXR0KXW0PO0AOgRtYfB\r\nN82cAjHWFWC4rolXFQHlk6dDzJSJTTR2atTlEX9EP4DvBI2rzjRmm8cehXfm\r\nv7fnaERVoXMqzBTAnnTB6wMKaaop4XEuHvG3GgvNnQhvi2u7eNPm6y2ghTyO\r\nUxfX74wRLF8tCYTS+3+4ep2FgabJLUt0j7pqg9iHmR+bJtU8sTq+AfajY/42\r\nCcghM8voUENvttkaS1IwXlN8HKfm0Un+OCKL4NI2pFOt/JRCl94Y/8l03orT\r\nN1wn1WlojFP7sMbLvcKqUGe4uCf35I7Py7HWw+ngUGmI8XPCfaLe8LVn5Qk2\r\nu/Oe7HpDGrE6jxy4CSTdwkwibtW03CvN3ao=\r\n=KAbN\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.3.0_1664555951305_0.10103638426579487"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.4.0":{"name":"@latticexyz/network","license":"MIT","version":"1.4.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1.4.0","@latticexyz/services":"^1.4.0","@latticexyz/solecs":"^1.4.0","@latticexyz/utils":"^1.4.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"3cb769df7f4bf0c1e838f8e521a9a93536c7c57f","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.4.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-FBWv+pJVGvbwubG/YpRfh4Pf6RMmHiJTefP143IMf4qL3GRDkwLwXbCKpx+Bd2pFgappmYZcSPQlTnAmBWG5ew==","shasum":"8f0e4b741ecd1bb429e449350df11577e9ff9225","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.4.0.tgz","fileCount":36,"unpackedSize":486988,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCSDGiEDfTvq2xf6pUXbUAlXOf+f11zracpWTFTRqr0JAIhAMZKQnWyiECrrz6NDqPbnydnYo1XJD8YITWcEXmniEry"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjOtzIACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqmLhAAiO3Bu/TrX3PYWyFLo9xL456Bkk4yDQkVDoXgOexcaQBpfHvK\r\n+ceLjcS2pTeMgdtWFa0JTQRYfAxNoe3SjkNmYWsAHau+jHQdalGpt/a3s9Tr\r\nv9f7YBkrspWf9ClXLbhoq37k/NBlqF4DmvqX/k6JKkYPK6xKf5HmuHk404HT\r\nZkWG/BiGnLJsTYlWUjccOKAEfwR86XbTsbPS/SXxCa6uV7O0kqXL4xykuSXP\r\nbrfdoR/rfidyJAatJe+3UmuWx8UlPfh4QTlhlK2VTOzMiJwXhF1ic8iBOxkX\r\nB5vjBigtSwtf0rWodzkWtiPwkp5fbQOZAMnTLrr+wu+Dks2tT7euebaKPJPh\r\nlSKj2F0CcVanPzOCawItjuoryBH67juQv5LWUgyha81hoWEd8ufJtthttWDz\r\nibWsNW3DJAPLn04XnP9kRCgtseIzP4sZ67r6A7IUA3U12P0ZPIXKapFfUS+O\r\nYkYUTNQ3xq9enzQLKCoHFf/ERQCgRi9Vf3fEbEzN2Sh6OXIL+9yh4kZVwqe8\r\nGpkTOCBIUH7uRndVKG7kxbahoQLwFVsKr0zl4RzeJX/Vu/oTrkHUK3DrK3ye\r\nAEl54CTNRmFwnwkO1CeZt1d+IVwATI7OX8wTC7fi480cXpmRdCHC6PRHWoxo\r\nSFSsh7NoB7Eyw8ebfq7rR9rxlATFSbync94=\r\n=yNvf\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.4.0_1664801992586_0.4405860170480769"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.4.1":{"name":"@latticexyz/network","license":"MIT","version":"1.4.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1.4.1","@latticexyz/services":"^1.4.1","@latticexyz/solecs":"^1.4.1","@latticexyz/utils":"^1.4.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","jest":"^27.5.1","mobx":"^6.5.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"9a9fc82623cb29802c55aa4e13808dc191f535c7","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.4.1","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-Ipx92WgNzI2iiESWAxQYnwg3OXF30+xU4uI3ehjtgjbC0+FW3BI02LXan/Tvr6JfAcO19NFMw3Pv9xsU3Qf98Q==","shasum":"698250c3b07095e5074b488da74ac8f5ba2c74de","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.4.1.tgz","fileCount":36,"unpackedSize":487133,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFueRnxxOZ160kkAz/pG2JTR7Qm3qZHgfD3mRuvDhTmSAiEA1KS7w6v/iaTAvAwN0c7MssXLwJr+e0auTo4EsAScJSI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjOuE/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmol/w/+PMHN15mN40dHV8LzYjv137vjBdYkOPWgaNT7B6yItEVmEI2u\r\ncnpK6vlnejzNrgQwBiOPpoIYDsAw46yXn8FgdFXhFa7hskxA9MHn7mxVYxlO\r\n1qvG6ZpdH+3C9MyrFFZScX9elBK7locoCMV0xH/ZKsECulrkOlC5TjVYih6Q\r\nqdKevX0fGpfuNsLeXLLHI3IKKzka6fZWVTIbyOZbT0KJPgRmCLic6uhKoemH\r\nrQk3B8Iu9wUO7w3mosKcbvCeXadFCBePo34yJg56HqFX6clnYzggpdS6KYFB\r\n/A6qt3NqqlySrwvP5+nm5aGHwUMc2jt+SnKxo33rUdyocCA9CW7ep1/pvPAp\r\nrx5YvMwCa4MioY8ZqdB4M4d8/iDAiYC1Sx7L1bfUm/wa4/nbFJ4YPo43QOge\r\nnOZGN0nTedz6TdCwzGfYjEGpFhRwgv1KnOEKgGr1wPklg/fd6bgolQ6NtG6g\r\nMKPjz8qb1kkgNmjT5Z2MZH/h0Qd55qH3o+ySHnN7a6YCsjv1BODwsc/pJaYt\r\nN1uP6RW2u0H61EE7Wk0vR+5aRZyyHUCSTd91SD5icXyQ8STMppsTNg1F4hlj\r\nDWSEkOCy+ufn4RMH0JR/WEOBpT0f70ytC8fKDX8tdKa1jdfnWO1DDkRiW3Hz\r\noibmkI3RhyMbrea6cfN3bWYnwj/WQYlYluQ=\r\n=L+nO\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.4.1_1664803135503_0.7098880291507461"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.5.0":{"name":"@latticexyz/network","license":"MIT","version":"1.5.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.5.0","@latticexyz/services":"^1.5.0","@latticexyz/solecs":"^1.5.0","@latticexyz/utils":"^1.5.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"b965b7c715cf28923d694d17dcffffa6e4bf615c","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.5.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-76gjcT+dKSbYJAQ1TtFkUjX2qL1VOXTC/GWcrPVjQQiOP/SK4gG1Z1iuAR+f2ZoitqrE/iQT3A5yoxrUcSVhCA==","shasum":"71ce0186159f7bea4d43fc4142c028c33d932bb7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.5.0.tgz","fileCount":3,"unpackedSize":27481,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDf7j2XPUrSF/F+DJaiI14XyFJqqeJIkrYn1K3aD4h5pQIgcZ+kvXyCmwkJu+wWCrmmhDIY9iGGRgFf9m8s0MJQLjM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjO1x8ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmok2xAAlNFI5MG7Kwk5cM3vjX409oe+1rbEkQEZnT48+WljETeS+RI2\r\nNVMPCE96ABV7d7aOEPjvTN00NHF2fsTEWuvJ+qbxLRw1r5YoqQhvegHfgAb8\r\nPCewyG0R2hP7FtsVlVnP8L+jsePRPMf+eyHDQItKmokVko6jM7JxW5DrvBT5\r\n5oCmOnna33n15jwiceESaZpEH7y4YyD5wg78TqXQy9frXa6SNV6QZ5X6u7eD\r\ngoIWfTusDl0afmjSLJkRwob0IMbRZTZFrtekMQlEB79qeTmbbkhy2TJSOeiL\r\ny6EV6DEI8GY41Zs+bhR+ndPHHSYaqtKMRuZntT+jift/zyaSpdRbBtACEmIT\r\n2xYSOgXDYde2nHqGCRtu9awSmgR9mc+54eoELW/p7yLD9BprI34cqMYXvo43\r\nQ8u20a99cJE+ImS1pBiAk+dxKHzt+2tGi1mSBbPOVCXY1R2w3/QoFIi6jmG5\r\n123+UvmNAhEKzxMhp5HL/dJKst0xK0wSHJbN6nbcOd9KLo5XOebEimz5yT4U\r\nSRBU7zbPouTw497dOn8bwbL74/qErWXXFVpz1ZPDeAoXXiYsULsYN5GIz6Su\r\neeCCpvRZqcLuqa0FlNTWIXhIrBwvyDOceYRbXPn4qi33iBCdfK8eCgR5RE/q\r\nN/MyVpsCLw5OeAoStHLGrqI3IPYM34F3Z6Q=\r\n=kyDK\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.5.0_1664834684273_0.279181892757733"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.5.1":{"name":"@latticexyz/network","license":"MIT","version":"1.5.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.5.1","@latticexyz/services":"^1.5.1","@latticexyz/solecs":"^1.5.1","@latticexyz/utils":"^1.5.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"6a1d4576b5b3772d2e4805067d90336e24dfe825","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.5.1","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-KAaj2yZ4PH3EXCi3Y+jEYc9PhmqZ5Vw7LEIhfK9h1I6BOh3fO6O2n/1qADuJQuE6TPWxZu9WYYJr3vaztcufrw==","shasum":"5d84a8ace1e7a328cd0d326f249f238f9ea90c25","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.5.1.tgz","fileCount":36,"unpackedSize":496874,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCTILcxZvzWY+I+62vpRomORg37qIeE5j0rf8/hM7SY9QIgBwcd9KWCigGry9vEoxxzz+njTLQDFTt7gJYycteY1Mk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjO19AACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqQjQ/9HWT/RrVgxhdQKIsSuDZyjA1EU2K2TB+Qv1bkOxarco5rfGwj\r\nh/6mKpciCWcim+JxyeEkTW5VyQ9iCARxkVAsAs9jWOx2uFeaXnsCD2sjNl4i\r\nPyPnNqRcnlcoE66OPk4eXRl5QvHLM66WtYkVOWxzO0wKLrnp5NNavn3apzD+\r\nnYv0c4cKncgSdkNgGQUMaJMY948UpHcVMrVNsKHVfIWy66a3pHxHc7BtaUno\r\n/38rdvO2ikhAeSl+FsfOQZROwuGhLg1md8/s02CusXnwSzdBzXlRtOxcGIzS\r\nPS+dq1h3wINY/B009LY+TeFn9wu0R0BPDjg6z2u65HIK/8GJd1IDOP462XFO\r\nKe6oQKgrdXYyrOmsezcjMiL2gBAlIx/+fKpGPreIFFUVhCmo33F6/3eDWnXv\r\n83OnbLG/W7y3PTQhKKmihgaysUOf5NWHXR0EeX3F/5qCQ6I1nlNK14cYdizi\r\nNm6dhrshaLkYIB2JS+nzDMcLDrHqRbz7NRsXpauLKj5ryt3hTMPju+GfH90W\r\njdWV03Dr0RGQ8bOlSHTlaq1Bi9CtVt+iXWb8tiBMuUn4IfICK1aGWXJkjWRs\r\n95fSRigC5fMicBCNG5bsvmCvbxmRlXDX0kQzHrhW7EUCt/MCT5Hwp40z09Gy\r\nA+wyt2/2FmhJQGxmBc7aqVPaWIy0PiwefPs=\r\n=Uage\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.5.1_1664835392455_0.19860940503458746"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.6.0":{"name":"@latticexyz/network","license":"MIT","version":"1.6.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.6.0","@latticexyz/services":"^1.6.0","@latticexyz/solecs":"^1.6.0","@latticexyz/utils":"^1.6.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"7e48133371bcebeda315c1931b38592ff4885e65","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.6.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-akGzmWZ60kVxiTFQW49BQLLwIU5cwKj0XdPdudK3sK72978MFEzuijFS8lsjSA1goSjmcZsAKKMNpLtiprodrw==","shasum":"13fc702690e1d4e1cfcc3b00c452c9cf62219192","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.6.0.tgz","fileCount":36,"unpackedSize":497018,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICP7tkJlFfy/VetBQEckG9wSMhbFTtjenQ2X7jfhQfGEAiAd/CY8BXuiy6L6vujo5nClWem7/KSn1NmE887eANWXIQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPHvmACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqp6A/9HDePWDpC49x+aWw3fa9gGvwTlpinIjdKA3ggdoJs/KLwqb5w\r\nnO69SoBCIYH0EjdXVJ/uLYO8UjmCqIKMxldVhJ3yH3G4Z8C0PGjW2PV5md4R\r\n73WAoI3lQ1XdwPYKWjovTuZstdLBhXjjLbgdYIc7rymluTZE9jX3rUKxI1ms\r\n6NPLy53/FY4BqceRAnC6CLaarVnlskEYbtCwSA7jMc4N7duZnw5XrPCDnybw\r\nnNCYdLvguAtVynl2uW/6Ml3mClwvbt6GWzD2h9BIkwnA5USONwpnV4TaaLsC\r\neGFWoW0ECoaBbY+zjMOZgoxho8R8wU0xyeVjJakPeOKMZEt2Cb/I7XouNty0\r\nHjdTgfnf7rMG0ks/GE6UYkRz3v+1MIP/i15WcbMlr2gO2SR3D2nTfk3yBgqG\r\nhy7fPjQHq0+avyCWAKq6ChtM04SojxWFznpF+FlGDqNdAvXxJNphvb3cDuSa\r\n0ALhLOG4FT/LVHXFMTwUoYQe5O8nF4g1/y7qbVMfiD/AZJqf4FkQ2ua0AsYg\r\nAf7UTGEKXP4zWXfrk7Pb4MubWcV6sKAwzPoXJJdLJ2rfVcYWYBkOctJik1+z\r\nBkuSRntP3eWKopTmUGQpCE0rk+r4rz9jgY5oOwCdlNwD4igyUxVXgxm7+58t\r\nP+ERjPdjAiQDOEws2EomHcHa1Ilv8hNPC6I=\r\n=6Ic2\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.6.0_1664908262234_0.17869141207273342"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.7.0":{"name":"@latticexyz/network","license":"MIT","version":"1.7.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.7.0","@latticexyz/services":"^1.7.0","@latticexyz/solecs":"^1.7.0","@latticexyz/utils":"^1.7.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"f1be62164c395699235140543d0e9b8add75afb7","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.7.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-5fZ1mlofDhqjtjwnr+eXouv1PQk7fnmewzld/y5OAPiRBc68nLVtmd/wtKkaXGC7o0g8LNh5ymvsbtcsDq2LNw==","shasum":"158cfff60d466a17f0e58d2f3169c154d6449f3d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.7.0.tgz","fileCount":36,"unpackedSize":501430,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDiMIkjfmxZUW5ZNL2LRK58pz7/GFjxY94SK35q8jzgjgIgN6TASel6Icon694qIOGei8Rj0kACPbqSLUS/L3+h0ec="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPtExACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmraWA//bYsyJefdN88ZdCI8AdkaJc6w9XTesZryaZS+La2y5nWp+310\r\nKWqn4zviGMqaOiM0BigNwM50aSELMrK4sRx5mvuPPUht/hV6b+qVyOoUnYeP\r\nha+3pKfcAT4UzK2oYqj4Uztg5coHWUAY+z9eXOuRGYO1GDRGktGZhCNzhe9f\r\nT8uIabkrNrX1eE1nYB9PBHiuT5bDEn9eSS9rt/FgzKbAhWRgDAbgxIU/nODP\r\nDhnWfWemOT/Fsbo1ijO2/V5Bf62yZkqbHYuGZGRv9fzF7Y82xCRCiUoWgUcV\r\nNV1WtHwath/YberHj+0n8TwNyE59nHASuRWWReC068Hwq+dCfsQje5amUZT6\r\nqyvZREpfPDgCOFWLZkMvf3J4HtRG6V40Bl7UKfycPms3YkFZvvj+AwoJJdr7\r\n/fk2QFF1kDJPsSVydS4WJy/W8XolHj7vL3z50yHW0ZktXLZbR2gutwL7DDd1\r\nzCzmjVI4taZ055H8tNuhtDwQn42OARjpA4lLf7NJNnURBBkzqEb0mcRatUTz\r\nMyn31fTc9d0Pu4Y2XNdD7jKd45UpRsxYwOpOKa8sm2Vbb7AXWEnNDtWyf0KM\r\nsaaL2emp7pd9eWa6e1VpJZv1QF2JdbJFCvo7H/uQqpyEFsyh7BjVIgIyA4ob\r\n31fzPhDGdcR6noVe1v602fwBlaOKYN+B/C0=\r\n=xvpE\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.7.0_1665061169365_0.058963623793808484"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.7.1":{"name":"@latticexyz/network","license":"MIT","version":"1.7.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.7.1","@latticexyz/services":"^1.7.1","@latticexyz/solecs":"^1.7.1","@latticexyz/utils":"^1.7.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"fce98bb007d60ca69faded30eceb79c69bb127aa","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.7.1","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-IZSQWWiiTaM79uB1I9cYSaEHqJfimPS9/+o9oMF4jbHWahc1nXWz3fNQfgKbiyqfLmt0I/WrAOuV/thtvNWiFA==","shasum":"86d69749f3557cf7263ad41516fc778944ff18e2","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.7.1.tgz","fileCount":36,"unpackedSize":503070,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFrKuih3b403lrzdcht+949cW2bfXFzorhfzTrKjs7sXAiEAyCe7xv/m7192OidoJ7XAP9Pl64WcRFPz9jUQP29kitA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPtLCACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqh5xAAn2YNmpcUWgGp2evum6lq9rnEMYvH11dD1ZYSbY66PZ+gfniF\r\nFmlt0hMqYWfwRuQsexgB6j5V8V3FOEelH62E0fS7WsCDFqhO87acG1Ebp7GE\r\nx0qNX6EEYw+dveDjiZa6wFZSdp7pLfhRMSGpxLwp99iODhRH52bCAF9IPtBo\r\nr/q3LOHBn0vxS6WtU6y8QkOb1I2TMqoy8oCOC4ZBjA4G9IvPs9VIYa7v1Xlh\r\nkRkYxKk07SQ67STrsViioUPZzwRIZsOny02W3fd08vmOrKAK6B7sgrKdtWnN\r\nCJKEb7aYBAmkhpH9/3Lh5Q5Ee3fGWnoewttVXHAF1mORY1Stke8lb8Sb3Fay\r\nb3mnYif+0pAtBqgLCg9lUrDWSY/0aAR+IBtFCq//A+dHXChaP+jA4brfy+if\r\n4Sfket7b9ZKRHh44ov6tz+DyaLbDPkR57BMPKYZRBCmTET3akvDSz4uWdgd6\r\nRlq9DLvPmLPy6fAF1kRywHSsa7dlJL9/rs9BU1Hs7AltU/J1J8VJLdMWpJcv\r\nTz0x9YeGei+SDbBt9OeIkaU28cdYUEL4+PNY11kGrTOnxyhEV0opaKSjGJiH\r\nmNZMuDHqXmH2NcS2484+zo09FPUe1fsx6Ecv8H/yY6IPibcHcgtie/l+mWf+\r\nbXMKheX6YFjVDcAM6NtLk1gPchSUdXfhGmE=\r\n=Kv17\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.7.1_1665061570577_0.037233476102763285"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.8.0":{"name":"@latticexyz/network","license":"MIT","version":"1.8.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.8.0","@latticexyz/services":"^1.8.0","@latticexyz/solecs":"^1.8.0","@latticexyz/utils":"^1.8.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"9443488cdee6fc811107c45b035d3d4c1d98ca42","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.8.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-IPcnRnOTGmdfs9IvsqhsRUJbCJ6b6K0K+L1IdyayOD7Av2RA9Iysc4L5pFqKIJ5l5w8Q9t0x3ZVTtzpoCZOeaQ==","shasum":"cc45f1b139d0f5c7d7abed07ba5bee0195d02d62","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.8.0.tgz","fileCount":36,"unpackedSize":505346,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBh9K9wRPtove9jo1glEC0UCdXg8FE5JPJdwMvGXNJTXAiBxNdB2JiE6sL6gaKduUD51QWEV4Mg/n1Hm7He4ROwuLg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjP3/hACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrQLw/+P9PEN8MCYTh+0W4dXf8SO6llXy1U6XumqobztCYTr62KAbOS\r\nBkjwnSu/m6KCnnv9NbbIKS9IGffnVwSDVihuupaCJVsGkw5frWWcjG8zgrhw\r\neyQKE2CG8amasoNqYZiEMTNzmgPfXSFYWYMeIcZXZh3P/JoDM22a1wpLISFQ\r\nRzDhvSJLl2osTt+SuCyKN4mcLsxYubrsbIrUWBKThRyOeMot7LvFasez1H0I\r\nTyntNj5To8EcT9EUdl6pOt05jN5lXF5U9pEMdDwDU1Re+YSyZILTy+fNqJqn\r\nIikLH8a51rng0QFNAn98D0QIqsc6oexBKdayXTUD+C196Un7Fa62LD4pe5V2\r\nXpCL7ZFj5CvTTcqXo5cTPNV3rOd/35t0OnA/5qwiQhTKmCAYLXb6KEJ8OzVk\r\nuNKWFg/PtNx+RrS/m0APfolNg4ZzPp0vqAMsI3UmdeXFZXJD+d6NRcMXdI6r\r\nsgQrqM3xvJS1aahzVukhxkNueNX4Pi9UwIb4wJwKmt+6he6sX80RPYCjbuLm\r\nMPsqcANxoCMqcDKq9INbocsRZJFiIgkXlrscqsj04k5vOLp7NIeVAZ7WCPmC\r\ncy5Xme/vbdH7A9kbQbtB+XsigINNl4GIOWQlMfDjoEN50ztTsfss37EGYfcn\r\nS2IFrQX/RS20VHCIP9lal9kswPdmfM1gxvU=\r\n=yhaF\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.8.0_1665105888786_0.505418911422657"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.9.0":{"name":"@latticexyz/network","license":"MIT","version":"1.9.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.9.0","@latticexyz/services":"^1.9.0","@latticexyz/solecs":"^1.9.0","@latticexyz/utils":"^1.9.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"a1ad90552165863751b4ee70ec0d351876dedba1","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.9.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-dxFbDmuFDfY8T8fn5MtUMphpTiJgcFIRfotP4+9Lvzelhk1bEqjgNc8eU/I4p39b8ph+BtHubqezrTbM7sQdIg==","shasum":"6a1c53d34140a5b20b193f8e81cdbfcf87b9e0eb","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.9.0.tgz","fileCount":36,"unpackedSize":507587,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGrxnAGYkoFX/PbkRuXnPxeon0jBD1hAU+YkWa8XDHl5AiEAs2Ii9rSVxGQAMSmxvebL/QsMJKv3V9nyu4BdlICsu+s="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjRY5EACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmof9g//eaJQvhq9TsKF3DfTKa7IkjVMdvF1m+TbN0oexlDDs06M/e4F\r\nk4HQ4NqCdCZeiRVMYeiXWpZ3HGGyR8mCU/5RbqAKrct4Tz4Tzcsx53BBfmx/\r\neAAf9auziqQyJeTN87D0ttvaUhuMDJ4Hyqg5ZBmGvODlPyxUzbQ/9kf0r7po\r\nLeBB/npbZOnGSIryBPt4peqVTgGPQH2tm7Q3sPHxzIqV+ftDjQv45R9AsSSp\r\nECPpBIu+CE2Zd/GUFeaLew7Rb1Gr1XmvOGUVQZ3ivKExFHxkLtpSUtljZrn1\r\n+jNxrCeBcleHfr4sAX0GVbiZfs/bKJPECAJbQfO/vqEqJ/DbaF6K93OUc1Zx\r\nBSbjWPQERieuooqOMe0Z7VI978xOWR338+uNm9NNimp1HFKV0imqY4al91Gr\r\ndsUstQPsjHOEUfo1qNb4sNMP+70Jm0BpAcUNVMg5HouPKAWNM08WkXMPryng\r\nLRBLOvITXnFKZ8baSFFO6R/lhZQB4Ldx9lgaAsmF0l0xLRD1A2ojdudBnU4X\r\n65iFFbd0mucVeDEFfpTqMgO60KlvZf4ZcrUOdo5eBBfV++v/0T5tYNlYjUe8\r\n0MuWLHrSqHMqRc5U+tvmV0eK5ylpXYzp7ZnsrmkFA/RIUpxO3+TbOrWoxes7\r\nCvrJ97Tpu0gmXjGD9GDA0avZd5HJj3rij7M=\r\n=Pi4F\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.9.0_1665502788712_0.498680164283827"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.10.0":{"name":"@latticexyz/network","license":"MIT","version":"1.10.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.10.0","@latticexyz/services":"^1.10.0","@latticexyz/solecs":"^1.10.0","@latticexyz/utils":"^1.10.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"f230887b5e9c69ef66f945002b9caea5ff000764","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.10.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-ecJp1m3kOueYPAGVGGR1xL3ASndcmiZx8AmczTH58IRXiOvW0uK1ZSf7vcOqoeTczR/DtxA1O+s+rrShhmCobQ==","shasum":"146cc35973690f8ede62b8222f0a2f886c823eba","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.10.0.tgz","fileCount":36,"unpackedSize":507738,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAqw12sY6brSpY87bDQEdK0hQnnKSc0VEkrD+4B6tK8MAiEA1Sc4ykvtPuPGlJPdn/zFtOn39kgr7b05eJSr1Sktt8s="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjRZX3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmol3BAAiCmFhFaOuhKW7rFJSUJ3ukdKKDvMk0bzuhc4omXbYUfpUaVh\r\nJoilY++QonOE6QIvEL7OLjn2GNbNuVrvF1S/JdGNo9q+vnbqILyIj7AQct/2\r\nsku2cIJRS+oEi58++A1g/rQrmF4SC/ol/PlvwV3mVhS2Gw5Z912G5Ip4wBfL\r\nVInoXOe4LEiEQM59dZehlEpizRKW7IIsUjtkAnNtVrlU5+ROl/Ex7xFP5AIc\r\ndTDQTWLeLDA7ylsONhT4xUgDQCSxoJDkpEsWtaO4xLfIXhlKfGR5WrooB2SC\r\n61QYWsnYHjTCaVufUdewShEpLy4faI/cm7k82DeCcRwsU7nwPzMZbfMF49Yk\r\nTbhXZgo1h8fUiA7uCpmG8BYfrYaJomcqyEgC673OlpKmpKXrQvI4oIuSUxTH\r\nOz5bJFMTT7b+PkvaAWiYS8N6gCLBMVYH4OEnEXEVfv+SYv92ay6sDCInY+6G\r\n7GuqyaJ8vpohayZIO9SsTfa1vlcUuYHDjiYm/roZmWCgvZBJ4qrxi1QjWJxg\r\nYzAlYmCdDg2kidlZInZ4PU0hk0hv0vOAF/YLvPEuYq64ruHkjFCgiKAcKFT5\r\noJEZ6ntASxKw2FRfTY3kVGWwdXe0NPwvg4bFjTdzi+tDecfQPaunjn3XtUhU\r\ns+PK+EN6PHySvf1lxgnOMq2lvsq9TxS45W8=\r\n=xBD+\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.10.0_1665504759235_0.31210567866176486"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.11.0":{"name":"@latticexyz/network","license":"MIT","version":"1.11.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.11.0","@latticexyz/services":"^1.11.0","@latticexyz/solecs":"^1.11.0","@latticexyz/utils":"^1.11.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"b718d759ff4a9e6bd05fbebf42a03f6d7c75f82a","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.11.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-BhywHYZRIsVxgejhDdt1mXcrj3D59TaN8Bv2sseB2DBODy6gvpUY3UndoHvnV1/9EpMs3YnSfc/f+UFvJ+xsVg==","shasum":"7ac0d0e424513e2d484461fbbffd14af19a5360e","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.11.0.tgz","fileCount":36,"unpackedSize":507885,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICavyxqmI2o7rYRjkB7mF881Fs9kAjqdLJ/FzF5VlzTfAiEA1Q6UczA+J/WvntEv0/A+BwRFk64UuIYYk7CiF2YpY8E="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjRa25ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqo8Q/9FjKMgjgI9SIJwnSscY8HzE44S/zrwY8intu71I++q8UXUZgp\r\nDDMH4oGUiSvp9fLZbYLKvlVMESVx5zFUY09jo8AiAQkRKQTmd8Nyney2XJtG\r\nA0SZwz/NYmjBSwmCF+3eTqMQFtV6/kVkQfIyyZJ13oJ0A9Zr6gcMxJfNgHCK\r\nJ7IZEckYKyomtSGiQI4kYKKZac8s1TGBLUeyJexTuGFK2qTpwkNtqbBebY8u\r\nleOJkJUMXQr/0zi+EzZ1aoGAmLRSX0+17av40VFHazQWH2MrEXwhMB64KoQl\r\nfh//9Uf/AkvcEJf3C7S+houhQ+A1qAQtk5sUiIq5b5GraYkLnPlyJxOyFje/\r\nSKgTOElUyZbeXBzMty15tiJBFfmQeKCppRAmUPT/ZkslqwurMyUR6gyHIlfp\r\nuN4RW9ef0pSQEywI938/hRApnWs7dr/gzJRMDipJtk5L8neckgAcx7ro/1zB\r\nieLnFgBFbTZSvvmHVKP6QshLMPHm4GXhfo0iFk9dFdI8IMjaXuX8WufJRTbH\r\nneJJrb6+/w5u6X8e+Mmuf0vHTN1l8+RM5cFNpRMKhld87EK5oVs0zyI6Pcoz\r\npTSYPDBDjV1LSme9fs8x3ITvq8ymuiI5j3iXObNBKmREFisNXXDRrKxQWKRo\r\n70yr2C22UKHgYye4+27bFMLbUPaokCczkqw=\r\n=9YzO\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.11.0_1665510841004_0.049365576602017125"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.12.0":{"name":"@latticexyz/network","license":"MIT","version":"1.12.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.12.0","@latticexyz/services":"^1.12.0","@latticexyz/solecs":"^1.12.0","@latticexyz/utils":"^1.12.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"36f2107bd655c43585584c7b01ddfa3a44c6c1ac","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.12.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-FLwJtiww4MytDNEHbr0tDzf7FZExiKKLiUjPoY+JEEFIIXaCkGUWjZFzj0Z+1WGrarhb0P2KCt+wz6WXtXQjHA==","shasum":"fe5dc44babbd2cd9a09e5a60f1d597eb2ad9f845","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.12.0.tgz","fileCount":36,"unpackedSize":508032,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCpFm5IxxbeIaCqE+PD1IzFrQxScNrFXSy60lF7o7V1lQIhAImbmJX/laOxeCPEfjUYUxNEZY8rigPtQDpphdKLRKqY"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjRrAZACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmojRg/8D6uVvBUChVFb73RGerUVQFaucsOiZdnlHs2RgA8HPzIbNo5n\r\n/xmszwiltrnbEtr+L+PpeGimcLxFq0oPq3ttU3qTYj6HbwXNCUKRtnG7PyWJ\r\noCsPGKzTQ2LW6jgSpLLIQWV8a5znn9zu6/3LGGEZNpnzN3gszqVYM9GRNU8L\r\nizhYFDDLQ0QOxzVSmNYaRV0IeBWL52FQDDsQj/MCsMVpIOI3CosG1rhAp+0c\r\nUL3lxyeCI3Sth0whyGwkwl8EhWeH5lox6oD6wsRUNWLIuCJmPg26+aM3GdpK\r\nYUM3voekxvls3FR4S0bi0Us3dMoInVRe3CAaT/bfex0m8S0o5HmRb6OOy2wR\r\nD2VtE8NYlDfj3epsbC5tjbluQx/fetOLBnyVYVc1HcvDizaiAjnp+c58sNM1\r\nunaKfV1k0HaL7ScpWBUtVRDCcVeXbe5OKBfYNzIlKK9XaW7afeD3jrLUUny7\r\nENUQIth28HdAK+nxDW/ITUV88Wd4qE5OmdtkdlGP5RqWtjjzMTBmEvbNt5VJ\r\n7gtSH5iwMYOC6oXrV5Bnlbc0D1PKXwlyEhZMifFPhXPhQdkFXqRVDykkr0h2\r\nu2ubnNRTK+w3URiDZE6nY313ArQmUaYyDykzXbab558i/B/E7mB/oLcnJiZA\r\nC8o7oVo8672SYNL/Jcom6qpkgYivAE3TyD4=\r\n=xfRO\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.12.0_1665576984774_0.14800568699833327"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.13.0":{"name":"@latticexyz/network","license":"MIT","version":"1.13.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.13.0","@latticexyz/services":"^1.13.0","@latticexyz/solecs":"^1.13.0","@latticexyz/utils":"^1.13.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"7adc7218b75bd47acd108ce392fbd4fe9779a78a","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.13.0","_nodeVersion":"16.15.1","_npmVersion":"lerna/4.0.0/node@v16.15.1+arm64 (darwin)","dist":{"integrity":"sha512-MeZDaLAFxc3ed8TQMLqYfUqB4oZg/B+7pOFsHZ3NL1DoudPPLQnXy05TDVlqYThdBoNOcd3Z5G2oMspQCLjPyw==","shasum":"5562df0f2516c38d5f6f5d76f454863516d02fa6","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.13.0.tgz","fileCount":36,"unpackedSize":508179,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBpDQ14gCyBnTbVSHhno2lHP7H3gnH1N/BRgSrIC4FtEAiBggZx29aT9G/X9AdWk24kHD+xA6JJt0z3kS9SIh26iXg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjSjM0ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqSNw/+N/fX47oLLV+XzjJlzxl2qbZJrTJK6mi17hBOFTHAjodAHAG5\r\noyFjDw2d+CQv3ExC7+BW7kaD8GOvwGydiLAxTx3wGldG06+2dehzlalgMKlq\r\nkthPO3A9si/5xETLUssypT00po/fnMOJ90XWEnskcpStk8OsRfXtRWeFnbfK\r\n8S2OSsuabpJpii4368HclZdL2cn0SMUl6iqfagznQ+sOjKrTJ1ego78q+a+j\r\nmyLzrBIIPavmDBuvHVZ7eoXai2QTn9gM2x8+CcvHi2C37tST8MWhkARI/roe\r\njb1MK59QJHddHSA4ou/E3xltTnJOuId5ALEAXmaxD5K15VInl1YkK8ZsMZx/\r\nydcNrjMV11CL1oYdR+0cVOHFMI5OOm5RFfI833683YJ1YoB9ugQhRm80Clve\r\nO0Sjf9Broq7surLid3DmVXCiwcCAiYv1Lf/+9TexeDibbnc7bNU8JCb355TB\r\nTduzzdi0sXMvEi2Z1e0NogMB4XsAhI28FawQuEACm9dGvw3jJyOu8uyp7XIp\r\nxiOCn4wEpN2PMg63KWPSnn9Tj4ldXstMYqYjX9BOiN0G1n8QmSXZJYfnUv5+\r\nzEITAqJuGNxLLmpwWS4WI/rgQt1TZedf5hMrTohmrHdF2u3HTKu+GlPnMDHJ\r\nTAzc0u1LllSooHdc2bs7mYL3Tofj4//LI0Y=\r\n=JhaB\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.13.0_1665807156239_0.8923018216027883"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.14.2":{"name":"@latticexyz/network","license":"MIT","version":"1.14.2","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.14.2","@latticexyz/services":"^1.14.2","@latticexyz/solecs":"^1.14.2","@latticexyz/utils":"^1.14.2","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"93b9603a95192907998b6e2d011df278c3d9de60","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.14.2","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-wK2SMa0ZaT/k2gItXCu8V5DMsvI5HMdQUehlRCUV7BvroRSB51DCq25K09H3LbzLbZTpxdGntZEfsua63qQL1Q==","shasum":"fb119902298cce3ce93e0f43fc857c9a31db5abc","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.14.2.tgz","fileCount":36,"unpackedSize":508622,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFM2yOAzhiPnfnTQra2n/6FjOHsVpkRz0hi6cl+4gHlQAiBkkWv/bR7wfxBTMMTk2gLfCTcKe4/ntENaYhjEmKeudg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjTt10ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoleQ//ebVfehydei7Y4I+zUVt4oK8q1mXMkPQF4aQy+VbvwC0eVTyP\r\n0QfN6xrDmOaz3oFl2UOO1nLXnvKfdLqL4pS6n6KsoOLA9xIUKYlvqqMWzDP1\r\nYI7vM+Kqa9zXGj2PrB2A/qQaQnrVHeDu/vkSQO/ngYLZOcI/i3Mj/xZo9sj0\r\nok92skT7XJlA8mFlsFxq1/TMNvXJTQjtbWsV/y3zXXrT/VJ1Fqj175GXbDVF\r\n9in58bmJv6ephmnNDrCwyUaOpNFWEMR3rgbKT5ykJbiCekGeE0PVdEUnoFN4\r\nOotnd2KKUvNU80mqRj/WbPSD3iLQnp9Hdpwlnrs5YE1gYcYoehnPJjsB+ws2\r\n19IO/slbEDWmG8pDqeYrCbdF1vZkCQ7/Ks2P4ASkhmnWFtOmhY5Ngug6p6GH\r\nj0ayOSNSGws07fGCLqkVxqqSEgVcNMrvK1AgUnyc7Ps8wYf2UhD94bEDrrL6\r\n1woRPNPUmCi/G1JJFoYMep4w1ZP77hIF2B7ayMq/6XKyrCvEwPTjwXh2iQGu\r\nmqquwEiLi11NCo0VsTLHEKhJebJgJkReRnouxIhvGBA8B1szp+giK3mzev1O\r\nx3AcnuESJ97f4quS+Y8pGBmNFjfjFCMtlYuFzh4mlIaljHBFHJH+SK5067Lk\r\n7i52ypP2ZMqPiBqgBEyIaCN+7N2RYxkx6ew=\r\n=h67x\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.14.2_1666112883860_0.33482789663347545"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.15.0":{"name":"@latticexyz/network","license":"MIT","version":"1.15.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.15.0","@latticexyz/services":"^1.15.0","@latticexyz/solecs":"^1.15.0","@latticexyz/utils":"^1.15.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"bb9d2918bc24abc118710620e2722be29b2d5181","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.15.0","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-v9DD/1+gw+QgnrWZbSnixtD2++D9TKyMuAhd+lrcfH0ANQD6A2RCEQUrMe4THfh5oiQGv1pMbntfzPIharVC3w==","shasum":"8694e51c9c940ca51cc8c09bb797e42edae24d91","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.15.0.tgz","fileCount":36,"unpackedSize":509596,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGJxx+YB51QLQ2dmZA5a1wRKM0QCfc/CnOBNPQmgFo0/AiAnzmNjh43Wa4RsAAFwGjTJufbrypOs2X+LzrlE65NUQQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjTwwKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpQGw/+MHWiKLVb+N7GNU/2OYXbvMHF2giTZUYIS3CNOybe9F2vHJBp\r\njRvnCNMvwyW78XWYeHhzTm6YAMUs5OJ6wUE0M6U5RHU/WFqL0h6uW2pPh9IH\r\n3Akqfh3foiw2GAnZ+NheSIzdAK3W/Ns9D4Y1+Cw3rBHWMNmnLW8f4ajTWMji\r\nKiJvCl67ONeiOESkFm9fAd6U+mRSBy8WjAg1iIbqT6BbTMlviJ/rSgIDTtFA\r\nVKiGMYOBMAkKLUhnq1KRrhDDHNtu03eP25rk8buHM96CF4boGJW6KJeWFmBG\r\nDAr9fuhU+eyAJdobfnXEi54Teks/4k2IfB3UrmqQOYNtl0eIHmr0Prp/8AAR\r\nlCPPTr7qaMcGMGVJPjdL93DJaxSvVJnnTSEK2gN7JU3IAzf3hoKFGtQKUwB2\r\nM/Y4Cnvq8DLuhAZPsP9Y0rwfew4+Od1uSwLttlKmPYw93GODRfyGx+nIg1H2\r\nuf9kQHFB1Rocfs+0PmQXq2jhh3TjC0eFW7gkz9wkfJeNxR4GqAZ4W7wt5ZVq\r\nWpIKPvJKFpKo6xY2a2PAee9LzzEhbdKajFepcq4NA3CAF9scdfKLOObwHQCB\r\nu+1Dhza0DgQRbVLYuHUfrngZeAnCFq+sep9KnPr/rvFewahrUUd5eBT10csz\r\n4oXj11e7famUl21PEGQMS56y1KWSpTo+zHs=\r\n=js5W\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.15.0_1666124810627_0.2096614066022"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.16.0":{"name":"@latticexyz/network","license":"MIT","version":"1.16.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.16.0","@latticexyz/services":"^1.16.0","@latticexyz/solecs":"^1.16.0","@latticexyz/utils":"^1.16.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"b9e8909cfe6de3e2d1b3aab8bd15432cde76cafd","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.16.0","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-GEeTrbuAGZfbpXMGHXC/HdCEqCvlM/jlwTZrhxfHGdbijeoeE1HUIM3TR9+QeDKI6pK13dVvEPTHxfDA0Vq2+Q==","shasum":"db8011d9516a4fee6742083269c5c997d52cdd80","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.16.0.tgz","fileCount":36,"unpackedSize":519024,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC0Yh2ci6GHrUqiax1jUs8FsUICByE1ZkJIMsXnE42qXAiAQfyx2OHguwMAENGS0enryZYvztPpfMMTxDr6bGpsLwA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjUGX/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqtJBAApOCJBpFyItJRECoKo4UpvV/C0DXDOf2DC4H+EnWchyXQGQ2M\r\nm53DcMkxjvPxUsARCvX/MmjBge3BQhxCxYIuM/j/hS4izLYDLmnWgCOVqTF6\r\n1yllsHQpZYq+0szMXlY7+GtJ3R2XE4+cydImtUr6OE4tYpz7SYylYHfwiXA4\r\n+GogNT9DBulip4BBoZbzutW6H+qzEH7uDEiW65Uk8M0pTMdKGaPkCjPM3Bs8\r\nHuuJWyvP91prvSm7tXGVBwWHRdsA8Zy3yBGilx6FpXOZl61SeeofaoYJUD1r\r\n7LrsGb8QH1T7q9Jvb1vKL/QVvpp+twQV7C9EVgv/VhLuYdFgoUdig/Y4Bkk+\r\nTbLlTFENEy875A3ieGB/9+QxtvgdVErEF4HI2U7QV9moONhpMDIocp3bOQAe\r\n0FNMRdI9Lsw8MeUamhBDUHKtIjSneV09l1A2YIQ4uJ1bEhk8FZzFrWJxDhWi\r\nb8c/TbmsZbUKO7bIJF1mql/NF5ay5eGv6kZcirK18YtHHpxR7iMJmC5dY50A\r\n0RBQd3uQn5CaQZlIkoPKPcoKFZIzbiRPN5YatANtcKTriXZoMMRnFHN+9z5O\r\nLgCHevWoI6cLqvuOGcCwHVm5gnO/ncTXTBRQbjNwqDCkRNBK5EvANn805q+E\r\ndkMCAaHEt5YrYrS1jdvT1e3oR+BoqXN1JzA=\r\n=xnf9\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.16.0_1666213374971_0.8615098159345107"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.17.0":{"name":"@latticexyz/network","license":"MIT","version":"1.17.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.17.0","@latticexyz/services":"^1.17.0","@latticexyz/solecs":"^1.17.0","@latticexyz/utils":"^1.17.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"0b624a87163f9cba3b523b5cd677f336a5262740","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.17.0","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-mChmUl0EIOKDtDYRDGJkE/0PtxM9XWXXQC/Sv7DnnIUiOqpbYSzCDAJD52N+HmGFN2V0kcTu5Py39o6GGrbZuw==","shasum":"fc6fa223c90f1e538d637617db1c29e4b2b47e61","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.17.0.tgz","fileCount":36,"unpackedSize":520308,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGDrgft8Xc9YIWzvRKPmI1NmZtfG92w/DEt6SZ9ZPgK2AiB0Agy2McqSwBbdLHDj4ySVN8ey78B/K7QKSBMCUqmyog=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjUH1zACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmopvg//WI7fzUc9W/77ghPq49GSaYsyBVoMm99PtAjVj93O1lUQcA3K\r\nsQJaQCgCfYcuMDFvj1LVbFj0NM6OiUr8OBxwCquq99YVFz9Rx30gHiRzMycx\r\nkcSwTaEiFLEplDn8e//ZnNUygshMBUQPY3b+5LEOkexgXaImn6Pk97aygV8X\r\nq6NuB14tOR0w5LcUBgsOHOoOYEAtczOoqYk2CfSjvu1GMmtsK9f/l3PpK0WJ\r\nzuCkIsGQqSW5qbULIjtyybYIOpbKoTYJvXG24lssbnKxzHix9BM/JObxZ91E\r\n+dxWHEsHZ234SgHKr1cFsjPIGnh7cKqhjsA84UuNGF4cOoIPEJ3qJGb0Up02\r\n7q3MIqrMvU9tGVwK1zd7O9Qbis2/te31kwCPk0V99AdLeIiXEAb8VtXDW4B6\r\nRc2KUyPCmvliGyAXJ8qbOJ7pNOvC95Sg9ImemxgyXms9F/VEp6ZaXLtbfWZS\r\nPqy9ymVJgVoOhsifHcnZ1eiVq7+D5rVgvQuXnmQsWqofTiAFo1IR9cG/O0h8\r\nBvUPJCSIf/hUytwM05mJSp5co6O93+pB1J2jlV/+BTU3lDZbn7vRNwFGLIek\r\nbTZoQEelHEPs819i81tg3oqi12wsdS0AyURWxAQyfYDnRoHhWNS6MN0p+71S\r\n6kBfnkZF+CVUynQpYXjXyDmNfUtgqg9AxgI=\r\n=kbiH\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.17.0_1666219378973_0.34465783827811247"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.18.0":{"name":"@latticexyz/network","license":"MIT","version":"1.18.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.18.0","@latticexyz/services":"^1.18.0","@latticexyz/solecs":"^1.18.0","@latticexyz/utils":"^1.18.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"d579fab7e081e0208beb90bcb23f25e711897ba2","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.18.0","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-PdyN9MQ6RMfCV2wW1aGEbSCELYR1PerS/w993kFkqSoc834yo5nbeU6Wz3ap2Gj3dlHC1eiuMPzj0xZVuP5xOQ==","shasum":"90d91fc3180863501cc40e69061f12fd8e610aa8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.18.0.tgz","fileCount":36,"unpackedSize":523143,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDCaQGgq+HAsLglXm3qeJr+5VIkJxpNH7NF8s3+P8YgwAiEArPizdgKg+Oi0Y9jsaTCC30yX4JEC/jU5HTYr/BZejkc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjUrjIACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrxoA//bUl+mOevzMlwlYq3inCOI61LXLO9xJ7/GVScg0VP2X+V4gig\r\nGal/8jSN5wfJyJsufAE3TOivsr1iGj1nXDCQll81NMFrzI/9oS6oAMB1B0A8\r\n4pPK2TnJWQzJkHIW8LmFbtohSgUaih4FJ3w91aLHXQODIPPK2n4RgKaATrwi\r\nziGo4/0b10pjimphQddXGCUowBU59Yj3LS7k3Uvt3XtNN4iXntwCLuATBeDN\r\n8x6vZPxSBc7se2111wabl4GOZIhqkp4CMc+ELe890vcXuprdacNH5ukff8Ns\r\nfJjVDyHOX6kBwN5CxjqnDO3/m0E/14oAxarbfwEi2aDlntyMGj3+VB0kXN7H\r\nckEbsWW8qG/9CqFM0v2IIB4UfXj3tvy1lFW22rpLl3YJqodyrq+zNO3Z3I4/\r\n0cFc/niWOEdzkLo9k7D2/NCYFY2yzgMLd3GmbeuO118r0yt+NeLf3hcJaaEO\r\nOj1s6sp18FFjDPXK2ql6toOAwgFiRWeXKdNRgTePHo4HQIXoV2oTah2Z2YET\r\ny9dDYpZ5bOcRlhSr4rTaDbGRnFilNyHJuo2Ob57sWKz93Jrrj825UIXlFgX/\r\n1OKCwYxzPEqOE4QAGCWNmH83WDnaoqT2syVtdj4FGuiRNGtsN2R7oqAjcP79\r\ne3J9IORBJ503hd8gOkjFW6PmaXRWX8yrUjw=\r\n=RfZV\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.18.0_1666365639782_0.9575528966524496"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.19.0":{"name":"@latticexyz/network","license":"MIT","version":"1.19.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.19.0","@latticexyz/services":"^1.19.0","@latticexyz/solecs":"^1.19.0","@latticexyz/utils":"^1.19.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"8df93fb8c25e8313fa2c0080faf947824665acce","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.19.0","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-PRtZ/CHKwG/3VR5PZ91zjIf6fAEfgkPDpFj9eSqCUvTu3XxooWVYlOK66BlR0keWLzPMryo7kcWbE8HSzmR0xQ==","shasum":"7d2e4a9f2cb97548b8dc198798d2628710d5a470","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.19.0.tgz","fileCount":36,"unpackedSize":523461,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCY2yo6zaDcnw1iiDZmCkR1fLPG4HwaioGPzSLjI7d9iAIhALw4TtJO8mOPNZwmhAZw8pA99BQCg0iVFQuk7eFdVHdm"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjUyumACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrK9hAAkPXFXJLuiogyPO/bc5SEGumFxW+Z807JUkmYUuM2ZOktXtHQ\r\nPNvjyHinmZss9PESCXXFufKfvIsJOqx+aU+THrNw8nZ40XG9mwmElh9uAnSM\r\nP1HTBopEEF1JSDbrQgC/SG25SI1af0Nr8ryZWLKxrweAQQrCjRXGtiQxPnC4\r\nhAYgE1u3h3JzkZo71VCu1ZAMVBXOTFJhpeenEhF101Ge45TD5/V/nBfEBOvz\r\neLV8etyZ2QSy8dFgmsd1P0C0+V15qUKIrx1HLAbfkd7v5y5iwNs/SC5/Xky+\r\nw1vMd/gwQH4yDW/ygaoaItQhiuij/YMLWcRK9KlBYssqokY2AQRPztNZZLi8\r\nJWVv1wYNtDXIxPnBkHj3PhBDc0FE8EVDj8bEu/aZ6PGmQMCndEuddQyOhz+i\r\nC4DUeHMfzTJYpWzVZJhMH+BGl58YfrLAgrmpP8ZYRP1L0+8lvsXnaNAajscZ\r\n635B6Sh4/jAAbRL0qN8ygjS0HPuJi1KY6oAiaWQA5DUfLEGh9gFnKcSs0wpU\r\n/HChcXaaxrYMXz68DyIBszam+nFlk4bSsRITvSRPB6AGTRc2NCVm3/jCipm3\r\nld7fR0XFfRy6LT8eFfvUrxa8pYnHY2TYOvKfHD7bIi6tlm/pTGr1sNediIJG\r\nYMEVU6HTxRvAVLd4eKNWEgimWQcevPZ0CTE=\r\n=WxVF\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.19.0_1666395046599_0.8539519492447063"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.20.0":{"name":"@latticexyz/network","license":"MIT","version":"1.20.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.20.0","@latticexyz/services":"^1.20.0","@latticexyz/solecs":"^1.20.0","@latticexyz/utils":"^1.20.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"63acb4a8214a9397cf9a75a05f14f51266126886","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.20.0","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-y1TybeoES1Ju/8d5MLlcFWdoDInnkqFXP6Tj7yKaYfE7be8oXfcDazAtNEEo+StFuOP8ITNtQWFqplwYZ4fTCA==","shasum":"f547421d6f5539f40ea022bde5442948834ddd45","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.20.0.tgz","fileCount":36,"unpackedSize":523608,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE8H99W949PaBqx6aaNdLfQfI4OFjBddOrOJPxRAu00TAiEA1gbs560DWXznqIE3+YA6nB9nQpBXH5T8LAr0HhtousE="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjVH2kACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrAJw/+MLkYb8qWYkjSPoM4k33zesyCeqywpWiIbi0J+SdNd/GiDBfY\r\n8H9AutI3OHAcsPndlTEquDKvH+qlf2/go6C1AOojg79RhopLs/DKE5Xg++NV\r\nDQly1tKnWu7Tgefoez2eUX9xgYGXaJjfawHxGxB43gFMK9LjTrV8cYQZvkVC\r\nBDdb0i4r+FBskzqpTM2xWhRye0X+wLg/FrE1zKlsH0LU4yDI6OWoypEq19gm\r\nMV+WOBmWotdBc9+sMJFyNFYjia86kklJytDbO0ZsWOppls+RSTsX0ncbEkxm\r\nATcBoKQWbY/PkxfK0tSbiXK8NwgFF0nKtsdMimg1PFVNQdplizRboQD6M5wR\r\n8zICxjjedWcjwvgcyfAYIXe5QgY+TigmhiOuMpF9ulDh8Xcx5Z1qkpsDz28k\r\nI5Dk7QJ+Mlj9T9FpCmgtQ6b1mi4I73QzYKSuD+lgL+mNxq+2zp9aXihxMtWG\r\n9efVpeahDK9+LItVwE7YeN7ABn7VOS5tjyydGfcpb46yRQVJti9OGCa9HakW\r\neFWdPLIWQBZZ6bnorPB3R0twvHe+FFYNB4Ro/ZPZaLw3tIppvdpFQoK7NKLK\r\nBpklkC7i2TacDrvYHNPwzlJTwFYbh24W4H2I/O5VjeChU8upq8m4uTLO3T0H\r\nKy7GKvPol/KOF02LCs/VuDNOOEjPCyA286k=\r\n=+NnI\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.20.0_1666481571892_0.6770246822922041"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.21.0":{"name":"@latticexyz/network","license":"MIT","version":"1.21.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.21.0","@latticexyz/services":"^1.21.0","@latticexyz/solecs":"^1.21.0","@latticexyz/utils":"^1.21.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"be5555c03345795c61f992352ae5a0c50ee8b96e","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.21.0","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-IpL0NjNKNajMe87RUnISn+Pc7jFuWxUiBiUnAuW18+dNfRCOJ83pdIrc+ZIJceJcXg4kOEhSQeVCkVHiW43SaA==","shasum":"b6468af18a8e6441416ebaa62e4fb124c8d60e03","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.21.0.tgz","fileCount":36,"unpackedSize":531402,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGrpHZkUVkaQ85aQ62G/e1fOGIhJDfrXoYnp2A65jspwAiEAgOYp5T6oorrMJ3c6sfbgxqGBY78O1nNuoIWBjcsdeIc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWQArACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr+OQ//Z4Trb6mHHWbWamI72b8YpmPXD4dhlWNQm6wbFFNWF9+1oVa0\r\niaEW9RJRwbB3+4aEgi4xATHVMgT28WqybvjRBTpCpcKpPcyFGTqF1BLmaqrU\r\nocgxxmUon+rO43AbMDtEFTko3WsXI7oKq+2lSjbBBnx0mmc8GvjreYC91ySe\r\nbmJ8WQzIuHKZcXw55FrHurfVbyHjIx2LD0aUvmBII0w4JSOF3A9ICI80plK4\r\njh3hRvKk/IExzY5PkZ3WKj2kdMKdydKM94XrinU0ET826RjWl4Kbuk9R5dCl\r\nUUB7LdVZEwKRrAKNvkWmbAE5DkomItzzkX2eyP2EWEmX5XHOeWbg+JOOLWB7\r\nZa2rOc7b1uYOnYiZTdAJB+5VESwchfoVi76bzRBVWB5++OggwriDXhbf/wpK\r\n93BhlIbEnIyiTu9Av0qLTx7zI++4ArRro7/tFllAXXZIEZiAmaIkXNkXpmHh\r\nrFV9bgOUhf9ujsm7r33iQxs8eO3Ya4KzCzX+LSqxN0VlJjQkIEJ8E88nbvHz\r\nGSqzTEX+zZ37jTpL2aJ0ZGX725juqEoA/2aKAY8LbjAZNm5smVxB9MlKmY8M\r\nfcHyocd36yfFklVbvAK77VZspdj55zD2Fsmq6A1d5PBJxtuAbiMmYXVzJZYs\r\ncTUyHieGgHetDgYDPYvREyGrMcJCT21Xsr4=\r\n=B9eU\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.21.0_1666777131669_0.7519462515540585"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.22.0":{"name":"@latticexyz/network","license":"MIT","version":"1.22.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.22.0","@latticexyz/services":"^1.22.0","@latticexyz/solecs":"^1.22.0","@latticexyz/utils":"^1.22.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"78ba7385990089c3549ea63af81bff554da9dc5b","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.22.0","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-iNriaE/J30eSKxBZfSMs4GTDCIxUZbi+RUmyX+uAMwkgapRrOGFvLmFLHuETwW0benU196PdFpZnd4By4uLyzQ==","shasum":"2b08137f8adbc62fd9e66e80540c5da5d48d9b56","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.22.0.tgz","fileCount":36,"unpackedSize":532929,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHgVYg9y8/BtwRC7R214ZdO/SoMENTsIMQ/O2CyAOs/5AiBBSJ0uQdNNtYWaTDC3QYa0EDOR0mCurN0Rvkfw6H9suw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWWEYACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqCqBAAk56jQS53LrTRh0wEeNmeFiyKOOiUoESDpOgIzqbNJT/Bzi29\r\n7tCHDitKq2w/eaX7JCLGrK9CS2hHwHtob9uNW62zgEzKb/QJsWKRcWsG9EOb\r\nIoKe7BQADz8mL+SDSkEv4YI/eugLdpZJylPZZ/y0xKMM35hC/ZFr15xnW843\r\nGLePSfsb8+Sb9Hag6W1API/UEuIMJfCQgQFYjVXkNxqfFSGC14a4mrllFZJ5\r\n9c/lzKYe9yD0Hkpk3ZyYrAYLRiVyXgxOWSliIjfGP2Imh0HGeVMRqyYwdv83\r\ny14Gssk1of7AyhN+R2S8yvFTt+raKTaks5Nfh0l9gs6Wk/DP429TbAsweHMn\r\n4uwc/+NjV3VqA+iZ03CY6+uU9ohw2ULt3pDI0TOg4tl1WvtdP5BU0KxhLJ5q\r\nWQFbsQrJi9NSLNxL+kAS7A3HZY2Pi9bcKE1Nwc9LMu/ttQYaM4ayCKkxrjo9\r\nPkSOW3V5ChPTCv1KJFS3uymR8LT0Atc4zG55ZgkH/hCg/4Guqj4MHXDLz3el\r\naKw6zqStq533Rv6JjZrZsFQ8XPR5TSwdIDK8PFcz1FwE3ZwgntAJqJVRgSVT\r\nVccI6gyvoqCGpWJaXBlS/aStT5CBvaZuWfEPWvJwXQeJCw4vPgT1Z7f7h6j2\r\nxPNm2tReoqmv0pKAbzvhwb4QhMpYaHDu1g8=\r\n=6j8K\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.22.0_1666801944277_0.7738415392781661"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.23.0":{"name":"@latticexyz/network","license":"MIT","version":"1.23.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.23.0","@latticexyz/services":"^1.23.0","@latticexyz/solecs":"^1.23.0","@latticexyz/utils":"^1.23.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"108c10b149260f0f38d78c97c7328bf3790dd5e7","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.23.0","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-Vrs5ADAiOA5XuxWqlQgDuZpYkrsJirAwdEj/L2kbqibzsLE4lyRMHbMti2wN2WqXmSJTihfsi7hNEn258Ych3g==","shasum":"65216f94135cfb46632a9bc8427065d797e28ffa","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.23.0.tgz","fileCount":36,"unpackedSize":533076,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDIGpNeNAn2ARR0arAxspvZL4t7ygmHy9MbB2HoOZg3AAiAtlXo0TuS/3DXEbjX/5sHPl5MNowbcbKRgtZUNGhCazw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWW2HACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp7lw//di4whHYLWh3QQAeFs3cflw5fgloOMAp+Y89D9ZVQ1/gS0fzL\r\nWPyNHAYaVUSqGorVFlKHrIHpDYtJP+RiVo1337Cobs81Qb+C+7aKq2k+a3dk\r\npNofXYqzRGj0mVGafFx3rQ7rtY4cPbKPW3JYrkgjhUWynkJqAIUadGhM+wn7\r\nKTQHdqxKWxspQCG5+Zfd5RMGR6OvnzbEm6aToi+fBtYU5YgcwEWO4o9MvmcS\r\nr/mGt4yej6oDZH43QYBDwcxYSnbMcqyqadqe2SobKnJLVECIbpLHEipDRSPZ\r\nVf+C6sQgF6AH84fJ2ja6UBBVhxt0VV4jDG6Cr7TrpgVMHWEyIwdrYegO/Odn\r\n/H3Wye5YTsAMYEI0WBeIPJJx5i/aWcXBJZ6+qBRgJBCDnNhmGz7R2arlix4w\r\nsFkCoDpSK/LVQfJFBnSVlRg1TYkSpQF2DigPyqZ+/sJ56LPMbaqOjrkL+IDG\r\nSNtaCU/luR3AK0jkFXAUyKoeMeG0ews2Uoa4yJHoSl2WIdcs4EPY7RRF1OX4\r\n25OmWC0UI67kDX0uXOpVuIIKu/1rLAJEf91MpvGyRcrWjBb8DcN1X3+kIxA1\r\nV/Z9K4yazVWGF3gZasbOkYDlnQ1jwulsseaj65pEIQ2hFK96kaHI7TDO0eDW\r\n8/Y7eQ0SF1a2Vhgzf4crxhZeGvivZSyzLZA=\r\n=tlIx\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.23.0_1666805126905_0.21968807916673572"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.23.1":{"name":"@latticexyz/network","license":"MIT","version":"1.23.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.23.1","@latticexyz/services":"^1.23.1","@latticexyz/solecs":"^1.23.1","@latticexyz/utils":"^1.23.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"b568e2d43e5de9aa5a5486a3c3fb70ba4f878842","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.23.1","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-HP0xhpioWd+MU23tyqGyNoIDPzHbkVyinrWRCskwPqT3a/Y5ddqSBcbNzBv7fFrv7jdugkeFT9OM2BRgtqxEmw==","shasum":"bbf5d4b3d42f04705fae2a62b3302421b620ba26","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.23.1.tgz","fileCount":36,"unpackedSize":533224,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFRniEW7REVWgYXfpXQ7FXkswRodWHAPf14KS28xhHX7AiEAvgBakfS3UimlkHbc7BUYmijRlEsZgGo9u0pyi66Sfbk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjXCz2ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrWEQ/+LDOE37njCfXsVVZwAx1n+D/vJtRbbr42WUbPkqV9B/MXL2IA\r\nvxYnQwZB9zaM5JKBmrjejXnihKPs06OMmOl3KE5tu2U9mkeL2SGeUepkxP9O\r\nJWEhTMj1h4zRIUGpgaA1Za7Ns8QJ4lVN2xVxn1yubzLU9XrVelMvCJRSdIcd\r\ndeWfB1/OFwKuOkvRr/R1XCghPHlFteS+PWASjLJsXclYPwJss7k860t0nFWj\r\nPNESwc0dAm1q4xirXHjc+iQ3rxdSQpcatujbq9Bd8zRaYi/xvOIBUjPMEA+B\r\nmEf4c+QH98Ittzqh5Bww6IBXtKqxxaThax3wAkcpRR9ifg995OT2MruzwFBx\r\nCgf2JLBkMckOBAxsGbuHMk0AlViImCTZZ+Rlli1syIZu+LOSfNPrXNstAESF\r\nDbGR4R+Prav+lrz6QZDBrK6LfE+cCYWaAc9bwbbxM8TbfQl/6ifch2UTHvww\r\nczWUh7+3og8pCWXWCUifIJ6WOKqoAc3f41+F+GQE9vdeKFf+IDdlCFztlL7k\r\nAbRdIIbPsNIWXZnxndDl6+cTDVsxJ038WumLjk8X2Csqd9yGjal9Fr31SqgM\r\nto9lw0FC6823vc8jJbWoriO1bW/sFtZ5v2QWeaUmJjry1GHSJ9cNVODXF/EK\r\nkbueBreYxY/wFb+U/BG83+MoNWr9wcdNllQ=\r\n=7UDN\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.23.1_1666985206796_0.6018866276061523"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.24.0":{"name":"@latticexyz/network","license":"MIT","version":"1.24.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.24.0","@latticexyz/services":"^1.24.0","@latticexyz/solecs":"^1.24.0","@latticexyz/utils":"^1.24.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"7d78c074eac7ac8455febcad474dcf50ac6489f7","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.24.0","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-Cax9RBLStQdQZba+XIWdPLs2HvrAbw/7kOImSLcCE2Qka3Up2voNKBKW7086txKgC+mWAUkc/21TcuBEyjyzAg==","shasum":"7b4e3e04672ae35ce0a299e14f82c828081937e3","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.24.0.tgz","fileCount":36,"unpackedSize":541678,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGhzcH3WiqhaH+npt5GVVIyWrc9jdLeSsK3TfsES6x9MAiB/sNuGFSKjNoMrUKzHPxuRFUKbvVFEqNbInYb1oBVgtQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjXD73ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp6HA//TUwWREN8DJtoPipKtBWP5/7HnpoAv8a6L8Vm7HwETJ5S9gbZ\r\nv9qP7A8CAeWbsY4bgsb58ZAx1aqL6bh6hbq4mqzymG5MPMUD2CSqk42UQvD/\r\nRNdXlp6l5U6p1mZSpnXOh4kEPKh9GuBdQGY+PaTuzmmqqfqAjrD45KP0XbK3\r\nDKcofB6VQgibV7lQOC0QkkzqQ5XCF89hYoGOjjXcYJ5r206X0PWQfgQlWXOl\r\nqjU+0vpBEzuLXUGifWM+6SCch8F4yXWxmVfLZFmV0yxmOB56bO+ckJ3QG/0A\r\nhO++0httxnR5Ex5vhhA46802SC/FjPRL+CvazBo8zmZ9DucVpqW6hLFu/uM1\r\nrFE6xzNR6y3IN2lpRFSCfwbGMBszvaLVtcZin/bher/3LJslkwCRXeQ9uCdQ\r\nTRQdsY4+qH6PA0vRW2vpea/hX0C9scBToEmznL8AxNl7BfekEGlbIJchWlXs\r\nCjQKCpmtMVqdGZ9bbG+AYneXDzPiMdxYQxKRzQc3M2JVxHlBP/v/Oe8RRUeI\r\n/XPu7faOn9Ud9i4Dvg8t+Fy8ywpKlEiH5sFeSCaJMWYhvtBWukXAljfRnY/H\r\nDM8YT3g0xeSv/AMYmwPnEDbyNk6/eYRpBKps3z+liM18NOXWNyAeT4Cf/4XA\r\nCEITo//u8bSG46HKWQ4+5NAlwXY83IwZvU8=\r\n=IUzv\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.24.0_1666989814865_0.8919547818352904"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.24.1":{"name":"@latticexyz/network","license":"MIT","version":"1.24.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.24.1","@latticexyz/services":"^1.24.1","@latticexyz/solecs":"^1.24.1","@latticexyz/utils":"^1.24.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"d728021b94d6bbbf12e8395c861cffc2e307ae0b","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.24.1","_nodeVersion":"18.11.0","_npmVersion":"lerna/4.0.0/node@v18.11.0+arm64 (darwin)","dist":{"integrity":"sha512-qGdwLBiPAvA77B+xFg8cIvH/aBOW9EF+PsOofvHj566Uoyexv+lifyZcFb6nV8MRTEVg99alhEhn6wp3vj6f2A==","shasum":"5ee36ec390949c5aeaa1c5b4a1e66583c8097a12","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.24.1.tgz","fileCount":36,"unpackedSize":541826,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD6E4diIY8I/U2XjtGAXkmh6HH7uNiNHjzC/f6pvyg4gQIgDlW71ogsL4Tt0yksP3Bb91D/jPhfobPDqYHYkO4qE4s="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjXRU+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpVlw//RVO6uj7AaAA/hlGwmnjdDnbHsPgiwEKibMqDiXKGk5o6sxDw\r\n2in4u6hKfepem3jVhvHJQVPnWeTVyugj0R79os+hVnmGBcT6iVRrEmqGO6ga\r\nC0rIXTyy9ttJhoCfRk8wV4fh3ESz8nz2ldqd3jBay8Q8VvYR/vNrYloRkYJ7\r\nFTw1V2QviMxxl+ZHjil96JI6IcJZ4eDEvM/TRFTquIjJWM9bdAFcX/4eOOmi\r\nSrUD8E0QyOb94LgOVu4nJ9pckgWt0UNKlowbiEcLzSZN67Lywgf+BaBj7IDt\r\nogto5DhmL1mFSZS2jdHSl6uIKydG3+KHT0pCfRSkP164TBaOuWCosch4I+Y5\r\n99a2j0mw+S5d4yvFudBcUtqwAnw/2RHcT93ktqHSFtC8EoWJPl7U0sQw9cVn\r\nKtsJWQnAeJwNRm+qAXQydnA0chreVW9lSnwEdtGhFIHPG1Xm+L/sGXyMtUVm\r\n7ZMpxYXyMtoX9rJ5exeJDuUuS9ONr6FHf/KmbmvuQ15dZ4BJxsMNJC3r+Dl5\r\nxW1jfNNqMf/ZtWdnzhT0TgwoNXzdGdhGYhOY5JmGvln9NSuwyukrg4kukPEQ\r\ndS7/ugalu75gAYzyBOPIfDCkUP3BK/pcKPAZ2CL1oemqW/rgGpp7gZlcGlj2\r\nd6MLUvlYd8k1/1PUaiKQk03NBnc0sah+SfM=\r\n=OX4P\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"bytes@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.24.1_1667044670296_0.3370210748653246"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.25.1":{"name":"@latticexyz/network","license":"MIT","version":"1.25.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.25.1","@latticexyz/services":"^1.25.1","@latticexyz/solecs":"^1.25.1","@latticexyz/utils":"^1.25.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"167daad86b8a665ec9f5a48afc88bfc7a987d3bc","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.25.1","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-c3OcJwi5h3lb1rxAWWEpIDScsglvgMTVofOCVmDXKU8hZmlc2xhrGHJKTO9r8Pd84G6wcdwUXN0SILbXOJs31Q==","shasum":"a2964e940bcbd0916e75683a661df8052931ec6e","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.25.1.tgz","fileCount":37,"unpackedSize":545035,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAjfD+PNwugCwifwKg0klBNQ7rvxkYxDQC2wdykMqLzLAiEAt8U6sTx86eGjIDirfSdIns7xvhx0rpIHevFJtF8+EEw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjY/e8ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoyXQ//XiqmiscOzfoF+o1ycpjbPGMPnid7Sup11l58v9lzuBzF1Lpn\r\nDQxn8Po0Wwex8NxTPwOLU1pOpUhVrZgeb9k0fHnoslkUd9onQgQeUZ/dYuGp\r\nDO4INw/9wWN73LzNW3jzgDnzit9CCKxpHUgrbW8HnQuwM/aaxzAlZkNurPir\r\niGt6YrifUntwXEqdX3iRyrcY51zMFdpU3XEWeAy4RtGzZbE89M8kzPYwKM4D\r\njk/oLLjPE+9SWPvyp7dwGSZxOhvjB9ysSTtrERgYknWmHj1ITmY8cAO5qppq\r\nsH4OfcKByVwcWVxG2yAx9nMRNtJS1imHcTwIOCelwkMn/9Gtsa+Ecb2eu72k\r\nteAgIZkQ6V1jMCiRLroVDWAUq3ffNVokegQMdV0jHzIjmoQQB5Z16sLlDze1\r\n5a6LQq3kGJX2K12aVCgXUoWg+T8r0z2S37jmCBpCluNJ0f91ljKonSpV5faA\r\nXavGmj/JUtCoKV37NlUW6gKSSB47IbqTvY15x0rzYrJ+mRNAmSFu7ueC8GWm\r\nWv2UTABBq/BUJ8/39h5cAfmH9xD6IqTrBBSavfUF8yh4MihVAiDClRBz1PqA\r\n/JAz+DWHu33Nl/47gQAxpaOW1ijokjyPQiZ0VhFpWOjOo3qlbI3F3DkK3Y45\r\nWgbuEyEUKOWlWFuLZkLJW4z9EhFn54Jr9W4=\r\n=C5D6\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.25.1_1667495867850_0.07161259920631857"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.26.0":{"name":"@latticexyz/network","license":"MIT","version":"1.26.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.26.0","@latticexyz/services":"^1.26.0","@latticexyz/solecs":"^1.26.0","@latticexyz/utils":"^1.26.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"e1036af748f9640f2d21e823458b3aa769dbb443","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.26.0","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-FNkJGHIpQ9fo7Bhw8C/LBIeeDR/YhF52o6mHdYrGuDbG46uLM3GZleOrIR7Adm/xY5HavnmPiiUGHSLWgh5A3w==","shasum":"84b35d60a54c60276064deb035af00dd5936f717","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.26.0.tgz","fileCount":37,"unpackedSize":546641,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDKGxIcXH6QaG4oHnyt9Kd49XHi0HfMYEVuskx5a87kZQIgLoTfPZE2h8g4GM0vMC1tCPmqgsUW5GqmpCwlMoWgP+o="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjaSt9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpVrA/9HI8Tu8G11rFbKj1n6i1MO/ch+45mn0l4tusE0Bvlxs7AObqh\r\ncoCvoj67sTDiwgpXmgMxx9n5ZHuZPPdq0iFcfuILddoL92x6Ab1JH+k0axWG\r\nCWhRWN8zwlv2bYspvbipJO52+qQKKxDOyTWpHHyyR1c2z5FIPULKOnXcnSpm\r\n3Si+NE4Nfp4eTlHDcPVTq3LRVQPRQrnyoA36QZYbmBL854DK/+xNaaCp0KlH\r\nz6gBMXQxhnto93zNsonIOhG+W1dRiT9904jesl83KgnJcFv/oLNvGJ4pn3iS\r\nm/EYOlkktNQdYGmR7Y6JvZgNyaoDTMardLcxT/ooFeTNLnejDeJjQ8M77Ah1\r\n+b2/PNxqbJ58XWEHay7DZ+pij2Cs2OZPoL0EWf5YLZxgixpm50xGult8jJhB\r\nGk0HcDc2lmwMbiFPA9LukAwh4vkb+N5zrBD7ss8ArXxQwdUkxge3XwUdQCMd\r\n9+d64ZUbngjRAGjnF6l3xftSqT7x/lCqtsOTJlMZKowTdER+QN2nqzw/dyoK\r\nyBPXJ3Vy+8FR0Zttm88o13KppsSyAeypCi1huj/vHfAo9GBOueSreK/inXIq\r\n8Znrl6hRgD3dSws/rrphlXnJ22Dix57GUIv5K8RvClKJOOLabRwiCX390klI\r\nIAOeLPLCOyMcIc6uZLV0GEa0kJrrqA4Bi6o=\r\n=JV2h\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.26.0_1667836797240_0.8764184079803707"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.27.1":{"name":"@latticexyz/network","license":"MIT","version":"1.27.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.27.1","@latticexyz/services":"^1.27.1","@latticexyz/solecs":"^1.27.1","@latticexyz/utils":"^1.27.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"cd8f0bc1cdd2e83dfb47f625948f0d58c2124097","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.27.1","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-hVLKQPuv9/cMiQ6QJRuS4+gp2eSQZ8scxZnFTEqREdjsA9t4sJtTJSaySY4aBpqVF3Xp3iYhAEyXeZ9tCb6hCw==","shasum":"57eea74bdb9e65e6db4de70f945aa2ae749a93ef","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.27.1.tgz","fileCount":37,"unpackedSize":547208,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICH5DfqIuESBFlXNp/UFlRDy9v23d6L5yDSFF+k4xGLZAiEAmBtq+MWXT5eXP4TyYjgQu8I5Oc1+jrcN4bgeFTkgwME="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjc+4KACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrUVg//dByV9Yc+Mdnsegp3LrCrNCZaJoLZ8izP4Uuf4dmVw3NnMNy6\r\nfjHTk0K72dcz2HrZ7Lt6Qzwqmgt+QDwKWkevh+n3du8GI6pByofbc8vPY+5h\r\nYt1FGINwpuUraLsI6hKNCuVycuDMTIsherl12z03MNRsnXh12YAIZbr/F/pN\r\nWhPrlYULJ4RGidlXLtBw0TWl26kp4vJEdQkJXv9ZaufKRZbctDwNbLB+ZY5w\r\nLIu7cUMa0+G60YI6Mq2SnK5anaRkBlQ9uXEIjnUNrbU4qK8aqs5V40BMqetl\r\nMrF4vKACn3ojd0YT3Z/BFMM8sFckqwUp+uG695d7Tww+pebpKpI2QHpEnp/G\r\n60YMEJYpevkZYVhynAXgoaMBc5Yb/BhJWDwhbI0T1pvjTTkMDBaLo8e5BEz7\r\nMNIdqwJIrtDUunKdouaAqtpx7hpS+xE+c5DfWRA1UnD+2Y/c9xvPd0207Ajn\r\nTlAjij/oSQRFVdrwX9PJQA0l4lg+oIYspZcaYrZ/bytUnhlTaR5WxT2/ZF+N\r\n+mXI3Bv00FSI3LLY+BlJghrUAziJaBwpV+m0wAgTo2vysRHLrBswwLnDp2yF\r\nholzGBioUMryjKIEd45Dqh2a+/ZwvpzbeMW8IpiBtihzXJeXXIfbJBkYK82L\r\nnWgtppvkRJt3Df2ztsaZYg4kApMVPoRM8o4=\r\n=zSZc\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.27.1_1668541961983_0.6368210140739861"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.28.0":{"name":"@latticexyz/network","license":"MIT","version":"1.28.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.0","@latticexyz/services":"^1.28.0","@latticexyz/solecs":"^1.28.0","@latticexyz/utils":"^1.28.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"c33c52dd829b429567a6f0c26b80e6a20b2e8c02","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.28.0","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-Ab2GHodaTjpeJZUh0PR0Fvc286/WqDAQY0YMg2BQfOM+ShfHrI4vnBYImXPcH3zxAKM7HNvV02v8aBZzDchDug==","shasum":"3ce902f8f52b712abdf9055878c6c626e573f2dc","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.28.0.tgz","fileCount":37,"unpackedSize":557153,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCxT3TWPHHJOwmamd5N5DmsvgEq+Zmo+9Hmrj6Sk2oY/gIgWM0GsU43wUUW0PIXyw0CjTylZr94ilWxPjcQ2SRkHN4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjek4vACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqShg/6Ao6r2Cqz9tjZ7eXM/k5arHosCrm1ZA8OdP4IKZ/V+p1FaWr5\r\nZrGDGcfUqMcqB5FZM7eqM1uPkqJnNTxohEAXmFAzu4fry38FeaP3u/JDd8pd\r\nS04cGSjDMZA5xpr7YBzYuLj4upQYb/7LYPERv0up4Qy+EA4sx7kEloDiKyVV\r\nwJqyShgTK/Ho/QOzhkfL9ndzulLZk4gehvnrebHLu0HfbCkkK3QFET8Vqd8Q\r\nGQtdyxmqA+DB4AOeiv67MqGpJhknb/9fISzHmqClHx6UelfG4VuvjkoP5fyc\r\ny7xy646FDR2Pb/hmSy5jO24z8c2lvOara6nNTabGcIXrQurmBbjtp6vyzWjK\r\n8QCI4s2tJVLPQNXRFGSyMqmhh+fxTHUPlX1P85nRTm/zQAz+ZQBPs2EKXKZo\r\nxC5i+bvER9l0nKgdGvgW0fzVj1gD4YfC1soTx2ryDR/e9jlaPW87BtEAUlws\r\nPtJQQFkTKSEbOo0eWoQARSsbZcE4lWPqPcORP9p83w2lbCnteyMHam35GJGH\r\nB0MGkvESQXog66++K5S4j8RNKOyWLKkyg0oZOTjMgr7HfZaqfJAc7GP7Xqye\r\nhKoeC+jC4RkVTKiDEKD+ruziJXcZFyP4VH3dl28C40tn3NcSH/4Mn1kmxzIK\r\nd6M3IKKP2a865amqZ2mNtQ+JjL1lrzJ5iDE=\r\n=qCd3\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.28.0_1668959791458_0.47941899773221164"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.28.1":{"name":"@latticexyz/network","license":"MIT","version":"1.28.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.1","@latticexyz/services":"^1.28.1","@latticexyz/solecs":"^1.28.1","@latticexyz/utils":"^1.28.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"42fd67871553d5cc05a2163a20c6233aa913decf","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.28.1","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-1U5bbUJWkYvTKlZfZuChV1Z46qxMKDZjZ/AEHFrCNaizVg0Kl4KncJPNRYL/iwvdm4wR/DVQIAFtH5Y17wiAyg==","shasum":"c78be884fda1f9e4106fcfffea68060a27e97022","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.28.1.tgz","fileCount":37,"unpackedSize":557433,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCHPWd1QhNO9yIETFhlB8Zs/7KKmVrP9moTGNaA/5Zi/gIhANDJirUKkCwhdFACC4Sfr49Aqa4ZQpo4xJhS8nwoBUom"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjf6PqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpcJA/+LoPfZbSGDLtC1vZqfBIfnsvnFl4TSOnAiUlfIs/zmYmkFkIa\r\nKBiwtfqx1X9z0hDhc+rjtZyfQltxHSSC3uXAc1MBB89NaETFGZITOueHo1gl\r\nq4ui0pfIFZV1RyCkYUC4yAHUC4S4pnjTlrkcLrpv6Pgo7g9Jn+j/CZbNroWO\r\ngbcFR1m2uAPFPNiWvfzIM2zWJKy6F/SgB5NGZTH9TiBhxJJvNcBz+DtfGkLc\r\n0eK6zX1hvylZ99ENuUb++c+XohR4ewHXIbi48gjBUsmTrmjvK4yx0TgKg6MU\r\nfVCJMKZ/BslpXK31qVsGNhnKGxInTSxiVglXvd+wLvLJe3VxFlGeG4mO9b+l\r\nIMREv4Ztl5FTmyD+l4BUSd/+PSTFUviwaIDYSRWTZA+w6lI+Ew/lV0qIt0W2\r\n/otwhqawjURK0q1TmG8M/BQaeHWaPNKO2v2qf7kQv1nQJMmQ3SnOP0pWpm3K\r\nk+BboXequy9X4Swko/XtFuMMCk0aZI4lExRCI+0NOolB8/6TvIo0se5evdUN\r\nvzQqAA4kq4qomJwK+dZHiR12YS32EustexyOUzjVjdi93ANElI63IQEPxt14\r\nt5WXJFdK6Rns+kglhgswRcHe2tE0XVE4KLIE6kaTFIeq0EIt6Lj7tGpiyJ2e\r\nIgmLPsW6jGHxbAAK1HE0Gvi7p22Edb2lqMc=\r\n=OzSm\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.28.1_1669309417944_0.10276000065482638"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.29.0":{"name":"@latticexyz/network","license":"MIT","version":"1.29.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"typedoc src","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.29.0","@latticexyz/services":"^1.29.0","@latticexyz/solecs":"^1.29.0","@latticexyz/utils":"^1.29.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"^0.23.10","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1","@latticexyz/services":"^1","@latticexyz/solecs":"^1","@latticexyz/utils":"^1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"2a044ba92dd74810c88afac4ec3e64fd6f5fd0bd","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.29.0","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-5yKHE0T0BHDA/UTD4mDORIve5eoSs71l83z4DegTDOn2kxyt2H7di1IvC28/OUw3cBzCbuLBdQltsV/YGC0nkQ==","shasum":"14ec6de6f6283e86b2e891c030183b536328fd10","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.29.0.tgz","fileCount":37,"unpackedSize":557580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCW7++DrVymlycWFSYu3E69GdhQ6nHULllqj8DIlSj1TwIhAP+nFV0WvIpumgQqKBaYlOs82VZzQ05Q5NZvTgH7h+S/"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjhVNBACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoHzg//ZsV9ebjj5IJ26+RRAv6UqXYB92IGETAIiPQku2uy2EP+/R5O\r\n+mMTwH8cN/2TtujCH9T82Ib2UWAin86YvJ1xKCbeGPe5yNP2p4wu5/VN1FVd\r\nIimhMD/oLtkm/ZCyfCHkyOYT8GyRokF63LNzllQqOUNcSvwN1Uh4T08eRoS1\r\n/bx2bjSQ93SyDHVyBlZy4g42K3+PO2hrHD/GmfOkoLQpDNbEbb8DMQX8w8Gk\r\nIuHxVp1KUxpImVkYjKsYGi1ZBPS3UozxkAeTg0eUhOe5+bfxjDv75CLhDWpc\r\n8e0qU/jchOGj6G2IRY9makaBUxdzR1Vg2sLXJeRjQtS/DG2SWlfBP67PSOYv\r\nvXPvKFY7W3GscezhCd7Ob/RxSxKw+T5trS7sadF8qUlRjPYwbJ8XlgKY7nwd\r\nWmFdQfDeC5jKWmZ3mMZrwJ9iAuH19wW3RtAOKU091u+MWDLhIqJueZMEyds6\r\nC7JP5nxEhPDjGHjJJwMu7Hm/24R9Rf7QfrIPHgOhOJ2PBc0TmpVENWNEEa4W\r\nsaR4bYpuPjgO1BrTYkDiq+kljCUQ8WJNR57t/MgDSBniCjxrwniZzyzBqaHj\r\nDBXqMMfL42d05vqY15LDYMH1gQbXWMldb9xcq5q+OtF2Au9MVyW2A28gly1i\r\nqh3L19tIUZMJk5Ti/KkvP9+4OoVZxan8kZU=\r\n=D+zH\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.29.0_1669681984861_0.9969711045209704"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.30.0":{"name":"@latticexyz/network","license":"MIT","version":"1.30.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.30.0","@latticexyz/services":"^1.30.0","@latticexyz/solecs":"^1.30.0","@latticexyz/utils":"^1.30.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.1","@latticexyz/services":"^1.28.1","@latticexyz/solecs":"^1.28.1","@latticexyz/utils":"^1.28.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"950b04bc94108d0f352ca5d894a5bf2c617717be","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.30.0","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-KZ4RIWu59KsJF94G1PIHBjhUMoNmYAPsxL4OKxbEEg2Hzh1x79W1dvoXWkEuFAJY4OAjUTXOToJFUXPhi8JIxw==","shasum":"797e6a1dc2c99938fad02ff4c61590513619f31a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.30.0.tgz","fileCount":37,"unpackedSize":557916,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBzdYytUPlsG0sWzXW58ubaFR1Xp4T7OqX+z5DbZ/1JPAiBzg4ALGCUsNHdSjXdWGE/IyepkK8HmaUGG5P/Xpdgq2A=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjifMnACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqnEBAAknPz2ZQIJvQdM0VxukRdmE63oQUZqfH9F5ZVtQfWUH7WGNvq\r\nGQ7E4zqKgk2XAPTjzKiNfwNBYqIGO5vMvyOMZEHqOa/Tctg4hLrx68WupU55\r\n+PHJQduT7ItbnsuAoMCrlRnDk0fqtGOABjd7u+eM5yvJ4xAut9fZpV2y6knz\r\nqZsWAKHP6xQZAwYRLh3qAgQ9LmMizgnBoyUmNNWtE5/VweuR5DE3/qxZfs3D\r\n1d4u73dS4YNPHcHAwyw8bfxjE2gJmU/KsPMOtLBhF2ma515bxJrXxbVIpJXh\r\n5JeuSoL8JeMgC6drCFWnm4IhTdldNIgKhKviCukxlefoyRH8v+N3F7vpUgHk\r\n1jUR7CrK2tKsa2UDp+A8cxZ4Xn2lXjFV1tMcMq2ErgyG9cv/WA1s15jTKGZ6\r\nFlzFBjG7FmJZZZX3QHh1FxUDNL45ZL9Au3SzBDxXwiqTxd3W6D2dwG7GwN2u\r\nOcGcBieZvW72QOrFROMMYj4ZeSzPb0sfHA7nLDxkmg6I8yiOkwiGRLojso/w\r\nZH0ot1sQA2mlqCPvsnfNvxKC/vQiLPLh4sCs0iEZwKBbFsSiVu03A36rPros\r\nbAJFsvQ1P20EZwWY8RbHU5h8UMAptqdLhvYT7KHUgZvTwgPUf6Y/l5d6RPMG\r\nk8POorDxS1MwpEDgkDFZpLKxSCjmBdT4aVo=\r\n=LZGi\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.30.0_1669985062864_0.34272604213859315"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.30.1":{"name":"@latticexyz/network","license":"MIT","version":"1.30.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.30.1","@latticexyz/services":"^1.30.1","@latticexyz/solecs":"^1.30.1","@latticexyz/utils":"^1.30.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.1","@latticexyz/services":"^1.28.1","@latticexyz/solecs":"^1.28.1","@latticexyz/utils":"^1.28.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"bb70a2ffd3b059131cb9b719c677ce2f932696be","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.30.1","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-PKFD92mUVyJYo4bqNOZwrlMk3HMbunaoIrZ2nUAFOQH9Dld3xuHUPb4Ll6rL+WBniVtl+hHLh2N5uddJpCQx5w==","shasum":"5faea51d77c05cc31eedb36403b570a3cc7e0e54","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.30.1.tgz","fileCount":37,"unpackedSize":558064,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDqXnt5CmwCAattQEO2dTjOC8rREck7p5TpN0M3h4/rOwIhANhY3fyAl7h/KShnQ9wUWcT949Proq/dTXofkw5J+u0b"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjifQVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpXqA/+KNzST6xND3T4vyROgigFhUEZo1FMzdndhJs3CHgGNZsbBsPU\r\nNvZJkoxZhEXtXXF5M9pLRXJ+RqHV8HesYg8e59iCGbG5GuZWAV+cC1pbPDT4\r\nuTUh7V1NpLLczYYY0NuvmRWWSaDnGH8iroIjaXgHTcLKlaVZsapdOXnP0LC1\r\nSKsgQ5GD8LIYtTL99ID31SnY8Igs0cjfRweFH4FSEqlU75VNF7Bck3OuZBFj\r\nJvKAphiV/S5LkrDivU4snLWYDJ88UEqHs+bCfHG9MzF4VNpi/NF01ZJtf64E\r\nfsGk4rlcUely8s9O7VG2a9AiGJ779r1dIku2x7AXPGrw6X+F3cAA4LPiHWcY\r\nH8pABaDmkkXE6ZZekMi7Cyv0Idd6C6XZwvpBfPfabdzRFmL2uLfHkOLGfOdF\r\nFhXOEhExWWYwRYE/EPU7UMdxKJqKq1gRevySDlZ1exocFPN5OvJKMe9b3F1M\r\nLZVZovqNHn74sB69gcRYvAlK4HEPHRXHi/waIjVNZLNIF94l0889Vdelx15R\r\nn9u702Vftxn04ZCmFkJoROkpfQt5XDXOWTjF3Fb7zpJeop13Qpwsu+mBIdmA\r\nttgPUYFyHBbIEaOHK9a7F7llwPAnTSrjlq1oXyw+zsiuwAZPBcnlQnL7UPH2\r\nlhn77y5rsZQ8E0UDJbneNrgqr9GisYsOLfs=\r\n=msXb\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.30.1_1669985301045_0.8876610725783964"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.31.0":{"name":"@latticexyz/network","license":"MIT","version":"1.31.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.31.0","@latticexyz/services":"^1.31.0","@latticexyz/solecs":"^1.31.0","@latticexyz/utils":"^1.31.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.1","@latticexyz/services":"^1.28.1","@latticexyz/solecs":"^1.28.1","@latticexyz/utils":"^1.28.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"gitHead":"a1a0d627e3800039b3b9179a23927aa599bc6e2a","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.31.0","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-oU19LIGpKT9jnnx3YTAD/BnQCnEwGF00jmC6afR3ZMYqiEX/2Jl8ZOv9loMySySjOt8PqhOegQh1iuijYvCPQw==","shasum":"ab21d088767e883465b1557cbe155f1776c19604","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.31.0.tgz","fileCount":37,"unpackedSize":558186,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD+ye3feoxBmOOxyW5uZ0om/IifsK+aap8DKBfxHYWsLwIgMzPM7xDk2w1rSu+8CMHU2YZOLFB5jmzk/z49tIUQyP0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjmh3UACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpgZw//aEuzLjPPY4+uV5CO6EeI+S88/3xe5R1fS6X28iP1D2YTNrB3\r\nKsLcvp2njBabXsFDnuHhNtVc6bqYjFVV93Kee7d7HOOA4i16Dvbjs9mrL/Of\r\nn13kFryjuHAvYVFyZoEJwApHfhoxy46Qdfn5edQZ6QSlu40nV3+f+NNJPfOe\r\nRrm/cFHZjJ9s/Zs/0C/g6uGFp2tOg+Nykfr6b+lQU7sLjGU4khYbw7KtUucS\r\nptoGjIqef61VBw2K0hKt/eMXIiI4XTgtdyyUeKpK15v320aIta2BajIXJDQQ\r\nI0DoYAZoDiu5x08Yv11bmR52C0MCimjAHbJtaANEZOfgfCYasQKekyRVSVD7\r\nqv0tW5SfmsZLVX+x1U/w+HUhm+6vrllIUO2KuUcCmweaExZmArNikYvs11iB\r\nKXyLGDPuy3x+LZuDktB2LwXTbB3V3u3IOl1YfccL2Vqi1w4pVAsGyKxGZUWk\r\nVKCh28sJNSh1aiHH1wlHoPayAWaIRjhACTqqsG5mXTVegw5Q0Ci8RUIQNJ+Q\r\n5fBKUgcXQ/QEVM3n/ipFCZFLddvqT70QFlwadJmaORiSTdee5SS5tT0CIpc0\r\ns78MRDx0JRLyuBM0hfK8E3rbP2aotQpCqp1PwhQBMaFlweBB/v+CEhGNWIHg\r\nHXnz28l3/WENxrtnxCVDmaMPf6j+NaNDuLg=\r\n=iMPD\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.31.0_1671044563840_0.3189267342906674"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.31.1":{"name":"@latticexyz/network","license":"MIT","version":"1.31.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.1","@latticexyz/services":"^1.28.1","@latticexyz/solecs":"^1.28.1","@latticexyz/utils":"^1.28.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.31.1","@latticexyz/services":"^1.31.1","@latticexyz/solecs":"^1.31.1","@latticexyz/utils":"^1.31.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"0e74b3b193762606f6df08d84abfd14dc39a1fc8","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.31.1","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-KV8PjRBnpJKOmYot0yzVP2UNKz/nXjKATfvEShvdr1LC/MhRd9/fLWx1dB9PHAlxo1gufPEdaUk+GExRsMoXFA==","shasum":"f8011f89c15faffdbf12455ad8caa6baac7e9c01","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.31.1.tgz","fileCount":39,"unpackedSize":560578,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGDUGzQxhquJDrEiWmo7QYzhm3RAjrRTcnhBhR+q2lJcAiEAhZJRlLlX+iqdhoM54MZ1V3vrcc2XR8skIIHtlEwWtdw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjm5KHACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrWAQ//aLu4BRaQLbtej3bVfn0oOCQVNZ35S2jzOqV9wLdKaBuCOhof\r\nmbv++tRjqc3MqY7kuf6R9/knL3yJombMSWoa6kfBYfpWsTox9RHq7kdcedp8\r\n5/SA+smyJGIk5AeIHExq78yHzvi3WJVuqQ7fni1FTWyFTcyf7/0SXtwsEZVP\r\n6A/cF6yYffYlzBVhLkeSB4EhfSHO1YWozPbrOtYz1ZXui5ZR/UqR6xoJyRUa\r\nLi+cbPIaNMJWFG5r/CoeE6OqCtUSGHRwcXsZVwgO64u3dM7borw4V6Yesf94\r\npwV933Z3qQVpjj2mStAxAZ2WCKuJ62XJlNgNKQ9dcO652pp769t/34MHxqqn\r\n1Nn2JFrTnjP+VsoC3PWZkR0r06SS8Z27AvtAid57X/4vDjNxOvrVRwHVgHMl\r\neLcbxjyPGCOQIMwvf4AUb/YqLJaWo+qPEqb6q4O1pDxReJMlzj1ksCBr63jG\r\n62bAKfJZ2Ql7dqWzIIZiXgylb5SdrRivcIDwOaU8eq2XwVyTGC0nA9Z347V7\r\nAg715IeFSgy2QQHQOwtMDGLyuKci/+r9PpfxGt6I5I8afhJx/PJ37rxI3aMy\r\noXJBwyMrTJkKPxHddABWLIphfx8/hMQoP+wXj42XrTErQblPvYZUuNev9d4T\r\nNb40B/4HSFODdyYEsVFYSp2KkmXG4zeeiQs=\r\n=fzm8\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.31.1_1671139975300_0.4841569404102888"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.31.2":{"name":"@latticexyz/network","license":"MIT","version":"1.31.2","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.1","@latticexyz/services":"^1.28.1","@latticexyz/solecs":"^1.28.1","@latticexyz/utils":"^1.28.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.31.2","@latticexyz/services":"^1.31.2","@latticexyz/solecs":"^1.31.2","@latticexyz/utils":"^1.31.2","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"bdcbdd6cb1a056779b73307acce20eccc65ad062","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.31.2","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-xImofhfIR9EdvvBHWorSGFLAPMGOm1Vb4kfsgvu4HgPzhkBEhyHXOpm1XeXfO+sJiNWibBosXgZ4NMHzROaviA==","shasum":"95970860f01b33ffac45ab711f6c1f8bcd48e656","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.31.2.tgz","fileCount":39,"unpackedSize":560726,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD2ldTPVMO1QynByce7ExoMR2k3gDHdEVComjWxg4QvEAIgAKEjryRE+SVHgGKSHQ3ZDdJvIeK+2xSdzgVGAjkKemo="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjm7J9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp56Q/+M4MTsReKBC0JRRWQIBopcfV+UEMV9fXhIT1i6iUHR5E9yPtj\r\nqG2IrfpWEGIbOHFwzh4vD6BNtyE2TIiDP0w2jSHT/Py1QoR+gRuuAgV/uX1C\r\n1j9EXzC2Kd3xxljrUYZUlPNVaLUzaUDvaZibGvLdA9b0P3Fczz7WCreifZTX\r\nIKCBoHUOz914e9IXvpi/44E125eLiqtg13uE99JVXFWJsaUzFTs8xSVDvGYb\r\nRJCc411U8rY5HFD5IYjzO5AORSZJezyS/01I1niNBDRC0aVyUuh3x4yM3t2D\r\nYFbL8EOfiLEtGSJxq+uROrP2/4LSIwqVKZgKq4vSJPi9QJs0Kl7CIb+4PjJZ\r\nhW4e3rnRo3s9+6wi9CTtpFcK5YKyHWuFDhkR121HaKgeod0PUWWiZERRelNC\r\n/lXygltcuSTtli+9TM11JauL93pWH2bJq/csX9MJXGaODwVj6VtrTuyEvXlQ\r\ngLrQtoFgE9Jo36/vdXrV1mkBPiL3zhPjBi5k3xFMzgsXZ47l1PD9jakMwJqp\r\nv0WErSCke2Wi95sv1es3TgQ+lMhJAoSjHEov2gXZbh5VAOm94fity9TS/j2Q\r\ndcgEBuJDjRwA6t9dN0EBC913v/VKJqLqFcfu9BkZBp/Y3gbH88frRxKPRPXu\r\nLE5T2N8m2SHXZuEAR67nTyROFFsHw9n0KfI=\r\n=GGJl\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.31.2_1671148157146_0.9291999768598496"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.31.3":{"name":"@latticexyz/network","license":"MIT","version":"1.31.3","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly; yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.1","@latticexyz/services":"^1.28.1","@latticexyz/solecs":"^1.28.1","@latticexyz/utils":"^1.28.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.31.3","@latticexyz/services":"^1.31.3","@latticexyz/solecs":"^1.31.3","@latticexyz/utils":"^1.31.3","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"637b7ffd31cdf0ba1256e17bc31fecf9030c2c57","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.31.3","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-9IL9NL1VQzkAV16+l1/V9R+oNyGAWghJ/QtKeciMG7VkiAXLUrAMcGVBKqL9C+7NzrUlEwAY28u3XcWlxGyJgA==","shasum":"ba724c7ee230d3fc4eb6fbbcaf696eb4ef8cb3bb","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.31.3.tgz","fileCount":39,"unpackedSize":560874,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGwo7raRbckkVEz2aRcuejtTpb3scBu7wMUi8ZR4l9a7AiEAhTiMJESpMbpZ/n50T249gfKeqtyvhB64D4ub+i1fkB0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjnJtUACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqIoA//ap4L3oB2HTTLm0Hg823mmklIDJ3AcMq0vXxgQ1QdfteP+JGC\r\n29mvym+0tIQz9iNuDbT0ELPVeu9CKI3WSiNRT5OdnZybJM99VFPWGGanmKiA\r\nb743v+muB70okfgR7/uJbhCkHYHh8GgsgjtYzvlaJuNz4eOwLfkmZm5/C6Zu\r\nxAzXnwpWvIwJq9T0duFlFrRk7Si+wSWHee482pox9wxpv1ZFUMwtr6HMhNO2\r\nIKmkkx/lkcYIWvWgbYeRxAziYWknr+hLOASGPB7cNmMwKDl4b1dqdJ6+cyz9\r\nr7aKSTwV9NHy76GU+WyQh0YpewIzjEvDoZkh0xIkZ+/VaDyTxrt9cqfgH+KL\r\nMpic5xVfGZJrgDKXcR8UYVrr81vajHikwZB7hK0mQOZFPcFO65OL8nu5ZZ5e\r\nErvGjbrRh9gkG+82DOgPkKX8v1pc/yYn7+NnBFybBFwQQ5476B9RkcQ9+KvI\r\nkn0CQ3QSPVw7aLk2CpHxqTAw3p8e6GFnEnsylr2rgYKyWtA7hBaelIF1xrkJ\r\n83YxyFZGgH7YgQW3y+6T+X2hfPOcXarIQfa6b51bAt5NwpoJYLAIRzfrrIQx\r\nWQ2AukzDgoqu4wKTVeXoQJhuPiAJRMTn1btc1kgm+wuARuYJCqbhABQ5ScKl\r\nboRgKgQ5ploKArcKazR1sBs65N/cJHj6XBw=\r\n=dCm1\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.31.3_1671207764640_0.2175943473469215"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.32.0":{"name":"@latticexyz/network","license":"MIT","version":"1.32.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.1","@latticexyz/services":"^1.28.1","@latticexyz/solecs":"^1.28.1","@latticexyz/utils":"^1.28.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.32.0","@latticexyz/services":"^1.32.0","@latticexyz/solecs":"^1.32.0","@latticexyz/utils":"^1.32.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"e777078fa8cf4b35b21e106b0cd11abedb4ec790","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.32.0","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-2Lp4OmJ2O7bNcQgGn1LzUlxOBvuZWguh0HefF0OTK8TolRVHN6z7kwG+Ox/uYL23J+XEtBf5xY3ck/Ea91JniQ==","shasum":"970f2a4dce445c964b6aa5a8658a3b3930095468","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.32.0.tgz","fileCount":39,"unpackedSize":561033,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB//Njja6Y/Sh0eVINuYRysZJFXQUHcCUv8L7UgBzn5+AiEAjZogrmAJZAToFywT/hBqoH8SsRc2zgh9gMqsXCldlkw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjuGEPACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqs/g/+NaeyISDExsuIRfiZEIoAeSj6wtO+L16po92FMuumwBQbypmS\r\nmgjhDr2hVvu49/rpro5qPKBq5zSQLnzzQjEwKpxXZYO1pL8eKzDFOEQC/1Bw\r\nYp+Q2C/dJw/L0NDuReyzqNdeA1/xxGIMTE3tTGdqzHXzU67Ej/+GKj3DYud1\r\nbNKT4LK/iOXOzqYRl61xQ66qJNhl6Kl/QnKHshKJNmI5/cbJ8ChI4RIJ5oVD\r\n+EZByo0droRyAyWvrRBiAqn9FngX5ePjESPv807cvHgpf9WJwU2bJpB7Gf9L\r\nf1sOQWVctH1IzLjldb2QFTQVpMK+WDUdOBkafxSJ1CAcv/8QW+NRzlHVG90J\r\nf1QTS2qMkJV+wa+H/eO15mytkwNh0KSHtGqVfnRD1EM4xjYmJRgz6YaAthHg\r\nssUvye4nAx3bi2GT+qwXnAffsCW1gPYey3tH8h3eTTrVTyemwppp3b2Z4TvA\r\nXKGnoDJeLiG3zQcTbwtL1N7B+NAuFuCl+fQu1dixdHT3sLsroNxaBHCTYudJ\r\nYnStkKML9lfTTAPJrMSMOzbzbIfIh682e5+CUupRRfZNX1i2Kgf7BXsVHZ1s\r\najpyyujOeKm+5J/JHAH1n3gKIluXQKpbICLTauLpOiTDOtioB496J/CuoKwa\r\njJmMjpuce3Vu6+naSXF2/YZ32BwiCPlZJIQ=\r\n=7bm6\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.32.0_1673027855762_0.31290053019190767"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.33.1":{"name":"@latticexyz/network","license":"MIT","version":"1.33.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.1","@latticexyz/services":"^1.28.1","@latticexyz/solecs":"^1.28.1","@latticexyz/utils":"^1.28.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.33.1","@latticexyz/services":"^1.33.1","@latticexyz/solecs":"^1.33.1","@latticexyz/utils":"^1.33.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"266668946da535826e1a8da29015a200bc2f2b28","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.33.1","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-phccd5LV+ZJ4+cVSR1+XudIl/sCZ4pkAFr8xBe7612IXl18XCH5rH8CkXBQZx5XXHeeLLwDcfNEK+f+BIBwFwA==","shasum":"8433698a2b96680d76b1e798625e7be0c79dcf13","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.33.1.tgz","fileCount":39,"unpackedSize":561328,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCjq4Q7l9yNpCJ6v4q8ZvM7czdH1IKh0ocvjFMLmNW5OAIgAosD8Yz2UJ37/KOv0pZM0aZwyVcqcV95/APbp+WJ6A8="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjwHlKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp1pA//bAHq19QTj7tuJ4pZNCxqf6q8U55lewj7kn0lCZlCfY/7aEJ+\r\nqs/ROV2jTKlwQoS0HY3FdU39jA7JCaY+oowy8MQgLW0aie6Y/tQkjcTp17ph\r\noZcafRkXCFpNmamMIO5gP/9TzRtDADGhL03jO3Y4woflcsafrLTxTXFiI6ao\r\niEaTL5QJBaKV2O1Cd8cCXS6UHeSgKpLdhxs+o4RmzEtXxtfnauR8xlC/7/rY\r\nWz/0S/l20HAVecPbmnqQAxRhDy5TMGCcT39AlAm8BRkA8G5oKKK8ECxgLNYY\r\nX/+fDZD2+kmdf44gC3U1ucehqV7ElwfkbQZrQcW2C5k1TrH5ybE4BjugJ39s\r\ngOez6SJgyGVaAb5KjnFK/cNIK11ODisSEFp1A/u6/4ahBHefO+lqnhrli+/c\r\nP1gSS45yjsku4H5MX+ZBugnahgfHkvVvzgRZBsf2+OuOw+YUKBdGksPXb/gS\r\nUZTId0wJRDAn9wv+HbjJZ3l8ktEjri7qG4v7LNDBONQs8yLSjDY+6OH80ymC\r\nBVU0desn8GcS2echBKkL4+NxmvRjRhge4jeeKDtMvkW9zrMETV1LKFWSgfzy\r\nDreCDsxFwdC6NsYuQQauzdV8mlU9l44r0+ifsPzD4kx6GG3smmpzsfMMnN6j\r\nVLQyzdUrwaDZajUrkPTylvMm6yMYS0l0J/U=\r\n=DwA3\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.33.1_1673558346486_0.6621323415344609"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.34.0":{"name":"@latticexyz/network","license":"MIT","version":"1.34.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.1","@latticexyz/services":"^1.28.1","@latticexyz/solecs":"^1.28.1","@latticexyz/utils":"^1.28.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.34.0","@latticexyz/services":"^1.34.0","@latticexyz/solecs":"^1.34.0","@latticexyz/utils":"^1.34.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"a722415d7a91dab1cc849f1c8c877146872a0444","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.34.0","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-I87MCRku/YBOVsF6KJHaEEriAi4Ict6llmuHf+kXvQX/FfGLEC7wmlFe7kTtleaG5S3L2sM6JPGfJxDRQkuiBA==","shasum":"6d7352902e3881dc3f5c54facd3bb908cad0169c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.34.0.tgz","fileCount":39,"unpackedSize":565362,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEzdFXLNk/3+A+FPO5kwAsdAaUBmN0Pn85mkuTjlHYkLAiB3HMQsGHtr8wm0n7mPY5I6ECdPAYHhJP3N9QodrTrz7w=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj1ciKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpcpQ//fHpe+KAZAVGw+1+154lzHvpDb8k+Xco0FHqrE++NU3UzzNG4\r\nF5tDiaNDfOlf/Au6P0xiLae3wsbVFKVfFlqcPeDFHqsqYgj4Spy69MCaYuTb\r\nJ3cX4D9ICNRubfF18jRyNFDcu5S2fTq2mNqRNBeo2aZh+FXuDOvpIIZ2UPCt\r\nPZ5/26wgVpfbGLaGXtmcscQ2bRP5wKR8RTB4WdANj6Ft5dybt5MZmdqdOwWd\r\ny/ansXippSXZg7S1iGwThObybkwOolnIy/bxyU58MEzzMpKKmQHePBVbxcng\r\n4l2ZFkSbVw2DmAfuptIlRmnr8wCBlkdp/nak5UYEzEttu4NBxgzaXN8aN6Bi\r\n7A5M6R/nv7qbaj4HPC2kKq9fxF3FRfb9Iml+i3ezjd1u3kSLzAXgKigN2Qkw\r\nKTlV5TyODiJmS93vTllnVK9g9Tbwvohf+SCM5F8MWNyGFEeGxKmQK/TFaLGV\r\n38YHKy/zostiVmYVO0Hqw1y+oQwLVk3XrUOxZg1O9wpgWx+05HqtvxpOH/j5\r\n1B5mPFoZetKdvlXeP4+mucTq3rb6BqQGwww9mrq9qtNp3rfvRWtqlU4t+9Pn\r\nMtVcYdezllN/DNENaVW16BxRZ8brfIjX6NBZQQnFRDl8cmgJnD+HhrIlG/qJ\r\ndCuO963V7XdmOiZ+9LQrTPf23XxWMb6EOkA=\r\n=Xv01\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"therealbytes","email":"therealbyt3s@gmail.com"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.34.0_1674954889853_0.1522741874351694"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.35.0":{"name":"@latticexyz/network","license":"MIT","version":"1.35.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.1","@latticexyz/services":"^1.28.1","@latticexyz/solecs":"^1.28.1","@latticexyz/utils":"^1.28.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.35.0","@latticexyz/services":"^1.35.0","@latticexyz/solecs":"^1.35.0","@latticexyz/utils":"^1.35.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"1d894904dd99b617afb8e8b1c334f631f51ffb4f","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.35.0","_nodeVersion":"16.18.1","_npmVersion":"lerna/4.0.0/node@v16.18.1+arm64 (darwin)","dist":{"integrity":"sha512-6FrRXOf9dLdndzYc04g+jxnwkf9JH3ShtiUoSAffywWmAycrZRe0wa9pMn3qW3rc1hIn8TRw+3fzFN+PBULakQ==","shasum":"b45693623aea11d561674fc32fad9dd1e10be461","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.35.0.tgz","fileCount":39,"unpackedSize":556208,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGisQBgvMsX92IvktY9gf4uft7BnMASUufjZKNDlJoaSAiB+/f9YcN3kNg/zeIY28tE0OReFSh7p2wYNysNfW2HVMQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj7Q7FACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrUdA//UEAkb2YVsCy+spLT66cP8HbR3rrWrljJncNrepa8hC+mHmV0\r\nyW3dZAevCoMOmpwjGXojmCYV6FUA39ybB7A3MFmeacpwiaZw2ov9xda/fXSZ\r\nxu3SNi+e2aUcGVZ/aQ0g6vHLSPdDfS9ljE7mNmBRM7+y3and3kHT+aLxXO5m\r\nvQVNJtehIOYdadt7YBJ4WnICOE3mxA/Re2hImRpdAapiZYd21RXEMIHBHYYw\r\nXb8wjTaAXwegHpTSIznSEtMpmZk+Fq2ltWreEmn+8gqGdm45A/HrEj9yM734\r\n2pE7+X1gM0TLYZjUlLngSf2BH9d47/sRUzsrkpCjeT3rAJq2Mtoqm4FaRuL4\r\nKZgdGUgOqSf/4Iay2gXyMFxlMIr1sb0EmGhmkzWE173sdEysmC67G5Bp3WhJ\r\nnRD17RfLDHGUDggbOQDjJ9jFlNV11wYIusH6cr38DesR3sXnHcggmLV3vgla\r\nLeko+E1jK14Y+Bz4obIozyDYXOeQ6QbTkqFP46tS/ydwp6WDhZFV2tcR7Lbj\r\nj4MVFI2FXMKnnZe0dr7kRdIRie6xVCjigZyqaFUqh0YbN1iZdTy15Q2rxExj\r\nRP/9VknTNu0ZS4ZFYW8Xo9s0c3l6qtwQixlvEl7Ixya1oXsC1IG/9mwtpkGw\r\nlQbG/OUsa4dvXAL8MZSsVtviRB0wWWSvIGM=\r\n=hqIz\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"holic","email":"kingersoll@gmail.com"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.35.0_1676480196950_0.3859202020391017"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.36.1":{"name":"@latticexyz/network","license":"MIT","version":"1.36.1","source":"src/index.ts","main":"dist/index.js","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.28.1","@latticexyz/services":"^1.28.1","@latticexyz/solecs":"^1.28.1","@latticexyz/utils":"^1.28.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.36.1","@latticexyz/services":"^1.36.1","@latticexyz/solecs":"^1.36.1","@latticexyz/utils":"^1.36.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"2e513a481c3588ea85254be6b042ddb6d9c32c5e","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.36.1","_nodeVersion":"16.18.1","_npmVersion":"lerna/4.0.0/node@v16.18.1+arm64 (darwin)","dist":{"integrity":"sha512-PLCcOaHvcbkQu2FEF34bCkROOfmKXXiMdWmoVWfNEJwkbD2naIxBHGTX+qQulFXxC0Xq6EfR41CNPQiR1tOY/Q==","shasum":"f61142646d42410a0c1254268d0797829aa0dc7d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.36.1.tgz","fileCount":39,"unpackedSize":556356,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC4TE1BlafuRgKE5oUzvvBdrOt2pUptFlNp/QxUYPlyWAIhAIlMI2ftVAonsJWGsNrnPIdGQcnG31iNjhBcBKcQTXa0"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj7l+1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrYahAAhrmqbsq+R9rWCv4Dy3yqubQA2EvimHRoPcAH27cYnEHF2zp2\r\nlSzCxsc36+9BkgjihxGUZGNYjYZxgs9unGbeaZwo1vSOctiOLWmRBHvLs2Kv\r\n1KuJ186KmvPv8+3yAtvQjsexCKxAMd2Ho8uIkyh4P4POcHU0Qkp8kMMutNHN\r\nvMi5+UJOFCH/njMNN4xGwzXEXNmuFofd5NMR0T+vNDhIOHUrvpmjZEhqEgD1\r\n0YZp2CfOlZp3RNU3a685z4JCc9jeR1hs1v0uFpy1LhNaB3LovP3f4d4ddr9Q\r\nMUAiT+RNO+8t3f1Mpjvt5ihU0kzdJw2HCbM+4rBTNEkRr+W75A6qt+Af5HkV\r\nYrdUMjw7Rg9kgxV1pDkS2h4fT7se2G8QvXGjdfWHFt747J92vpA/QHChKXeD\r\nKfmqHIIUmwt7SP59KEz+zETa0LckA0gHtCovuNbLp/KiTX0EAyluhqNibmtQ\r\nVn0fp3ZAO/t7nuLvHzh4NiHqJmI8EDyVKN8YhLTYi0SVIPe8U5PVa8IipHPq\r\nzZg2TG4yJxe8fmp4D7U3gQI9RawDTont40+YyVFVI5nGe6pntBHzIJN61fHL\r\nugP34L6k7MHc1Ep8ddWLzZJtjzztb1VIhuco8+KbaCdFZg2zFpEwvwCKjvHb\r\nZoWsqk7Yu+b9O3WoS0PuE0T4JfLBjc7tObY=\r\n=XIhY\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"holic","email":"kingersoll@gmail.com"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.36.1_1676566452993_0.9431976282961057"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.37.0":{"name":"@latticexyz/network","license":"MIT","version":"1.37.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.36.1","@latticexyz/services":"^1.36.1","@latticexyz/solecs":"^1.36.1","@latticexyz/utils":"^1.36.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.37.0","@latticexyz/services":"^1.37.0","@latticexyz/solecs":"^1.37.0","@latticexyz/utils":"^1.37.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"3c37c234782ecefbe93209ec3dfeba58baff59b3","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.37.0","_nodeVersion":"16.18.1","_npmVersion":"lerna/4.0.0/node@v16.18.1+arm64 (darwin)","dist":{"integrity":"sha512-++0xYaSUdyEr3pi0bsweke3KnN3SNjgoPDBUdafYbYCJR8LCAGLo+x9BNw+iln7ukDMBRple8VaSgqHf3SfHRw==","shasum":"93fedf1c5c2d1a9b542edcd95213de5b1a238f65","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.37.0.tgz","fileCount":39,"unpackedSize":556802,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG0nEWaZvfsqZDal0COcfDmLVDWlB4O6BRPEr0I9NisjAiAGCl4OV7j+TZb7kLYJBpIFq4yyaBFsC0Exm83kSfANFQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj7rLkACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpuZRAAnmTp27QfHulHCFWASIigSPYsoDeo+7ZT8Sxw3pBNBTtfygww\r\nTZOG1CZInijWGQO8bhukAuGesxymkCvxfFPbVcjiaGy+AT4uKPQm7D3io9M8\r\nxqOlnT0GUjtzsLECXtRcD76mJ564dabPJMqEuQvof0cRMJzy+EmXIESb9Nle\r\nKD+D4/tVv/k7x6jDmdavPcwkmCp7+NGSmpHEmCx5BD3Uj2InmIQ06fq8z7gL\r\njrp1iaWCa3RSZPKECam5HIWGGsp9a1Zhfa1X51oDQbs58K2RlcK22MhBSc1v\r\nuRQq8I5KK43eo6bodNvGZqaJhhf8J/CkIg3cQNishwRarz0JQvsmCfcozCNa\r\nEtGxUl1G0dXY6rISlFIwEGIJaK2pohbgRQMoWArh97eyQ37iuqG+BYF3GnAL\r\n3DJNzTtPPao6at/2Lnt18MnIEWcoD73XE1TQGcM8hXw0TUvYP49yOG1j9Ocx\r\ndNFCVYLdTBI658RL4EtmLSFIZNoWeA2axPA5cL0N7+GfL80ahSTzWWL9lcTd\r\nJQJ056JjIWmANGHCZnM24uXW72dt++AhSR2GUTrtLf9v7X3TWGqbcMbXpQ9r\r\ney6bUZLYdrfUz4Mx3rziC1gMiqHOrgA8aC2sm7Vn2gTJemQP4S7ozBLLnmST\r\nzMyL2Zp6A5cp4wx1ufPnGw2kceXvXfs05vs=\r\n=Bxov\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"holic","email":"kingersoll@gmail.com"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.37.0_1676587748743_0.39237157992146443"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.37.1":{"name":"@latticexyz/network","license":"MIT","version":"1.37.1","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.36.1","@latticexyz/services":"^1.36.1","@latticexyz/solecs":"^1.36.1","@latticexyz/utils":"^1.36.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.37.1","@latticexyz/services":"^1.37.1","@latticexyz/solecs":"^1.37.1","@latticexyz/utils":"^1.37.1","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"338b2017aecbd30ced6944a1f49ffa7195722c7f","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.37.1","_nodeVersion":"16.18.1","_npmVersion":"lerna/4.0.0/node@v16.18.1+arm64 (darwin)","dist":{"integrity":"sha512-QxiUNPsglKIuEOK5sjRYvD1Fdnon7hbFKb3LPEjtPsLjkpfbOTCJ8IhbGlkJMsH50Ng031ReYjaRimLvjOetNA==","shasum":"5987ccd544884f8766c60e07258b5ed6edae0d7e","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.37.1.tgz","fileCount":39,"unpackedSize":556950,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIClnNw9D1gPSUIrYP0sw0xlFzZS3RoesgkjLmXnM8krKAiEA9/PCdZppmqSVB/8kPTeB12iACtfKFaG1YLXaEolYM9s="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj77tjACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq82xAAlW9uYUbHxkGGQkZIn39Cg+2YrgkfomgvtjxBFBgoYPlW8uZR\r\ndPxyRFjp3sw6O/5XfkOQ1446+qQe6gUfiNQlwIfwwc1j2aEtktaqEha2AoFx\r\n5pLtNyO1fJ2G5tMCf+4fPprYIM1K1UpJ3f7GDKJTH57axJKWabPxrHm42eek\r\nKDvJUjR5GueJhHkVQGDk8jvwJ0/1+K4i/vN08nywVxuO7epKiYqYib/xaOUf\r\ndy1N5K84hPhsOzfVLFh2CeVF5t2Mzw2HQ7gFyoIpXlxSNFXAlsnaCt17grz6\r\n6eXHxt5zkvaQqZVoPU2k4cJZiZMgY/2WI0q26dyI56TxyklzCbh9U6fRfpSI\r\nz1B2o8Gkk6MxkRVz7WGTOMf1K+6xQg0SG1yYwQxXKuWvvdh2zXQSC3r1Dw+q\r\nYU5ROFEi2BzcgC2VF05OPlEUCHn8JA05Fzw+omSQGQaFA0SR+U9ANiOrSKEM\r\natFxeL8bLnhCUOH5V7xF6vqmZ9lpu9mABHVmID4EfH7f8PRipMo0EzstglOd\r\nxPTKoVHEOcSJSblMGo4toIN5N54vwESBjNH6OS0VSsmGfN7qMUC6X2qgHD2g\r\n6qNUJIMS3d94Wz9rm+3y5q1UG3e4thXPKjrDKsARw8ROnt1i9OgdxJ5l0/wn\r\nld6xpCAT8lEZQXYXZLjwBXl4V+wStlAFJhY=\r\n=qXHL\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"holic","email":"kingersoll@gmail.com"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.37.1_1676655458925_0.5336357342804778"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.38.0":{"name":"@latticexyz/network","license":"MIT","version":"1.38.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.36.1","@latticexyz/services":"^1.36.1","@latticexyz/solecs":"^1.36.1","@latticexyz/utils":"^1.36.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.38.0","@latticexyz/services":"^1.38.0","@latticexyz/solecs":"^1.38.0","@latticexyz/utils":"^1.38.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"daf03245a4db65012596d40978b0fc33bef10ce5","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.38.0","_nodeVersion":"16.18.1","_npmVersion":"lerna/4.0.0/node@v16.18.1+arm64 (darwin)","dist":{"integrity":"sha512-LwAegt8T1rMlNDvqnwSZLAjVb+jThuWnGJVZ4rzg88k3EfiebkD3UXDXOKaanIN2rrCRVSNMD23fyAVTHUOt5Q==","shasum":"056cea47e131d094d672dd10654c00587ade5ede","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.38.0.tgz","fileCount":39,"unpackedSize":557919,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDOHgYttVh3ynufsJKRQmGaNvX4ypoGwn/v6Udj/mLbXQIgSI62Xybm2di54JqIYkpdiqnwhAWmw07bTDteMmDWeBI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9i87ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq9XQ//aQF3aeQ3cbu+8hCmBEZIH6coFeKWXMsHp2S1qGEMu7UvGfwv\r\n7nglaTzMAg3RNhRNs+UPlz7+P3mixLvdg4abHk1ZhWJTFV2O0SU0hcbO3Sl9\r\niGm5YM/EeQQytulkTzMcTLV+cKqsKf+MI0akiamLj2Pyj+VGQ6D3xXS3iyQq\r\nyhrLmSHmmEVNvSWezosaOBOJCQvyh4rvNSdG5Nb47xAcMhHxA7enuE0gkzFX\r\nK5D10hjFXoQ43VAapyifzxdQRu3D9TVxe8MIjIK+x6h0u36T1zZGzb8RVpSU\r\n6bAzJYNttIlThMYcmgkfFvVp8ntl+HFBGUyYsPPRxuEux6v71UwUw9ako8+H\r\nPYlTXNV9J7AW6eCAcs0rdquNkA1IV/iawNG724acNlk33/okn6pBZJFxfWn9\r\nkGV8XB2pBU2ygMG1sd62RnWjJG2SAYhTVNwZuA8wDqFikuw7f4sPKC9Xf0nb\r\n1SVfGRtmE+eHtQCKrZefE7KH2yTZJ2RGAL8Y6d6XPriNViwvCESQwgyew43V\r\nsreFJOp/v4VFtycd0b45OHTpMiwHTXPyN+pvqPZ4jUmzthoMzZfvLbnKiaUU\r\ncCm1vj9aDPEsxHmehytI57gq3pCrpj6+FxBHHinvMO7vWz6UrwtZjxORwkv+\r\noZkHrnxtq5atK6bbuD/rR8ivYuGobo5fxvI=\r\n=9/bR\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"holic","email":"kingersoll@gmail.com"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.38.0_1677078330936_0.3626606999883464"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.39.0":{"name":"@latticexyz/network","license":"MIT","version":"1.39.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.36.1","@latticexyz/services":"^1.36.1","@latticexyz/solecs":"^1.36.1","@latticexyz/utils":"^1.36.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.39.0","@latticexyz/services":"^1.39.0","@latticexyz/solecs":"^1.39.0","@latticexyz/utils":"^1.39.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"5787c684dd56adab543dfb7debcc79438dcaa166","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.39.0","_nodeVersion":"16.18.1","_npmVersion":"lerna/4.0.0/node@v16.18.1+arm64 (darwin)","dist":{"integrity":"sha512-zFqDi/2g8ZosmFrrMnYaC5tAV4+xQDb6xXDPussRr6aZgkxHqd99kdgzFGANHiGqmSM6MqiAYVuVml1YX7uTgg==","shasum":"ab1bc1e39e6cd7e90fb83b4ff76066d05bbf755b","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.39.0.tgz","fileCount":39,"unpackedSize":558066,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH3+gtWqX7woEpdOOZgj9pxuplhT+Qj1M5O0tvfhz0CHAiBCmwserOigrW/MnosjwfVcDxEz55xElc/8Tvm7k1mEEg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9jkbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmriBg//ZHSl9rKTcUZiTUa3flGHDhNZUkoEffh68wWFyUhFPHIkWBM5\r\nZ/At4hvjQak7KX2acPNekdWKrxta90MNKIJA95898n5xyf7tmBpybId9uc1O\r\n5fFFgy0W63m2IjDOYXnsa82L5tBgtjkAvyt9Ah3UK4/pC2bnGyvpdGYlJnxc\r\nwBYV7CcEN2qU/d+LTVtrOLAI4Q7JAeNsAk6L0hpb+kPLJzUbA24/nuDY190f\r\nec259adYm4UdyJXxdTqTKm3GpMhaC55vw0urLmUJvkNDlSieiPpnklnKrUwB\r\nSKvPjaDfZPRBfXsKb8XCRnN+/nl7uEduL9dQWHIQFMcPJmZbKVZxY6QeLse9\r\nJh9tpVRgIMek0UzxkuhpgHxSIO8mHD769CQblWtuN+fKong2ZkQWPW70qC/v\r\noIWEgUQiYTxI7oJYTZIAQFIbsJ8tz2QE08np3Jbp5SRJHj4BEevfo7/Q6fUZ\r\ne/E6h50U4L6r1NEjZlkRZ5Fp+h2ucS7vpTRNZkRWm5xYpyW3RDLvLI6j6IZs\r\nGlN8x5Y4es6JZ8xdkp7JApK0AjXuWJ1tsSWeX9/2owIYaHLj/CWwc056ahQ+\r\nqYP+9xkHdggiLF33qPqhq0gdRPIBQYJO9NBOgbW0ePqAVTP6YMhfyDAGPp5y\r\nn4NKg10fA+q3+uB7ANMqtwUg8SV3Tf8yZBc=\r\n=mCZk\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"holic","email":"kingersoll@gmail.com"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.39.0_1677080858722_0.3678122366114909"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.40.0":{"name":"@latticexyz/network","license":"MIT","version":"1.40.0","source":"src/index.ts","main":"dist/index.js","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.36.1","@latticexyz/services":"^1.36.1","@latticexyz/solecs":"^1.36.1","@latticexyz/utils":"^1.36.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.40.0","@latticexyz/services":"^1.40.0","@latticexyz/solecs":"^1.40.0","@latticexyz/utils":"^1.40.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","types":"./dist/index.d.ts","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.40.0","_nodeVersion":"18.12.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-c1y/khEuOEdix1Y5hXdP/FVnWtG3yS8kMu9IUSLABZ/gmRdtI0FhiRPP51JQVf4IYx3hDwiQO5O5VsdTh28bNw==","shasum":"85ed68105bef91f126cfc4705e61f831f512daca","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.40.0.tgz","fileCount":38,"unpackedSize":557111,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGgVT5a8slUQQKuU7kbVfNeJ6m5JG4q6tkgKmU/G5B/HAiBNftFyEIFlyO44ZtM2rwI4ZFvxKS8c0q4ukeYuyGQycw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkAh8wACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmox8g//aurndnJQEW5IlFsa0zS3/6Ad5XF7OCHdQTvNcrcqlWWN2oVg\r\nRawAiqx/E3Dle7XVj2D+EjVpY7Qd+ewVRC4Pu75M0k8CgCiYpW1k+gi8ULZB\r\no90wkhZTPbe7cnUXabpEWfQMXkdfvUFfljtPqTp3qSU8TPFOV11sYd3v9vtW\r\nuRIYPH4oSOKSstQxI22+WswaNVH/kV97h3o0A51atFPURCEMkllNiGlKzfIP\r\ngqM3Rrk2OHysWOCajbDkoRULXPWuKPZ7pDyB1LpHe35iF/FpHLvay9l8Jrkb\r\n+Nr8+jrugT+Cl3JvaPgLEUvKr9W1NrkB1rdMjU1gEhn/WinKfI5+Z+Ex0Ki9\r\nTcuDRVoenagKkNjS/KzC3uDeE5kCSn/v++OXxlslppPohxOQ8QIzn3nkKqmo\r\n4Xt4YYgQC7O+mytS6w21bb3yOQxXXvhe2nibi++/xtFjIXkf0wEW22CDrnvD\r\nv7QgczdeBYZdxu+4F4uO5HBChtZeMcGhSdwYGujV5ukxjd3Vo7od7wdi4fx5\r\nQRpJjsCrrwjwgBfNIT8yT9mbpu9BoSNAlmPSlC5ZPm/M8nVhiRtVSqPHs5Ru\r\nsPkooHC1t/4tYU1r9r0sj+Uhol94e5GhSxxJZBaRD4diK6uAoaVqVV03UPhj\r\nufMPNa6OVLqekNRuxkPaZKWL0ks2a1IY2IA=\r\n=irJt\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.40.0_1677860656339_0.3117547793950237"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.41.0":{"name":"@latticexyz/network","license":"MIT","version":"1.41.0","source":"src/index.ts","main":"dist/index.js","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.36.1","@latticexyz/services":"^1.36.1","@latticexyz/solecs":"^1.36.1","@latticexyz/utils":"^1.36.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.41.0","@latticexyz/services":"^1.41.0","@latticexyz/solecs":"^1.41.0","@latticexyz/utils":"^1.41.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"ecac84146f0288e3a129d1d3dbfaf373db86b1ab","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.41.0","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-ollF4vvaaE7Yz4EnqTNTEXWZ2x+EslaveXSe50dTF3pOmnoGFsugLo0Zrx5M+n3Pt830qKPqqc42bhh7d2DC1g==","shasum":"0dc4408772f980e29cdfcfeaca8ef678b7b7e4b6","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.41.0.tgz","fileCount":39,"unpackedSize":558340,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDBwtMobf8HUu0Dr94ugMQH1J+XseqEV1veDpAHxJoKlAiAM76ZYAlCw5wzFPTLBzJ5NSZ39Ty3XkFD54OCi78DIBA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkCkiQACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqrng/+Kqb5zO8KXARQAY9oAkgwyfoCg9SwzTw88P0YBxYUkBrcUB1K\r\nF7JoeGL9uKptFFd6bKIgNuBzVFO7nNdHzVxKLB0S02UwARefWffPhI/8lHb8\r\nInoGqWtQONCJ73oZAbMh9Pcrk7c7mERhIb1O0LNKMNa0AY1G6i/f3kdQmHUH\r\n23bObjFLKkifE9SojSlnSP0ulXp4WHT3aQiie95nwsjbB3RuJIresQXoHVIW\r\nSFqrt6yCklcP0YlwMWmvT0HmcRZ2CzHMlJs5fRC2t7PeVnEVit69s3vAYkET\r\nFDylqWcbnrbPk2bhNfo73UN0XRRs+xDYeKHZa4Di5WlQLNnKvr5/VyjykpVG\r\nsinDzFB3F51QmZRVbx6CUQBSIWAajGP/30b9hl7Qo4WqwvuiNjxO2eekMeZb\r\nAQfuGZUFfpQLtcyWjQ6zyWStcuSsIliI1LzrUSWNSsnfl/OJluUPlC0VHO5i\r\nIVvTAguB+3xPcj4qoUzfaCs4YtvzBIPpbwDFWmMlfSzvX/cDBSeAVAvfrSJt\r\n/VeweJ1Wvv2nL5nc2ewwDACsL7a8FLfpZ2GdOoeQR8jnMkjmWMTqJJPAZtZ4\r\nRKLoa3SEsi9RoczMhimH4/TWyEt+MNYUX+uVxWsPwdJCScMbJuoyIx/hIkkU\r\nZMDijSaCfiveJhHQ9AEVPDB6XozuOOkSbws=\r\n=WWBG\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.41.0_1678395535962_0.3821867382766"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.0":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.0","@latticexyz/schema-type":"^2.0.0-alpha.0","@latticexyz/services":"^2.0.0-alpha.0","@latticexyz/solecs":"^2.0.0-alpha.0","@latticexyz/store":"^2.0.0-alpha.0","@latticexyz/utils":"^2.0.0-alpha.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"fcb2166c25edd27ead54f0afa1b71d2583939603","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.0","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-fsbYo0XZN5spGeRsnSVK6h47iWcTwnYmrlFayy3ejzjrY19io2hHBoqJTvTozurrk3VN6kopolJ896skQbTWZQ==","shasum":"d3c9e31c125865716e56e5c9fc53b876f67c21af","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.0.tgz","fileCount":53,"unpackedSize":663103,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDCMH0IJC30Y2G/ylCaO9usdOQPAvUshIDZB6/NlZvE6gIgQ8gFL73ZDwYt4Pomd2/P9SMbQ9rUNSTURjqP+A2ZgQc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkI1hWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpOTA/+PvYFYrKRw6qnmzic69JsxIkHdRPqJZK63jAtNHhGMnUKTUHe\r\n+S60GU/7vefAMmcF2pCHBPKx/Dr/xCi1DUSSdhWslFeLkuKgG713dkBKXjce\r\n00iyNmcdPwcNXBrkY2TlvBVup0oIRQxqRDrruQ/L4Gc993/xqCDGOarWyngo\r\nfbyIP7tAg3uA9tSXoRA7px1IuT3QRDOsxE4aKmrhWZwXYil44SZ5MLsbNfue\r\n8tOUf9SoKoMBT9B4giH6UcPZWfsMvtn8JZncxw4K9FdjVBsvcKxReb4lYUZj\r\nZ4Tx9uCrDBvfqoIB94wSfsRMjyDps7v5ujLAv8goWSR+NsEw6cjsBp5RmCA7\r\nnrM1Go/vASr9ZuabB8cE1AGcHbAOe4RPYVGxiZsPhnH8q66m/vIXizgbxd/F\r\nKv6333aJT0i3U8tF/7INGCPqnDd4BLSC43wuyvj6ar6y1Koe4gnKZGtW/R7c\r\nmOFQRdYZ/Vtyh/h4oRueRmeKlqKCjQAvT2Pgr7kX61Nkx1c9BiqZSiVN0652\r\nvdFmaGJI3Ywv3vM0kzKF+tueZOx8qKoBGsAH+4GZRII73yzoV8Iph2xEalEl\r\nOX4ZvkA5VIgc5Yd6r5a1lArVJK9mMkxOinNDaRKJL4SnZU6PRnUbaeQkXAtJ\r\njfJoBpv5lcCtYsdiPccnynSKQ1KOPvLEYog=\r\n=HaoI\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.0_1680037974725_0.5321813344282005"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.41.1-alpha.41":{"name":"@latticexyz/network","license":"MIT","version":"1.41.1-alpha.41","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.41.1-alpha.41+efdfeb310","@latticexyz/schema-type":"^1.41.1-alpha.41+efdfeb310","@latticexyz/services":"^1.41.1-alpha.41+efdfeb310","@latticexyz/solecs":"^1.41.1-alpha.41+efdfeb310","@latticexyz/store":"^1.41.1-alpha.41+efdfeb310","@latticexyz/utils":"^1.41.1-alpha.41+efdfeb310","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"efdfeb3102429e76ed87352cf69465990004957b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.41.1-alpha.41","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-IP/mEVkH6oiodmteUz778KkfbSfyI9wvzN6kuFyQj6JhHf96KbNKQ21LJLLvw+GI6AH8EbEndjgvvyziLkq6rQ==","shasum":"1a1da0b301f4f7826ef6152faf291f1f08fdc7c0","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.41.1-alpha.41.tgz","fileCount":53,"unpackedSize":662471,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF6frQt+HMqpXU2Nl6TOGVxVPw42SYssZLBZh1NwDBuRAiAb3V/CiuUkzCb1T+B5ukLAB+Q542aWxtxtqSq4GT6xDA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJBQ7ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoZFg/9E8NgkT4zZD/vMAYYWfvKGkRRpFOf4jiHG1Y/sxVNfMg9Tu7K\r\nsL98DPsUfwIGquYr9tEfBLUKOP+lB4uL0iDCW59p41QRbhfPDqe9HY19DtHV\r\nfBxFX9vDRmIcwqvWa+nUvm4zrSR77Ppm07838W3fQ/BV2OuE4SLHJN2ZFMg5\r\nIn0xoyOkJc6yDpFXQaDCNfDr7HYSg5qEZi+LOdFTsH8WDo2+LYTgUgbmBNcr\r\nkq5Gi7ggP7b2VJ2If3LnZk+AAcLx9SfYtv1Cus85P0FZztHUoceHWb1F48fL\r\n6LgZpxf+znmOVw145kttvv91jlHB2zhcfXl1izWMNBQi2uIJwEQ1V3KiFCJa\r\nPo7VYAKAqAGkYL+d8rYEijdLNLz4AieDLYRbJ8DCiNovxeOeb7bi4Fo2xpSH\r\nsVbE9+ORtzaitfR70DFCvJ5cVEs2+Yr87sL7Vr9YGfV1WQn6/hkQcomlJ9VC\r\nFyoEPcpHgiW1KGKqLIty8uqusPuxn6+Mvv0F+u55iog4/o+CqpNQVEQV6bMN\r\n4hpWTsszrKVHgog9GecWbvzhc11wXCd1QhtV7xsKGv9urtysPp4cMFTaVnpz\r\n/twUUod6BwKTlU7PvOQ4+nXZvIm4AozYu32P6TIRheCsityh0PfwFzFUDStr\r\nEEca9myiO9pBCqtFq3J1rHU4Dc3HtqJMJIc=\r\n=QnVW\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.41.1-alpha.41_1680086074955_0.9582512199554272"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.41.1-alpha.0":{"name":"@latticexyz/network","license":"MIT","version":"1.41.1-alpha.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.41.1-alpha.0+50af005","@latticexyz/schema-type":"^1.41.1-alpha.0+50af005","@latticexyz/services":"^1.41.1-alpha.0+50af005","@latticexyz/solecs":"^1.41.1-alpha.0+50af005","@latticexyz/store":"^1.41.1-alpha.0+50af005","@latticexyz/utils":"^1.41.1-alpha.0+50af005","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"50af0052a8cec84014a64b759f6e72235a6e6869","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.41.1-alpha.0","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-guVpAghVpju2xKl596X12re1pLla8N+R5MdiJm1iv/LPQXX2EVRZENVfwVeQ7s344I/CJGGUEGswvGwmolKUog==","shasum":"e3073c538debc0f11c47b2fe635cae468bc21ebc","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.41.1-alpha.0.tgz","fileCount":53,"unpackedSize":662450,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDyP6Bw/NqVPLATQuAyOQnlUwZObd/0wnoHTJyhHXyGdAiEAzRh9Gf/iVWnI4szRioph9UQh069PvA62/eMYvj7R+eg="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJDjaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrlVg/6A7aFv7gJkum30XSTs349v1VPL9G2Tcd976UKFe0B041Wthed\r\niSkdCLLWlABjiQurC6M1z2OHyfFQ2ZmONwv9JKtFCQKx7StAAL2tPdRBwcr8\r\n5qQADszTaZ5EcMbnH8Tm4FZw+bILOu1yrzEuKBRObCfX7ISXC21ORq5kJES1\r\nYnBSsU5xUBM849R0WkfbyYkL8+AqKIGGouVkQyW70hH1Vb8PBNYsTzLtze1e\r\nRu4YuDdHgsTJjXHL7IhFIBl9uNAA5uBB2cQJmP4sd61MvugP1r7WJhoxREH4\r\nV7AlSzoBIKZQTrcljBxadI4EAA/0rq/RXmjN/uaRpO9FY3iqcujqHXo5wbTk\r\neUR3aunUSc1WfTv2crxyp3tLrZiWlc0XOD/p+yF6RJiAWz2KmQ8yQcG4ViAE\r\nnLW+zDJHlKjTVVNrcLnxlkneyJKuFSuLhOKKTHFFoJq3p5UNCD/qEJ3AiwU2\r\nVO8s7KMD06Z7Jj6n3YOCECxbRxaEkrzF/nsxPWPyL/KNXJVO0vaxmktNCd8a\r\nawPQtrfu1dZE41TH3rD6WazhtWF7rCAIxIEDpbZtrQEzW0+IU3JsB9cnj+lw\r\nfrb32Zzg8fXx6R1QLdg6TynQdaXbnR+wYTLt3zlCaMuR8WMgSNse5TzZGc1U\r\nXUry7bKOQUCzlCA4N+9qjLNl6LFzxIPyCW8=\r\n=97Rv\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.41.1-alpha.0_1680095450649_0.9967551299067716"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.41":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.41","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.41+f3a0e9185","@latticexyz/schema-type":"^2.0.0-alpha.41+f3a0e9185","@latticexyz/services":"^2.0.0-alpha.41+f3a0e9185","@latticexyz/solecs":"^2.0.0-alpha.41+f3a0e9185","@latticexyz/store":"^2.0.0-alpha.41+f3a0e9185","@latticexyz/utils":"^2.0.0-alpha.41+f3a0e9185","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"f3a0e9185a2495ae354cfd7c437295c9aa65e064","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.41","_nodeVersion":"18.12.0","_npmVersion":"lerna/4.0.0/node@v18.12.0+arm64 (darwin)","dist":{"integrity":"sha512-HOaaYmU8cQRz6s5uj79uhF+ztE2Ydk64u3nsLsNPLjwc++sDLL7abBuhVnGzEhSV6vOO2qAFAUUmaVv7Gg0MHQ==","shasum":"8feb508154e3c9dcbe9c9d02d6b8b88b74ceaa4b","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.41.tgz","fileCount":53,"unpackedSize":662464,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB2G8RtrM/NGfcFPJSj4Uv5MKNKpUOmSSdLZPfbqRs0IAiEAwQkFwst/VIqelGPxDkV9SkcDf329DMux/Cp9vf2bREU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJGSXACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqAyw//W0pEgu0KYG1jlb1BT9v1TqyqnIccGvvLRiK/5N8loAGYaPC0\r\nCaVnpW/euz6X/A7Jx3ul5eeuZKzRQe005eLlF/P+tTaTUq4ciSVzbfwuQW11\r\nAF0oQRVKRdz4THrxE4eliduakbj77y+IZ56cu2fda9ezXk6H8HLuAtY4xbNE\r\nWnZpJmlKf+ZmqlcLtRND7mdsY5L2vhbs8CuJ3TAui3Buoe4+4thkMnJ6PVSI\r\nn71fNF7D7MlzQyyNHl1768aGlUhEKK73ThyqSFeQrbHeiZC3eWKvPa+gbnp5\r\nqMdRy0dKix9p/N97D1sZW5oXF99eP1XHfcV/HFsVRHba5RnOW/sJKsaqPlTZ\r\nQ3vXBaj++XV8u6qVaba/JChzVr2Yv65WZdNYktT+V5Un4y7yEI077R2U8FTz\r\nbibwKHJQWaEkHi83Q+lON0T/9nYBRtwNAwp41guEpa+XBoIoR8hTKJ/lIbXD\r\nFNnOtJS9oqEl71QX24DeuYtIfynOAhlw4mO6OFYYwcAYErkkQjMCDL9yHJsY\r\nP/2klquE/Kz2KVByTU+6t3+CbgGmW5I7wKC58ZyjynJQStxdyuIuXiut8YgH\r\nGCa1EbJkbCdfiVIN/P3n83Vzww//l4agIDsztX0E7RNA3dOimueDOvAA+wl3\r\n41KjxOU8leMFcMa24VQSpPWcvKHn2wC4H5E=\r\n=rocj\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.41_1680106647294_0.5818043155968577"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.37":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.37","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.37+dd1efa6a","@latticexyz/schema-type":"^2.0.0-alpha.37+dd1efa6a","@latticexyz/services":"^2.0.0-alpha.37+dd1efa6a","@latticexyz/solecs":"^2.0.0-alpha.37+dd1efa6a","@latticexyz/store":"^2.0.0-alpha.37+dd1efa6a","@latticexyz/utils":"^2.0.0-alpha.37+dd1efa6a","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"dd1efa6a1ebd2b3c62080d1b191633d7b0072916","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.37","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-UdyEdiLBzQRzjdXtHoZXRQDba8m1gd0YY7HA7s6NbK3R5ZOwZZ/7XNZldIqGBSesBL5HfQosaBPDN8mvD0+0Zw==","shasum":"75e28cee7901ba258e9507f7acc4225c204f166a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.37.tgz","fileCount":53,"unpackedSize":662457,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFI5gzkQU99TpyEJaUZ/nUi/W8WtGW3WKXonpXbFiMyCAiAGCkpFLVIl5otRiwRxTWPC7OxjSezPVYp0sSLYER9ntA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJJKiACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoPyA//eYCX29ADd66Dr4a6F+bmb5GfqiR07QGMHJUteFV8Ik4miCHq\r\nmkV3ED6loQbSIYDLl5dKapO9cAF8EyvRJO8LzdIkgjXge/iJ3OdtVwGcy0Rs\r\nR7bGzuFoZRq2FEO8XEY4NdbzPUbNvehm3rwyl7iCOJU5cG0hnowIp5LoH+rM\r\nBvZ0Rbmm86YUSPYaISIllT6K4YRKFGXJuDqgSwgOO2sumU56gmhSA5Lw0WMf\r\nWfv1p7NBH2GmL55inYdaSPAwEGHCLunl+/zTuew/Dnfk9DKINHPvUHm/TwHI\r\n7/5RDKRL+jEkJY6ZguyBk/XnHXDMh33wJqSmx2KqMEGx7b8gORkNOham9Wm4\r\nzpKSr+VlOJD89ErGo7gmI5EYeUfMd+KOi5roXPuQmS9Cu/O4onSUXP9NNjYl\r\n70FXTrkvcNyBRJb2FVyvuphY2QSpKzZVC81Byq5astOR7GT0NuIIzPa3hUNN\r\n5QZtddY6fl+/jiNEeLP7UfO5Uz/ixsK8J6NSC1rbfq2afcT84Psr6JSduRaM\r\ntTJ2SojU7GeAjVxEovXtJofYVUbjpJK1O15P3pIYu4d5F6SV1Z8kafNZHhQ/\r\nT3XGMWhHcF1+IkvSz6OVnPtNx5fWJtvgy3gLhsevLr35oqSmeGB4P7ozfpVx\r\nXEUEVODyrnEFFGO3yv5wqwgVyKR0N45XxxI=\r\n=hJ5J\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.37_1680118434328_0.7847408952863404"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.36":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.36","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.36+96323b45","@latticexyz/schema-type":"^2.0.0-alpha.36+96323b45","@latticexyz/services":"^2.0.0-alpha.36+96323b45","@latticexyz/solecs":"^2.0.0-alpha.36+96323b45","@latticexyz/store":"^2.0.0-alpha.36+96323b45","@latticexyz/utils":"^2.0.0-alpha.36+96323b45","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"96323b45b2c7a80f256e179c451107183a26111b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.36","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-iDUrxx6x16uHgSDs2WVxDJCLz3u7pDROowD4lAx0UFphpIlVqWu2aSGdyHPF+HfE/ylzu/iONAPQZHy+k1ZSew==","shasum":"83e9abd5c7ce687b926e9cdf959f4a21a34e2630","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.36.tgz","fileCount":53,"unpackedSize":662457,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICr6A+La/Q1dKqSZI7LjCGd/DxMvgcchiamVSYlkRD1LAiEA1jSOEjceBR9KKZaLpY/rlTVSeitJklNNfQxCggJC6dI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJJNpACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmodsQ//VtWJtbuAtQ/yHY3tsRvJhO5KsMN5aRuJBvS34NWivdVBfU/+\r\nLLFojn7QB569Ua2xVbGhOQ/7wJiTeFgDSHAUB8aDploXN0tZe0i2k7gYBPzK\r\nYcWqKaM5rLivInt3U+/ikzNrVrjb9l12R97zAnT0uu6PkwNz+r84JACVLqb/\r\n0sbeoFFdbgivYzVpXfp3R7rOIRyMWplmEMfXYDqBnbxyO0itTSSPtFfElOX+\r\nSX6CrjAIJjBDswAztJGDd4tGVF1fRHoJ0QAuQvMj21NFz6V4Eih8QeC0WD+p\r\nafd+UZZ/gRcXv7nGlHB0BewubExEE8iPiVk4SLBm48/fELnivNtCqPFYjGlJ\r\nHMUjmJLp8sBpepzl6kfZBMu0goNN2RmITQrgGRUJulCQlEF/e85AM4w+Pcs3\r\nKrcGF7c/NNz4dUkAVZdULvSRf/kn/gynaL3MFzfcpIwWLd/XDDsmlC1MpAv8\r\nP7EHcF53pEz8Y/XXl61kBYr2vstrwhwVcFacM7nvM6ln8wQj+Z4nA5n4yTXC\r\n2HQpcQwHTlKeljqe9+UK29lcrscV3a7YRRQvyjlmB25l5NowjrcZ6MawpJpA\r\n27o9n/qjHjJGnQpguyYMZIe06Dq26F9AeivWH6z5jh+6kwa1TFdk8q660CpK\r\nJwvdic7mGY34dpUnnE78SEuaYIKg4BaRsxI=\r\n=yJ04\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.36_1680118632799_0.8550568274537587"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.38":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.38","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.38+89731a60","@latticexyz/schema-type":"^2.0.0-alpha.38+89731a60","@latticexyz/services":"^2.0.0-alpha.38+89731a60","@latticexyz/solecs":"^2.0.0-alpha.38+89731a60","@latticexyz/store":"^2.0.0-alpha.38+89731a60","@latticexyz/utils":"^2.0.0-alpha.38+89731a60","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"89731a60e6a5643992ceb6996ed9d9894541fc72","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.38","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-rTmPmBn+WUBtdAg9dyofeaosHVAJzF2Vb8nXIhNRS9H/7DlUD0NTsGBIYKg1gMnTTTKsMvZ4gjOWFe7QuZ6tHw==","shasum":"fc60ea3d53c14171a754f3e8a91d62b6aa5a6801","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.38.tgz","fileCount":53,"unpackedSize":662457,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCdPitwu9CZF0ShqrjfyBm2TnbeQAzsc+UM5XPcJiMFegIgA/Anq/XIQF5UWmh8+tsnHjc/thgMkBg2oviAc0WZx1c="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJNq+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpxGQ/+J2taHnXvnNC0dvG0PjGr0bCsV3bmlwn2HWvHerRLW4tQ0aE0\r\nWQNX9fFQTpsNwuPkcr624kq+rPqJPSMK46dkBQy27TAcoHY08EGOG+KxBZwa\r\nDqU+LtOLJaLwiXDhI4jCbY37JCG2eDIi0vdtR2U+fmMYW1xgcKtQIaJbBPfG\r\ndGW9MrRwtxmunNFys0nnbQXTI9t/ZarJp4u0otu9RUZ8WxnyhM6gwkQAORa9\r\n7dBM78S2CK8gytnxFqxyzUffhm83VEkRJJz96hee6wi0+IEMiXv+epsM+RaB\r\nCdqvP0zuPNkOgePjURaCD6gm3AHu1JhKZUrx1NAUYxR6GYF+fbZKP7Rz2wAX\r\nUhb81i7tESj9tO9AXH0E6J75PzDebHtnCldNyS1yztbhYzZtc8hTThlivRB3\r\ndRm9dzSEXUE/dTKtl9/1BUVFidwhBuoc50mCLlriPiBiqZCnI5W9B1aCZwLu\r\nrRVZWq/Bk0B59L3HRzVwGO9VY81zQcVs2FH3DQ1E1I5xBbbSiepS3PYWYqcY\r\n8vO+wuPPWFl59znNHdY2pv4AlAO35VEoVSJU+zLonXDPvMOR2j7UbsNzulTg\r\nVJUrLnXii4zR6oYjEK6NxTyqMUvgzjCL9GKWIpOJwEltOloajeR7TZ69d5A8\r\n2qE0N711EuUq5Zlld/FlxiLXkZB5foN1kJ8=\r\n=T0B3\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.38_1680136894199_0.12211119124509628"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.39":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.39","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.39+9af097de","@latticexyz/schema-type":"^2.0.0-alpha.39+9af097de","@latticexyz/services":"^2.0.0-alpha.39+9af097de","@latticexyz/solecs":"^2.0.0-alpha.39+9af097de","@latticexyz/store":"^2.0.0-alpha.39+9af097de","@latticexyz/utils":"^2.0.0-alpha.39+9af097de","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"9af097de7914d0c43b7d65ca6271260439bc6bc4","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.39","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-BSy+ulGd5c61weVpkXmLXNAQiDZf3LvERnrzBigLg7T2saUnGJ7fmcbumkbCtRUrp0mN9HT/7uGhnO8GqEzH6w==","shasum":"6efb5c453846279dd69c8fab453ddc8fff703994","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.39.tgz","fileCount":53,"unpackedSize":662457,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGceLZryHmUPaOL3KOhq3KhcsJy8DympDHTqrsEeoBtuAiAF9LDiojT3JaS6ESEZ5RBzzGTQSXHwt4/zKwBlzWsqwg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJdG5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqBiRAAkzcA2yQLPS+RtYOOo8ILAe+uWhjwOvgBHKdpMbMVDW+cdX/G\r\nXE6/F396kJasSiYKPZGlgoi88/T/UAvq/ruJBTXPXmM/RkunLBo5GD9OHPR3\r\nygIvUNu2BQz2911l+XlC2RNPICuWTOBJ80wFa4MgXCMSHBdhUB9bpuR7k6ih\r\neTAhbCOE7y9809GPQf2JvGYyTo0r3vrWL4wp2n+EXaMOvGJGqpiPhWh7+QUw\r\nvctCrB7Q29I6fGE5TxX9hNrfBdA9OB2mPbN8NLZWC+zX25fBcotRxnJ7IFfG\r\nnB/K4QqgHOCtsUUv/J71Ydpz/9hFYguNQNdwmAnwcGbRLHKFDuPLoFxyxGZA\r\n4NdvC8M4is3byYNKnQCGc+QoCRNu/notWtB5yFDVta4RfrOcBSeYNVRpafOG\r\nJseseVb6vba86z7HKb5RSuR683ljNJoSLZGPq9KlJ5TlrmZ30lw61910ME0t\r\nQnhQ76PmHji7tZsYXVMaejl7o6DD4bAJbH/ElqbEJO9QU+kSOn6xpNRN6pv1\r\nVGTrSISzi+4shIbF6t7I9MtCiYphCT/LTx8WOGoZSp0kyp6c7eQF2wPSdoxN\r\nUGWiRE98V0G0fXqIoZN2TtxW0EuESzQ2VEfBp8PBE6wcw7mRMdjSnR1x0wf/\r\nYv/8wWi9D4zqXBEHJfgE7XRhcxNZ9dEj0rk=\r\n=93No\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.39_1680200121047_0.34042531812758803"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.40":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.40","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.40+1e0ddb9a","@latticexyz/schema-type":"^2.0.0-alpha.40+1e0ddb9a","@latticexyz/services":"^2.0.0-alpha.40+1e0ddb9a","@latticexyz/solecs":"^2.0.0-alpha.40+1e0ddb9a","@latticexyz/store":"^2.0.0-alpha.40+1e0ddb9a","@latticexyz/utils":"^2.0.0-alpha.40+1e0ddb9a","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"1e0ddb9adaf2376ee6b578e3fb1d1eb0b3e22206","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.40","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-zpIE36d1WvG2AdSUrOG+F/Do6S85eHHrn+ebYVNAzUOWyWulH/amPufRFGzh6uG0oRUx7THqdK62BhmFy4v3ug==","shasum":"d5bb749e5ad91a6c4956e502131b7fb34df958fc","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.40.tgz","fileCount":53,"unpackedSize":665762,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC+1Gv27AIHBxcjRrHIcpwmvVgOYLY9k+a7h9+Ifpp1bQIgNle/84WVwU9hajmJanPQTzfgTMc3+wg7vrmDUqo+eWk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJdJVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrF+A/9HMLRV0Ukfzhp/67SOGZDdEvrXQtYf2lFAup4W7cfhU835k9r\r\ngWAWsgy0jOdx+olXI14Rju/XRr0vfhVDb62RX7Ugq8HzAxMhsDphgLvteopG\r\nnU/DoPmSQmm/sTeA0DkB2rSKD8pHDLDXiVP7/rmtipvdPcA0lxW91d3Ugg7X\r\nElW1edJDkWoTND9jZeeFz/uxtnSCBBjZBzl6fCX3tQMBKp5fjw/sWhp2YDut\r\nKSqK3bnK13Km9Ha8+jpDDFL4Iud6qaZiJy/LSRagndfyPncmNIzQYwRcsXbW\r\nsiy94FNQAnglHC4ynj+9M7f9ROcpHBNfzstK502Sn6mFtBUl8eXS0vw8xTt8\r\n9olRikHoXxunh6hBgZBvzqnzsKCsTrk2YxE/ys9jUkETxxmFksvzpzRPEIvQ\r\nBSWIQRw0SJdQV47ytSFT+wxjDi0F0EeueZZCDbwEAmQSkk6f39IZRt54CgMh\r\nkyQd7N4YkEfoFZ96GoA5wlrOTlchczum0M4R3/0rtx1Ou/GWang84ATnKTT8\r\n5s2FiwJ0iijGyujSe8o2rvs1VFDaSRv6HB8I6Kzw2hg1ZLh/wFpdFpm/dz1O\r\nVp46xSI9h+t6Odd0IYGUOC79c941Jm+tHgmJwALVbcH0o0SOvDN5oNl71IiK\r\n3sOxkGXGrPhkEqxfkreZpKh9d9FFIQmjs5E=\r\n=vIdz\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.40_1680200277252_0.07067975818491234"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.43":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.43","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.43+38b355c5","@latticexyz/schema-type":"^2.0.0-alpha.43+38b355c5","@latticexyz/services":"^2.0.0-alpha.43+38b355c5","@latticexyz/solecs":"^2.0.0-alpha.43+38b355c5","@latticexyz/store":"^2.0.0-alpha.43+38b355c5","@latticexyz/utils":"^2.0.0-alpha.43+38b355c5","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"38b355c562a1e5c020deb6553a000a4d34d5fd86","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.43","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-N9SlmylDewlf/sh3HvYVryoO1X9on0wsHMURR1cdEqL6Lev2z8bnxwGl9K+vyiZWUX0j4lewuZWPbKrb8tcS+w==","shasum":"a84a38fe5f81b11e531ea90c56e74c7011becad7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.43.tgz","fileCount":53,"unpackedSize":665762,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFqMYjURz1dfBiMqshji5GhouAc3yiViabFiAzbFKVidAiB6UG90isMfGWUwVE7048y2s35HhCrW+7RFzNbwUywS4g=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJe1MACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrfZw//fdHhV0OBgUaJlCgBJ+cQLr140DKRuYdIyeLwVfKpnkbTfdD8\r\nmXu/Hzft9IxkglNELiSaN1UXvLw+LlSFA32xcNSDlV8C1VreGfrYtqfiDduT\r\nR2HwXH4PO/ioaZlkHc/ekCGmK+rcaDqGm5xK+qUkDb2/nBqe7BiMn5czutjF\r\njwmGw2xMy+NtA+ODHoeKVFZyvLr1xlu0o8m4xpm3RS8vFYFIeAAFWUByVZMz\r\nOuh4W2vJavvxFq2xBevHaInbrG2JIixDrQ7Gmerty5TNNJ6OLZiOHKkzxDjG\r\nwdHV54FNqtfNy7ERZH6wDnXwlPn/71fOB75n0Uf319o1gTNj6WLPWN79KBqV\r\nldqre9ML2zPfwzr4ZO5HKEj8zZDnY7fj2vhMok+IjkSLBpHrypa/rP6ONKKF\r\nwTaMtj2HtDhE4QkraY3uxvPF0J+qpSqZfvKrY+8o3EoJR0JiHqRyt87HfvIN\r\n6gRXr/WiZKLhfVtxnK3GCafmPwlZnOZE761MYtZH7jUHeYBOrJ33sQl4kMZ1\r\n5qUAoT+CUe10mEFZkXqspyI8sxMN3scsR0CMzoRaPmgw8gwcF/bsCxkhRUBS\r\n76wlyaH6USXQJnbqnAyk67QpvC5N1iKjIy6Y6KK7defZQnESSyEsIGcpsSUi\r\n1x+kR+Xspcejr4OGpYs3TvwTPbDburalivE=\r\n=xxN4\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.43_1680207180321_0.6819696073178181"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.44":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.44","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.44+f05a70a2","@latticexyz/schema-type":"^2.0.0-alpha.44+f05a70a2","@latticexyz/services":"^2.0.0-alpha.44+f05a70a2","@latticexyz/solecs":"^2.0.0-alpha.44+f05a70a2","@latticexyz/store":"^2.0.0-alpha.44+f05a70a2","@latticexyz/utils":"^2.0.0-alpha.44+f05a70a2","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"f05a70a2e4be077af44c6d6a0b9c8da8d0c18bc5","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.44","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-ikik5ZybIJgnuYa9ei79MrDlOVGynXyZNnNHCMzW1Nmdsfv2uerI7l3f1P7FD5zlnwDq2ULLF2+pPMqE6j2fxw==","shasum":"ebf3843ea62821bfa2fc0887176042f869850520","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.44.tgz","fileCount":54,"unpackedSize":681479,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCAe44vzYmLeGa32XuUzEmndmbNPCloq5S+MXZy/qe07wIhALe/iIiEaVgkrLdZoMo7h99D4WHSdW5toVtvOY89wfTc"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJfMSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpOyg/+PH+CeyCK3is8WJGop9X9zCjv86PfkmadHStKfDIzsTq9NbA5\r\ngf62zHrI9814TZZ5hp1Mclm+q4ZPrUE3EkEAQ7yGBXCRv8iqPRzkTMa0zcW/\r\nlYEydAsjDNNB1DFY8ADzCdwesrPxzHBZkbD2mx3wsyU+LqLJnCjPruo4pLrP\r\n2+5GTNoicoJOtperv11lsAK3E1wiF0xVBLtST385u9iaWqr5E8GyTBegOE8R\r\nTKHyZFUKhU9WoL+QvLX/Wx6d0tOpCjhLssB7WP0EIS0OLlk0wecXqCxwYAFz\r\nbbgv+5DCrDJcQr17LgYsrMbZOhFF3w+ZSXY2Uf+ijP7VGFZgwFxkMR9UFWVm\r\nauI1m4A+e6XTO5ZQcuZ//s94HJAuYlYRZIuPiaaNSxZzJ72ZYAx/43V3lLUL\r\nlz0sGv9J/YJ0xy0o2u6j2PW1qQ0u4KR3JJQhkibJ60PqyX6SRniwIMM/YURI\r\nArC4VS+WYiJ5ZjyrTtPh/tWh0AvXa4gC/Mj9QjF8aXRBXwL/iHHULIAW4U/Y\r\nFnvODGTWAwn0qEL2nnoUj+av0eOXNDlYtoTVxdlA5jkIyjB25FyI4nsDiDwq\r\nma+d8Wf9B8Nuj9KLBbhNx9BgOUF7Di9VRuS8eesKGaYAF3xC5QLkh3V2bBwc\r\nQjMCaCX+KMe2zfeHJFO7f+pch2D04y/lIjU=\r\n=gvZQ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.44_1680208658315_0.1382346478432035"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.45":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.45","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.45+fcba784c","@latticexyz/schema-type":"^2.0.0-alpha.45+fcba784c","@latticexyz/services":"^2.0.0-alpha.45+fcba784c","@latticexyz/solecs":"^2.0.0-alpha.45+fcba784c","@latticexyz/store":"^2.0.0-alpha.45+fcba784c","@latticexyz/utils":"^2.0.0-alpha.45+fcba784c","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"fcba784c0da6e95cc661fdd560279f880ba95b18","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.45","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-DJ4z/JrYKSamWHQrm3MBy9tpR8OS2NcwqYVtwYnt2iwLxvO4dunhh3aqm6rX6odv8SipSGrh5uX3aItEQ34fQg==","shasum":"60177ec89bc321c9809a50d7fd877a4f3750f147","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.45.tgz","fileCount":54,"unpackedSize":681479,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDdpAoiV6VQMueewdFABMqRIjnGbYlxlhs39jCi7cT08AIhALJ5FApiV7EJrH6Es4H2/x621O9GN5yHitrTjhxz7IOm"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJfMoACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoYYw/7BIcYH9ko9RLb7xnZu8hDXZ6jNjsTyhBgfzw/NOq/xRT/xFLY\r\n/4331zUUYkN7T0aY6DnMb8+jSRwOmIavdfbrhz8by9HldNx+8zK+/FzKNEpK\r\n/pg0qGeFYuacRPVeQEePl9BER4LnwJgx9AwSRYako8ffckKHVbLQFwE1yth0\r\nnh9JDwSOZehdtZYbQILqlksO6YJLU1Ffyx/7fN0vBlLyT83YYjq660XmEJk+\r\n9q0c6kst8NL8cTPg7EJQ/LkdbERex84SknyzY5Q0/9RI3C0FZz9tGkcaplgA\r\no88740yelJhuLyLg+2e8ra8+ZEYM2sIoNrs4AJpO6paQE8W2cmhW4+0dK62C\r\n4rbflGPEtfYcgI548MXSNX/9AyJoRY1ZPjn9qccLBTLLuiqhCQtAP4LoO41o\r\nCmMERA2YC2S5IXLlDr3AS8Q8wf+QePu/CCHFCj+vL+3N92g/AYz/Q6f1vOdC\r\nl4ENZfjXrKv6/e7+W5lv9aWZ5WRpHztO0kKv4YRYLzksMXSDqDBZClBs5fN0\r\nfjKiTceYNVae7T9q6/H9ihQGWRAX63qpvP9F1If3satxk73krG+Wo92lqq9/\r\nIXGeccg8l95WF5EunPcimqPvp2EWoXi0R7mIzMQMB1c//zXhhQcABlUBVneP\r\n1gTTHG5i+RTv6Re75HDIlkEnIZ2/MkEJDQQ=\r\n=ey4G\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.45_1680208680457_0.6868503399871622"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.46":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.46","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.46+c8b95555","@latticexyz/schema-type":"^2.0.0-alpha.46+c8b95555","@latticexyz/services":"^2.0.0-alpha.46+c8b95555","@latticexyz/solecs":"^2.0.0-alpha.46+c8b95555","@latticexyz/store":"^2.0.0-alpha.46+c8b95555","@latticexyz/utils":"^2.0.0-alpha.46+c8b95555","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"c8b95555d25636d34601bb62788975fc9c0c5c6c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.46","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-SmsxiMS+3lvrz6eqwUViB/AfxObBP2g+O/q6AfHpPkGkAmhTcArNQoEyva15x4mZWKL6i4TgwOx5LCfIe1ZPMw==","shasum":"3a750924a4a3a10b1a810c89090d7dc80625870f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.46.tgz","fileCount":54,"unpackedSize":681313,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDWIdGB2c4em55YxymzDNUw3LTP6eloAjnbBaJBin+H7gIhAKlSwSiq+hjTLC402fd5iGA4zw02tyYQkjW5Igly/uS6"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJqatACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqeSw//aooU/dq7QQN7tsao4eM/XuxTTlZv35VKzPs3oOTEUeipMT8j\r\nEI+J1L2vS8Td++mjBJA9GfB1tjWSu3qZuo2FFy8xnYS08GRjYwgro83Ax/T3\r\nmNtVrLlqSMTz2ST1Q2RTTNZzNOd2Gl+kTQBprpd5ZCGr2gVH82laMOZPARIF\r\nusjVrCrAhdIzsS/krr2TXde7kfs1JVIPkxj6+Vc0WUsNkeQjUIZwIO3Ccqoq\r\nSNzdxN6bhFSe4KjJqa5J3RutekGFxUINlRNObu3vGN522Xlo1YKL3eORZTF0\r\nkgbYRFGIQJGbkLsNhhdmt/DtioCNhENVoUBHIUWcFBOlYJ5zTwu6DzqeWXbY\r\n08DFG504VQTdAhcWjmxUAqnskrheSDMRMxBSbtLqhZlHbxljfSLoniaTQbbC\r\nSL/z0npzVoFlICaj/g3OwcuWBuQvjocoN7r+ywXzzFJlhc3iJUgYOzJNrNoT\r\nYBl4IpRgcZUOBUJJHqecdRHNav1j/FsSa/S3n6s2N60Z37GQZVAbBjwdtaWv\r\nmcWdAMnt+fNjVI2gCqbxiZNIwwWY9YRzGSJpOua/uHsbBZls1QbYhG0EDwtD\r\n1kPMTjJGN5240kIhPAxfFgiku2i3GmK1BHQwqpXZBTeQSse6Bg/Ah44kD1gs\r\nbPUVm+CKUMJGNJYGCOPKBS1waCcHJGiVfTU=\r\n=V5XU\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.46_1680254636907_0.02756478012130059"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.47":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.47","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.47+55ab704c","@latticexyz/schema-type":"^2.0.0-alpha.47+55ab704c","@latticexyz/services":"^2.0.0-alpha.47+55ab704c","@latticexyz/solecs":"^2.0.0-alpha.47+55ab704c","@latticexyz/store":"^2.0.0-alpha.47+55ab704c","@latticexyz/utils":"^2.0.0-alpha.47+55ab704c","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"55ab704c36a8ba5fd021cc80abb32b3f69e97b73","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.47","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-ogK1R94kRzXmTcw/9E7zvlpTl4y6lUaJlEnozZVMey8B1u3pQ+zNoSlQRFkfmtQ0cxRiGUwrbfh8IOizO+PR6w==","shasum":"a7d958c45d24fdc061c1339c45bc204c72aae077","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.47.tgz","fileCount":54,"unpackedSize":681313,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD/RX/uy1QvWXyItxWKGf68uzXu1alE/Q/w9+2HtpGUTQIhAPyLdvM8R8i64dKguY7VTqOw5dMVIAA2jpWZjXH2MEsF"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJq8HACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo6sg//Yh6hq+agDaXN+GLN5KrLb53wa0N7NLpy1al7WOe9Y8+SKHJD\r\n8NWo2Mb/qWBVuJnMIo7L9JIbmvHlH8s6FtMQFvCxQM11PeHgJ8lVtWGDWOWZ\r\nPX1n7xK4Hoi0b+eTxM5JFh1JRAkEDzg1/HM/pe+3DXGziSrZnMODNG1la936\r\n2qDyiLVFxVhGzzmbo3zie+3lud+7KnBZ4EuVv/otXc+VxrmX2vzSO6KY0SEZ\r\nqEWjPYexNPBSRko2hskwWgoU5puBjbhEEjplCmOHXlWjp1sQdPFWYyntyYcH\r\nAcEuYDYikSW/1c+9kdjl0nia7Iwl45kf4Aqf0+BRcPFReg6TNzlonboZNRcy\r\nmhXUDm5YNCpUe8kBu6yE0mnfWnjfMhB0vRmEMGhUWJJM9LWEzLDJrji4e05x\r\nEQMEfgCpaxn79BGybPm15D5NaPiwNzuZTMl/4GwaWNQ2wgtdG7sTSn0gBTeJ\r\n7sbCQXqJ0mYRt7VQ5MJQT7Vma4+NpR2HgAx4H6QOZYd4iybcSx5a0HTZu6IH\r\nl0pE5868zS5JG6hjqcK4cRqd4r5ZoVqD3vfmpY5YABHEVw4vIfPsqgdHbuI/\r\nz0m469Ust0kX7bHBiU+0mISOrIHdcq6QvuI5V/QRJjEcXVpC+KsAg38nnYs6\r\nZoK11kSvr2b0ux3xd3NN8MmBOfA2dawrnyM=\r\n=ixgj\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.47_1680256775762_0.6447002046555186"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.48":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.48","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.48+08a7baf7","@latticexyz/schema-type":"^2.0.0-alpha.48+08a7baf7","@latticexyz/services":"^2.0.0-alpha.48+08a7baf7","@latticexyz/solecs":"^2.0.0-alpha.48+08a7baf7","@latticexyz/store":"^2.0.0-alpha.48+08a7baf7","@latticexyz/utils":"^2.0.0-alpha.48+08a7baf7","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"gitHead":"08a7baf760f227f2f513ed7da2078e0a41b1e928","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.48","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-ArOCp9qLzXDuCbhVI2zGK4ZY5J9F/vXsLXPawpRGANaNGw87WXa00d9KP5/5TV/vKmmDgMBzl4N4k+VlzWEdQQ==","shasum":"e7d3077c8b86cb182268dbb6d2c4b7a9a85b4368","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.48.tgz","fileCount":54,"unpackedSize":681313,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAfqgjnOnBT0bB8CHKYK4o9ZL1pQFlZP7tAgVqztv5J7AiANOnZ2FdemlsNW3RyaTg2Stb1ViOWNGfGX8TZzHBmLeg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJsQMACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrExxAAgDyTg4YvnUO2LDiBAqSIC8PHh/1wx3He7TvSAKkYwrfGZzos\r\nSMMtwKOdK+0OkFeGYpAvbIsBmC6DAD2oFBY+sDy16Ryv1RFHGHHw3zNH50L+\r\nSkpO9/AqiKTzMCGEaCp9CR03Y3cybOPcbBDLSrifQNicyOoXeVOZl6JxlKxY\r\nfUqZfnZq9qiAo6/HD5RZA32c2vU0Q7hc0DbIo0iZLxWVam3/2WsiJlXjLaUQ\r\nU0mw2cw/Fh64nvAWIxFqmUWsqlGgjMd/ggut95mVT2BI7tsSoyfZ0899bs5y\r\ngzXMUNH7IFXlHK9c2wPFOnEygQ7DoNn5MwghVDvHjIZ/L0rDAzmXOuiONgXj\r\n6Qazv6Wf07SjeGCEQE3miokxrirxWJ7xji/hPzIyvh00eM5rdFYh3gBOuFud\r\nr98z1Mz8zaoQmTyfEQrlsKc3/qi7J6aXSty+sC/KSZIvoKZUlbbOkG5YP2OK\r\nXAUYwKVDFD+Pw3+AaIDabXwuiFtT9Rg96wDO81cNAp7Pm9HTl5HC+dsBfr0i\r\nZY6MGGKuGB/CbmbiAT5CqMmSkDa33wXLmN8r2V9XQiNHRMpwWyYWRSn0Q1sc\r\navtjqVvQ7M31Z6Lz17xssnrAqDtikJPo7NaLcPhxOzUrMMiyWTBH7lJjAZXK\r\n19E5BYKnKvvE4o9QTaa9SFPIquExUJL3JJE=\r\n=L0uF\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.48_1680262155878_0.6596804785624806"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.49":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.49","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.49+7d06c1b5","@latticexyz/schema-type":"^2.0.0-alpha.49+7d06c1b5","@latticexyz/services":"^2.0.0-alpha.49+7d06c1b5","@latticexyz/solecs":"^2.0.0-alpha.49+7d06c1b5","@latticexyz/store":"^2.0.0-alpha.49+7d06c1b5","@latticexyz/utils":"^2.0.0-alpha.49+7d06c1b5","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"7d06c1b5cf00df627000c907e78f60d3cd2415cd","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.49","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-PsudKyrFU5G5MbxP6K1DEGX54hmZTVHGZ6TTx7M8bI6c8LZp9YaTZvaaJ5qLmqC4p9g08V01mCFLqHMy1mL+zQ==","shasum":"92152de2dab28b4103f10e126a45b26e9acf7703","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.49.tgz","fileCount":58,"unpackedSize":739090,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDFNWcYS+RBo/CBaYX7VNIDnVSv/3hmY+Lj/vgcLV0ddAIgJW+MX7VTJyi06tNYYce2IMA1hhuH92IGL4Tt8XXtTYg="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJuFgACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmourg//cjPfTP5L6XWnd6lRzTu70HdWAQj5hARj3hNtgeTEFQfTeFFM\r\nD306G3syUTH1sPETNUZzoTLeoSAeMhJWX4IBGncr+08X370E3qB8lLYSij4t\r\n5C/4T7+WgcX3bDYiDfPUvFaGpAFfs6gdnnU4TUZ2uzgjt3K6ad90xVySVPDW\r\nywnhqjaQsqUYgE0s58vfryK1A1DblfRvic+GO7UYKFFN6mGCP4b3gQqeoXBB\r\nF4DVUf16p6SVvzZSBvjeYCikKfspKVxbagLJQ5Wjd/tHobWNYpNIw7NxxJvV\r\nviXYAoNWSlg4hhHGomLZSnF48q3UG7u0iULMLdol8UPTqvEO2RtYIyjyHG81\r\nnJbSXgtO1UObdpovPtyJDWCFs1t0EtOsZTi49aviY30QoGNm2vbVxu+FujFk\r\nkvrlkJJfD0aBAZ9hitceDdrecw6qZrz6+A2cHDDnzgPPanSZI8lvWNY0Sx1l\r\nitZqUlMvJJbqfBN2oqaUoeOkfB9jIKS+WtFxyNN4SRrrV48SoshtHn1cZv6j\r\nVv2bp4xYwqhomtKnWsGp2uK8tpNL0F6RETsCPUKjM4BJlgSuNkJ8VAD5w5Tu\r\nWJnHUSK941V5ehJt2ael2AvK6vsGNLEgzeVgg2s4ZFPn7IrPo+setQ6PzyQ4\r\nlqg6dVqqp9HBa9QHuh5F5PXBBpZRb92dZLU=\r\n=hRZz\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.49_1680269663882_0.5676375755401495"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.50":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.50","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.50+d6be8b08","@latticexyz/schema-type":"^2.0.0-alpha.50+d6be8b08","@latticexyz/services":"^2.0.0-alpha.50+d6be8b08","@latticexyz/solecs":"^2.0.0-alpha.50+d6be8b08","@latticexyz/store":"^2.0.0-alpha.50+d6be8b08","@latticexyz/utils":"^2.0.0-alpha.50+d6be8b08","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"d6be8b08d0eeae3b10eb9e7bffb6d4dd2fc58aa0","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.50","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-ugecLxklDOho/U7KTF0Kpa6uLIMDKbW1ArP4ynws1ScTrlP12PqTUyxV5yor+gmUVZT3Dwbv6avyr8L0b8LDlw==","shasum":"6bad5549d38e4f284e7f7701ab0fe89f09191660","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.50.tgz","fileCount":58,"unpackedSize":739090,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDyztPBWCRL2hzB9e+kRX73qcVvA70e3h9oUS0mQbVS5gIgKwa4eL20+2Inr59N9+X89/g+4GASEusw65o/TV/AQaE="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJwqqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmokRw//Z0RiIVbsNZx4Jfb4ccDsJo2+yZavzBsREL1LlNdVXz25wgzh\r\nr8oID64slstmAiOIQo/pfgRZTeYlmkI4ANHKLBzqkoFoJYU031P8wXqZcfjY\r\ngIRjjsiV/tYeZZ7hrtRE+yNxiCLz6xu8M8/8x/I6q/o1cijEyvyk8ZBG3RWz\r\ngnp85kQxc9JsPs4kzwsVaOn96FMnnBB6xl39lnRR5rmTg7WgwWcRbep2h0QZ\r\nTdlR2i8gfLCJ0P+Pb2Xrj5dt37C2gYnAyemBiaQcEv/Dg6qWATPYPVlHjXP1\r\n7QZwGHLzW0CI9ddJeESFO6EdGcb4Mh0lnibEoDgsAY7wpH0TBrMokA7KLgUj\r\ngZW9+1sn2sktqBN+YUJXlDtTdW4xAE7zRmmoh9m0VprCsGQOutRjlQThJMuG\r\nBcIVbdUN8pakLFnb4MsTulz9Z5CM1M29r4pIIYJr96fvGuIoQFEBHSlb4Tss\r\nCQoW0vhvm3wYrm8hQDQmZ+kvaVvm+YjGZAOee1D58z9s0OUx83QBs3BBd183\r\nd24gRJWtcUErss++/S/vQN02rOJoIR9jL2njM9ypK7/fW7bL1hMYvhqKAWEH\r\n5Zzauq24PTP6AwYrNgWAUM2bi+zyZZvMHXU/qqpKz1h9hAfmHwqb/VU58Ha1\r\nsGT84chi1wES/8dJiCQ5txgZAcylutPqU5g=\r\n=kyJg\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.50_1680280234173_0.9365615490409536"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.51":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.51","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.51+4de4b6d5","@latticexyz/schema-type":"^2.0.0-alpha.51+4de4b6d5","@latticexyz/services":"^2.0.0-alpha.51+4de4b6d5","@latticexyz/solecs":"^2.0.0-alpha.51+4de4b6d5","@latticexyz/store":"^2.0.0-alpha.51+4de4b6d5","@latticexyz/utils":"^2.0.0-alpha.51+4de4b6d5","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"4de4b6d5ab4f8b27873af6d298ba3e6e1c1fd02f","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.51","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-vdMnPPgXGI877VzKH05KDE7gINskgQe8bPEvk5Qz4lEXnlGgLmK+20u4KA3dCu3P0FQkL70oSQUxAhC7Uz+7Qw==","shasum":"91dd0fdbf759cfe156d86477622c8ca56288bdb9","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.51.tgz","fileCount":58,"unpackedSize":739700,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCX4uz3aCbEVSNQZCCBmYE6cryGgfWJ5auoV7l0yNCgBgIhAKZEFNF/KB1IveiCIUJgMNjx7c2FuWHgMyB+Xbeh5oVy"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJwsrACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoPYQ//aORng70FzGgG/Uaj5uTV4dVwWz0w5eWilp6mJ8eAOmnyeHhX\r\nJX00HKY2bX03V6ePrMb9FSdRtaV4H4BR7IKQamENkDDT3JXcZVO844t68hrz\r\nUDMSXAvi+f7GLFE+AFQenlDHMOdFQJIvuB04Dm76uTboPGfC2fdOz4W8qXxT\r\nQ+LXyxBd21LAAvvmZKpoXlaQnkigNoqxVc9lpeduqtC0173HfMYqxV8RfdHj\r\nkOn8UiijsP2bhdPvtH98cZH8wR0Z3ML0ibtNoSWJsBpsoeTc9SNoHNrizbcQ\r\nFZ+SxKJ+9aiqWspVTedlNPzZwNk9g8XHg1a7auF9iaIwCTR9reA8ydIqL+jn\r\nAnCkkHwM8/498ONL7BOOj0gQxMMbfWcr4SDLP73T7C3ae3FONvkdof1xi0H1\r\nin7Du8heT0mM6WmCFPyvLNYvF7a5LwjvkplDWMWcwFXvbVCIKCrGOPSkg/SR\r\nUTj1cD4CBATTMpih3r68cyiZMadEWmcDYot2Q2BqEAQ82yKX6DiPy7poacB/\r\njE7LFO3B7MDoeoRDETUdXFY0ELKejlSA+qML+JVV60DOBICUjeE7waT1MD2N\r\n+MvnJajHRv5wugMHPOVNg3KbVkLpeiTI8VdNrP1XIOMaVQbX1u4JJhQWAdtQ\r\nlHm8sSG3gei9+JFbPAZsq8R3cyCwHiipPDI=\r\n=2Anq\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.51_1680280363240_0.7822025189917676"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.52":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.52","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.52+cb1ecbcd","@latticexyz/schema-type":"^2.0.0-alpha.52+cb1ecbcd","@latticexyz/services":"^2.0.0-alpha.52+cb1ecbcd","@latticexyz/solecs":"^2.0.0-alpha.52+cb1ecbcd","@latticexyz/store":"^2.0.0-alpha.52+cb1ecbcd","@latticexyz/utils":"^2.0.0-alpha.52+cb1ecbcd","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"cb1ecbcd036ead1b1ba0b717c7531d15beaeb106","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.52","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-zM3xCM/1abXbjiDq+Tlel6rT4sAsizOj4j9PFkBE3vVwAlMLAfSF8PLUs+vKtoSHwK8t2ObWIp68lTlSE+FEmg==","shasum":"4550f43417fb7e5d8d9e2e7be3fa62f261761837","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.52.tgz","fileCount":58,"unpackedSize":739700,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHgqbvBD1gA3A5kVPT+sX5jRwE8l5T8dIx9RrZaoWStkAiEA1pFGB/aiYE1PYcWopMWcZ8soiLcJhzBktyPXzU/CTtY="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJxMgACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmomUw//bazJLkXOl7PPohyyaHO/zilQHh+uiqUGdtQdQfuYZykXZz8I\r\nKVpGPkMbPNCALrsmCIUEdxhIGQAE5gvtOANHpyblGbu59OJ87a0eBPjlDLxt\r\n51jAQ2M3DD/xa0IE0iRLpmi/iViOy06naLO/WJamWXJMXpRCUJ7aMNrXZhM/\r\nEvuVnShgjfGiKkWbCQ9xMqGqp1cQvZhh3/n5Yrz2WFKa3x3aav4ghzyBnSDv\r\nqW/099Y13VaCmm2kAscXGnGFT/mcu2EbiyROykQw4mWhDoiNcrFw6uMgaiM6\r\n9xHYjcpg6aYUX8tTwNzObUCuHj/wRwpG4aAF41jdgyF8XcIB2BchK6Lo+NVd\r\nb8ZElMi5oor0wfmkhza8X4poNWbHum0hJznZ4LzJFQC5prpg61z0re94DZAQ\r\ncJhcuV5BPC5GlfB9LLxyaQGD9/ma0cEIe3o6HKeb4gKNxOO6Nm9sl+JUa+Ha\r\n4uKdgWJGF94f/lHjvfoi3J1Cj0HiBM8Pzw9+/ygs8cX6zcGL3QGLlqnM9wsd\r\ngwaoNM/Tw2DJcch86sNm8lPC6NIceFW5dwLFrrwvthiahsATJrAnkCPjWvhz\r\n7taByF80VcxcUsmdb4UBov2kXt4WXPbWqCOZSxyN/flAZW++f8IBJc743f7m\r\nxh85/H7gxOrzRYESgbwRKSGkTpJBr3+gJy4=\r\n=9Sor\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.52_1680282400302_0.8423799969668131"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.53":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.53","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.53+eb7985e7","@latticexyz/schema-type":"^2.0.0-alpha.53+eb7985e7","@latticexyz/services":"^2.0.0-alpha.53+eb7985e7","@latticexyz/solecs":"^2.0.0-alpha.53+eb7985e7","@latticexyz/store":"^2.0.0-alpha.53+eb7985e7","@latticexyz/utils":"^2.0.0-alpha.53+eb7985e7","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"eb7985e764221b7bfcc740912d6f4660119718f1","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.53","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-NU15TDBfu4007nOYqcrdODyiqmQvI960l9EtiSYR5W8HbUa3i+7B8iDefNzIvjp0SDj+upJ0z/Xm68AtZ6e3VA==","shasum":"9088f059759c5a9de5f83b507e35b008efffd911","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.53.tgz","fileCount":58,"unpackedSize":739700,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFAZTfnUtraGj9f2obWj9uDwnEdfXpigDDFvVzKdJQiQAiEAvJ+PkR3RGQ5VzXn92kL1grq4+rCX1JcGqn+YOxOmk4E="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJ+0WACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqSSA/+NU8w/vmW3XSHJWw96xXKtprejJH/HS0dFEPTqcpbSc7AOlga\r\n0I9rhoxDZ1igGQ3/xWF/l4E07hCeJspK3yliahKCPHvbZXY/onOdvHbFY0JW\r\nyXbTSYx7o/0JFMxG8FNK+5v7P0WfQN6uutuTuW2P+L67OueOaCz8C562eXBb\r\noSwVb63mLbIV74NqimI7fTH+yrtlBq9SGCE15QObVKUaWgViWT3iLRAQBQW/\r\niqh2lNl/LrqfAxeOQonpsa2HdZAi+bDJDqwwu5D5y6b4C/lEKeAdUXt4xbBe\r\nUzMzSW9fQZhtdDOJCumv7BbgRisa0ng4SQ0aFIzNvL76cmsCoeAqjD9RDmNo\r\n8UZdCo3qp+wC5/uNm9cz4wYeTiuGyH5o7bqIi5DFSgMHQdcAtX1XDrlgnavO\r\ncf3cbz/8Veq+kx5WeVIa3MFQjsc5VZllYZQe6OZ8wdMRc3CddyVqCVJtrhw2\r\nirc7JpMzOkLQKOTbvjBY0kEtGOZUJ0VeTL8xSJ13qg3qohb2gNUlJzQImPid\r\nSahB0uZbyN4n0PeDalPWKRaZWb8XaW1sEaAy40/9yKZrBq0M0L2v2aui81+f\r\nVB4zO384FuoQBJRYF0gRvjNW16c9QeGuoGduWtfZXldC4aku/CwE1YTtTU6Q\r\n8cJ9wu8oCUF6uJlmgbSwM0GVDS7+O1lrjDk=\r\n=2im9\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.53_1680338197992_0.8572564837771659"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.54":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.54","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.54+fb823131","@latticexyz/schema-type":"^2.0.0-alpha.54+fb823131","@latticexyz/services":"^2.0.0-alpha.54+fb823131","@latticexyz/solecs":"^2.0.0-alpha.54+fb823131","@latticexyz/store":"^2.0.0-alpha.54+fb823131","@latticexyz/utils":"^2.0.0-alpha.54+fb823131","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"fb823131fc8f7bcbdcbfa57de59a8a5dbca2f8b6","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.54","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-iA6Y0AANJUxkUUUdbpbrfIi39cWqpLK94i4X50dEByiU2ee9bwQ3sQZDM/PuRhZ+hlk0wZ1QfghGqIGoG71ChQ==","shasum":"598e9b42194c8c5a580ccab0b5b86afbe9cc9cc0","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.54.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDziZEhQ8o5BnrrZ5rcjujizgfa9/mpw6UfBO/MSGU8bAIhAPTB2aZMwYcXf5IvAbK7vCVwZNBguogZySzB/OfhPHDM"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkKBUaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrQqg/+O0Th5NvW7FPVP1kAPE7qTptlmM3TKZdWJT12KqPYoPX3RWjO\r\nWSiBnW/Z4d8URxCKrRJHPVGB2r7OoDvKTPjm0gdo8po45hk5hJyH52nsDphp\r\nmt3zS6mi7dVA/bDsauHz2o3K8iA0X+YnAAA+Hi/7Srf7W8Vnhg8b5R+yJLAh\r\ncDy1v5TZ3Z+NUzKnFmdPY6Zri76BC1VA2/uRSWTrQ3ZDlZykHqCXPeHC5GwM\r\nNPlZshxq2Fto8HQ5KZlZ2ZZ0aGIcAcAzGuvsdmoaqMhnpiRHhI2llWK6lE46\r\nD8t0bTjHJ6LgxXOfUOu8JJxoZjhouXP3l1GZzmoYPr8ryq3tZ0oQj8BvavEy\r\nhpSt2gXHNm8DfBsI8kiUv0mf8sAfUyE+IIESlz+jjFP864hTVlKUfonWC0C8\r\nU5yUNQ48I7royYCV8fiq2o/XbuhW/Yfv7lPXpfz7amijiXb0iAsAp8NCZf3p\r\nr+65C7jDOVa1kBKbI6+DvXMHCGZ7wQmlGMSX3YoFDjouS4bHXIFkqN6NTEPO\r\nzLogBFIrcM0TiQ0qCqEqo3141g42rjujih1M0wXUMLLm9/fDjhizezi/EqTd\r\nZw2Vbpr6kJJPM0LuKDVL5sp/OfwDQHMlV/dLc4+podRvvrTX2xapyou8lKxd\r\nzAZdeIZOWp3Q1iGJOWkQggHuGn1NfcgD4Fg=\r\n=qWEK\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.54_1680348441988_0.7845272741503322"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.55":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.55","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.55+29fefae4","@latticexyz/schema-type":"^2.0.0-alpha.55+29fefae4","@latticexyz/services":"^2.0.0-alpha.55+29fefae4","@latticexyz/solecs":"^2.0.0-alpha.55+29fefae4","@latticexyz/store":"^2.0.0-alpha.55+29fefae4","@latticexyz/utils":"^2.0.0-alpha.55+29fefae4","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"29fefae43d96b107a66b9fd365b566cb8c466f8b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.55","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-cqkqeY1nvlF1bBx8VdOYeWeOQUVAvguOApUgtrxFG0o/nvryxgCmoPKsKXEiTbWf1z3sjYDaeITKgkv67fuuyg==","shasum":"3a41bb67278d3d2cdb8a68d9cf46f1769493327d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.55.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC24/v4b/QTX+dcwj7UcFF3+lHJwasYBgzPXaKHNM2qvAIhAL6ULBTWLYkwmjIAcdUX2sIhuhcDwYWrHFR/4Cyr4rw+"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkKBumACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoFxA//UBUA8ft71yj5N3gS+HuA20i09gFTwnW7GDWshdHvDJPfi0AW\r\nPukir5E6OPjUOIsH5q2xT3Z1Dc1qG5jmv/9wwAhIzZ9x3yg8XjKoKNcdx7PE\r\nVVEf9pwAnxGTmb6oGz0cTayA+xZa65RrMGEk3TudmWGwE1JU0D7LXnyL9zEC\r\ntA8yF9cy5M979VGp1QKulVU4IbXbvoTkH0fyasPo2XsbA4cvrPthyj8GpItq\r\nLHWsDoD9R1W4iGyAipmrN65ezb3p3MSJ3O5pcaCgNh23FHKiY53AFUgrURNC\r\nYR0w6WH/hh7pE84RjwdCSBa8Xk29RAH3cghESa2iHpC864NiQ3fyod5WElRx\r\ncbhoalKgUwPd6teRuEPY7hc37X5ukpe44Utkksy5MqvKqlTMXZoBGmrjgl35\r\nJCm4ysXp7epZQ64fbnb/rP5hhTM6mn5LF7Kp19UlocpLJU9gJJ2VqL6cDOrb\r\nXUjCGNy3NJEOrB2MZNtH/hFtG8qIyc94llfp8UCRQy5pAXW7Y4voBcXwGodz\r\nSW7jWfllRBa2ae9JJGpCnwoL5YJebyfX9+sEH2B5wXCO8BNi4pfYS9LjU/w+\r\nwKvm9o3qsiFBWppS11W/gZswUtYz2Ifj6tMWO/jIVjvlfm4nsBp87B4A6xfG\r\ngB3TL5NJRELLu2/qAma3sXrADQYC3IVedYk=\r\n=rl/D\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.55_1680350117897_0.5414524310306148"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.56":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.56","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.56+18a8c42a","@latticexyz/schema-type":"^2.0.0-alpha.56+18a8c42a","@latticexyz/services":"^2.0.0-alpha.56+18a8c42a","@latticexyz/solecs":"^2.0.0-alpha.56+18a8c42a","@latticexyz/store":"^2.0.0-alpha.56+18a8c42a","@latticexyz/utils":"^2.0.0-alpha.56+18a8c42a","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"18a8c42aa26ce54ac1a1bf4ba35de249b7f55979","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.56","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-hSXHAzYusPasw6srhUP3cep3i9JAmVn9QBbY/mLy3q2HsQl6y1BxeoAZYX10drp2gC3b+1nmJVPYLHBeJi7bBQ==","shasum":"307a49c4e12c32c450f5de3e5f13705d71010248","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.56.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCmo80iZXRKS4JFTrzjLlZx7Q6Yxgk+mLdyjz2eS/xFNQIhAJaNOYrnCY+L+K3dFRQyRJB53E9ND44uWiU5LgQAgipt"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkKDXcACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpsZg//a5HAdoAkErG6Wc7T2tRirxg8sioYvNVYB3tVw5Jb8jMmFDRD\r\nkJ8iKfRMoCr+Mc5Kk0iIy1xk+hQEzXLPXzPrlMlccp1gC3/Qx0llNAHCp9pm\r\n1tKsWAez+OvB7lf5mNzN1s2i1ZecvnkEBNY6Q3QvmC+HrnrX6PRGh/I2WOP2\r\nDoNYjSNEnFmbTCA65kdqZs25VbnYqA19umQqDQsbWzER8aDIA1u1QLGLyVSe\r\nDyIL4OOcQTIRjJdL6qjO/TiEWK3rdS9Lk8HCgJkPS103W6ZwbM+3CRaTdTle\r\nKrZyf2Xkbk+1KJiJRTxGDaK+PyVvI8lcrP8YJmn4hwzja0O0tMMkYGN6Bw3B\r\nlTlRnnHsWfUPGzyt/tjtcFQwt+K+DuqD8wygLq9ob3twTzCzw7IE5LIpyNZN\r\njw9sDSj/ZyurkalSq/clQfxVTHdlJ93iTaoBlulkoyKSrfitorwiC/LQ9pf7\r\nHzqIoaPg/DAk6Yx1oirYyqlKpfgc6Zh3dw0bpfrf7akTtNJp4okJ92W9HhBa\r\njssSwkp8FswE6WO4ktuT/svY0dt1Ky4K//8jgRTN1CC6SX6FErxo09Zqjw+0\r\nBb07b5IYRmmc4dURJsrnX280Ukawhh4wK5BwjjR/tB1uLHaa7j7EKkpbZsn4\r\nueIhd23iBSZ93XXYEYUlHgEsoF9BFEC9Y88=\r\n=ZNx3\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.56_1680356827930_0.11175215245703729"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.57":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.57","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.57+b6a09f22","@latticexyz/schema-type":"^2.0.0-alpha.57+b6a09f22","@latticexyz/services":"^2.0.0-alpha.57+b6a09f22","@latticexyz/solecs":"^2.0.0-alpha.57+b6a09f22","@latticexyz/store":"^2.0.0-alpha.57+b6a09f22","@latticexyz/utils":"^2.0.0-alpha.57+b6a09f22","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"b6a09f222db8fc6d32800671ba238bc1771eb917","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.57","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-Fh255V85E0259hhLmVAgLm6DG2Ic2t92skVic/BlO5otkFzVEkNcCIeqkW4Vej7DWDRss10MCIIVGnUmnSVb7w==","shasum":"d79c22ead4069d940b2bd17a049bd228af6560e2","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.57.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDnkEk2ahQaUFLuEQSzIqeclTDpVrhPvKPPHv+HawIhlQIhAN5/iU60ohlcj2JLpr5VzSFv0/lKnA0LKJ4kzfQTDnFy"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkKDnvACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp9qQ/8CJEa3/sP3Y3uNSgzcLw3xGvncE7SNEcqNEQ2HdHsYT2NfLh0\r\nCErTLJIWfjdft9SYnbXUcSRhgqE7YgR/LSmXgxKxwhikVx7WCRm725QdIN8i\r\nXRGMakrSVgGgTjoRXQGpUJSUPm3RsxIoYkVCzouFIgc0Am0JtZA0/6QzV0W+\r\nKQacQbDTEiRViGmBLnWIC+mNzlVwOVuAhqw7Zq7AgnYa0dscyf0yRjUojnXH\r\nKz3738rO+/KEuzb7MhvMlRh84yiNOgvjgYBzPwmDCOmzsLmYaPzwZyxOdK8D\r\nS+2sEsiYilvXo3duQkZZO5kZSZO1D5UVe4FgfzAuuk70WyJuKWT8psIk8fTy\r\nmuCw7cY2TjFPKZ/slGd9CkEupPD8Z2vmHK25/j/QT63Pws/Me7IQglUMa+3F\r\nJdolscMFwCJ5d4pMVpnxhiDJsxbGD2P140OFY2jThDKXz+oXklzTN3d+2+We\r\nw9PrRhbWCVsUZ5V98o1ZfPiy8DEzdjXRdfQpCfDdO1Fji73mbq7RHXUZ39Hp\r\nktiDe0LYuWdP4SxF+izVUXQHSXvhZD7JW1IvNJmkcZQGkZUXFe8Glfi5T1mV\r\nbPimMiZPm1un8krPRqNkJKNYgHAysTQ/wmh3113bVC4dnAE5Ik8UEJjR/qdY\r\nLzzB3D/BYaP6isUXTUU0gEcXIbGhuYUy9sU=\r\n=jK+t\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.57_1680357870741_0.18644401951126843"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.58":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.58","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.58+785a3249","@latticexyz/schema-type":"^2.0.0-alpha.58+785a3249","@latticexyz/services":"^2.0.0-alpha.58+785a3249","@latticexyz/solecs":"^2.0.0-alpha.58+785a3249","@latticexyz/store":"^2.0.0-alpha.58+785a3249","@latticexyz/utils":"^2.0.0-alpha.58+785a3249","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"785a324920c11e24399c5edf575a9099ee4077b6","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.58","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-aZX0Ua/69EVR7SJDc4bBKKLdY1zGgivxTSHIVwXAgsZx7sh/Cze5Id14caeJlAmcpSf48Mf2ev3HfF57XD6Ejg==","shasum":"b5a3c75c05cf0407e4c63f22f2349d962c931d2d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.58.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCpyMhXcGq1KyjCND21qUCkALN1f+PXHfwWC6XPHsCEwAIhAKEbDrU7rGxLHzQeIz1HHshG5SG7VSJoYjd7B/IPn7jV"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkKEmfACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqgwQ/+K7pOVBeouUCAA3TB5zNRzazktZ1RcVwUOGUKOZE6SXK/aC/N\r\n8uSdDAsoVos3vt9DcX3XsIsg/JxTevITDPrCuQn7Kmqv/76MusGxYpJP3n7j\r\ncU3ZaFr/G8waE/BCP6IgeNwdWxQkChZJf0eN/fKsCE6mmGkqTiRP2bbdZ8Rl\r\na0DGm2JuTE6KoaQGGVDRJgLGzTpLsVDF0Qt4+swGjkPS1O/fEoBjy1BFs3BJ\r\nqID+K/a+9UjFTExkzhhlecj6zF2wxi+vQodT/alCzxe991SEuoZBNaeejz9Z\r\nDpzIFiEjKwCwIJ/T4xQE+KerfBAvDILtDYqk4s68HpcuI73p4bFcjdW33bkn\r\n5Ih3ia4bElZ/BDgDJ6tguDBYQ3WLPT8ULD645EKHmI31uro3G80rZ468NMB7\r\n5sfbir6SUV85aCUuRkxifjM+PTl7wyQdGZKrRAVGElZGReFjE9/KLbNimy03\r\nslc6dQuqXc0QuB2gmFQO+fQTiEtzHiwnpUtDHlSaA1Czx14uy9S13sBP5FTP\r\n2bG6p2uEuURoE12SFQv743yssKv1xgS1K/8U3o/kWYMQWxQIr9bx5If6JNvG\r\nO0TWLZwpwNNn9Fu/p//3mXA2Xu8Y0rUbHYhDvFymOW860KJVUmScGBGLPeWs\r\n0p2MWisugA7vFVXavvPdxwmfSDZ0Ftbgm/M=\r\n=i7jK\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.58_1680361887057_0.13152885665714953"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.59":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.59","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.59+bcba1093","@latticexyz/schema-type":"^2.0.0-alpha.59+bcba1093","@latticexyz/services":"^2.0.0-alpha.59+bcba1093","@latticexyz/solecs":"^2.0.0-alpha.59+bcba1093","@latticexyz/store":"^2.0.0-alpha.59+bcba1093","@latticexyz/utils":"^2.0.0-alpha.59+bcba1093","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"bcba1093c1221f9964632a43cc8fa1a9cb1963d1","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.59","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-LN/nT6KEPjrjTn2Fnl7LSrEs9j0H5RADBcQbK8agIx/F/asyt37Ch9b6wnE11ZNKy0UfM6ML8YVuRjViTE9SKA==","shasum":"6554699aab5495e34f16ed42f2f16b489b92f330","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.59.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF2aytYFBB7zzKt2aPlABA1kvjDfsRizPbpX/rcVvnUAAiEAxIOVKSM4VtRKMLk8XE37KFgcHKVBp7+yFJFRu8Mxn4Y="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkKJtVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoGRw//XtsaMCQY2gKZQRJG12zg2phbF/O7zbw/jOH255o1hbih0Cu0\r\nP76SFJxugXtlo16sAnvdkJs88pliklyDdB+VPe1jfxh4KIhjrWljX273qCHM\r\nO3WWBh7wZicmlgZeHBPTQ0OfTYovDDCGbOeDRVzTpBk50AILNJwOqwoUOzQk\r\nMZrQjOBwFBNL6xogkJoybVW870x3c3qFe26lWC/PC0+fS/UQ5e93YpBZKFLh\r\nodfemmjTu1ggkug9DR+E4m/cBQqgN1ZcpD61eab+YcrgMj45tDFI+y7sUS8X\r\nqxrh3l2u/AiPkun+6PpMSyLkC3POQTlaCiWuaT0KTn1uwilTWo3MwH1jUog4\r\nvDN6QEEzX9IaffYhkLgkJNN16yOY6RMFkCpkB62yEpBf05dgTyrJSfJ/LK3x\r\naeyySVx/Hul3a40ziHcT0mlVA9Y5VRPfd+FhbAxARjBn1SdSkrYv+rpIa21u\r\n59Pjv6rVilGoWaXYPIpAY/vqmcX9STB//PB1N762n6DyMaAAK5MbkEvf76iN\r\nuaDrMZpLsK0MMQMcgnMkGAayCUMu/yAwiwdwIwK/7tjpMxmuPNphyfYEO/jo\r\n2pHIQpHU6Mdf6mCgcZHuTkRQK24mKrYqrzTTGde1k3Wks15KjwqfAZaL/sd3\r\n+097Z3ojQ03N/USadhi+MlT0VV4Fcg4d0+8=\r\n=2wYX\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.59_1680382805594_0.27367773580587795"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.60":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.60","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.60+36d56e38","@latticexyz/schema-type":"^2.0.0-alpha.60+36d56e38","@latticexyz/services":"^2.0.0-alpha.60+36d56e38","@latticexyz/solecs":"^2.0.0-alpha.60+36d56e38","@latticexyz/store":"^2.0.0-alpha.60+36d56e38","@latticexyz/utils":"^2.0.0-alpha.60+36d56e38","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"36d56e383e4d2d0e3437cb8ded174bb4e29fa552","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.60","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-ooVjENiMZ8Bi5q9pUqdVOYid9aHzVo5g6y6xVB5vauC1xDMzJ9PmnPcjlneZAUYOJc/2Wqo4oAmaHXQOH33r5A==","shasum":"d6277b97d7ada6c3ffb2351940bff040da91baed","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.60.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEwWP1J8KAAk0jXZCc9wVsa9IxTmTLv8dtSUpjnIz7iiAiEA+yFE2YCzAl2FpY9Em85rt2ARrmv+rx1vQMVSwceSlas="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkKQWVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoodQ/9G/wV02SjvtxtjDbnkjorOuM4p7u2n0N6aDygMLixqyu7ezVe\r\nypfjdwgSxjHFS7YfsKrtoUbkVN2fiWwvSBfpZeM5Hu6afq7uyr0HuiEPKS2Z\r\n4x2UBIsd3vZR89L43Bo1F07EolrKiwpa6Bp94udOHk0sQLkYXWm5sytpjIks\r\n8z1q4bnUhc+9EMuGpCZmElAQUHoHkCqkO1oBNyGj6Pj4arlb5394bC/Wz2ko\r\nXaMnB6TriNGSzBHxEQn9/bXoQktBx0UTMC/Qx4FLjNjWKbD+01fWirGif6zq\r\naUxF6D8j0cJ9d52bBnwH/1IfrUD7h8r355JH7jhbWeNLjgd/o9KsP73ejIdm\r\nnAIfbIR7FCixYvc2bcsrn4theeE1esdiLXszXB7+wBTjiAHxKueTUI21KFh7\r\no34MCj0GIPibMh5huH/AUeJpFD3M3eQ+VROOTnp66O5SAlQJ6Vfo9frFOYOL\r\nl0OcOg+t2FFtYsrOy4h+h0pDsFUXQDlqEij7nyhpIeTy/4PTHnNSCX6SbRdN\r\nqzz88QZ8vNkHfLUt14Pk3ErpC8MY/t/PzsRwSAGHtks1KPKYLWWpUOpCWJhO\r\nokNWk5HthANxX0GG0wkpB7kXK1CUnBCdJeFVmYEoAIW39FuERYcF+otlVk4T\r\nIULqfm3xQfORnFOgUo+EhBgrf3QlveF+2OI=\r\n=S+fC\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.60_1680410005515_0.39084136691282345"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.61":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.61","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.61+4f9ed7ba","@latticexyz/schema-type":"^2.0.0-alpha.61+4f9ed7ba","@latticexyz/services":"^2.0.0-alpha.61+4f9ed7ba","@latticexyz/solecs":"^2.0.0-alpha.61+4f9ed7ba","@latticexyz/store":"^2.0.0-alpha.61+4f9ed7ba","@latticexyz/utils":"^2.0.0-alpha.61+4f9ed7ba","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"4f9ed7ba22ea978623b6d54e9731081580c2ad8f","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.61","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-iwIPm/TibnKixh1mdRTvyNx8Ugg2dMd4DppmPFP/UlyBubuSUYHvsycR9H5D/bwCsPsxfipa+blc/nzU/ExKtg==","shasum":"21b21a493924e2d0ce6baaf2478642965d2ec8ea","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.61.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDTxvl7yZ4Ah2B7XVfQu7Y6+mptQ8rUpFk3XJXnJhnegAiAHq1l1ehFkuMiC5N+MuQnm2K6GR/2AgYixKat6VAn7Wg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkKQkfACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpBLQ//VETVFJE0tEVx/0QRW/28tW53BEECFpn4Rl+iU/k07MAz2xLl\r\nr4OuvdEqcdumZ7fY/7j4PhIC/cSHSiOO9p/GW5t01B2kcR+4VIu1VTPZmRwQ\r\nbu+xDac0GBZwCClg2RvNRzXTJ7kecvIzW06+VWorOK+usdQgfPEabjgY57oH\r\nNX/VQusMRCl2aEX/DxBGgjZ7OU4I7i5cEpFicqN19vHt0Jt8fbvc3/xKp48u\r\nF4sPZAbZIh+Vr8p2QG9tmDrwXo1/8hYJ/3a0z0ecy82ofrg76LLt7MQAi41P\r\ne8v8mxlsJmxVuaTymV+qUbCyO9gCgCD/IT3+Iq75Om2mnjS7+8Kk9LFzIBC6\r\ndYc8f3hiCr56jLv9xBUDjcSzubzhzwW8mnRI6tKQcVMgGn0O+f/tfnWgBGjL\r\npW5YSqpu9cD272fm+FlF2PzA6FBr0r+6Oo9A7C3l+NJXx0lJaW+5YI+adTO4\r\n8u38Ype/XykXNNoxvtfI1VaHbgy2p6Ud2wqtqKFdcBWD3mim+Qf6UvHf5h9j\r\nyIiqzDwhVgvJtlvm8hNQOV9GlLjQ/2HKCvWdDcfr7uPxvQRcyj/EpM8KFF5c\r\nzRTCudC/YuX0YycpDDrtjObjjGnlKwNjFsAFrafzozrskNLnRoImCrpClxP2\r\nPrlqZ3G4pIwCumht5xZe1gjjrEXwG4v5x/s=\r\n=6kO1\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.61_1680410911088_0.25891288894496034"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.62":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.62","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.62+9c5317af","@latticexyz/schema-type":"^2.0.0-alpha.62+9c5317af","@latticexyz/services":"^2.0.0-alpha.62+9c5317af","@latticexyz/solecs":"^2.0.0-alpha.62+9c5317af","@latticexyz/store":"^2.0.0-alpha.62+9c5317af","@latticexyz/utils":"^2.0.0-alpha.62+9c5317af","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"9c5317afb2c4a9ac2fbaca424f90f30575dba671","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.62","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-RA/zFc8sXmYmNO+hF329FLgfm6zS0vzbTggpbnFAq/xRNOYflIEjV6H6vOGVxiYEiXor5QkKJJU5vzunxGg7mg==","shasum":"5447ade954ca008a9fd5f866ef5f4b09bc64c457","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.62.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCzydTxunRrXgD8yYer48E5GsmCGq2U4UBYRiPcaabEagIgNMT0oIaOF9dbMKJUxPfdRGjcMP7bV4FoUThebD5cihQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkKQysACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpcxw/+MxUjzCrOtL5xu9fNLIhhGjCVGcVjN1M5ZPs2DFIjytyP2SM9\r\nvdHab4MYMJs+/vy9zhB+iDNJ3Jag8Ekupod1ZnO4UI1jfOG4bm2WlpUESdLl\r\nt3VZkRdcl/YKR43tppHAYw8EdN/s4YMYDrIWwjZts/cVu2PQavtagfXZyAMM\r\nRvdwS+1I08zbhIPWy7/5VKS6xFRf4iBrklstCWXoQtAqFDp6xVvDzTbyR7zp\r\nv19QiDGNuOknWNkrqb09P09+INnrHRH6g/6YGTBnqRsurvzci64PWZ704PJs\r\ns3lYBu6jc81eK468mPIbiB2mJACuhkx/Cr5C8EnWhI/NfScp2fi4yddbkuIb\r\nG3rFYiJDUm/zUsWGw+CoYrbxREI8JW1SAnq7Uf/OYHaeW+X83tGNXOe08foU\r\nZJkaWoUPvn+rzw0bnpBkRgis16T7EY+DP/vmX/Hnz3gO+CCFrqB0bjc/qKIj\r\nrlJidTLFH2gXppJbJ9cTt921O7NSJwn5HSKu2zZ9hAb9e2yQ+qB/hkLfPhCE\r\nD3RWItnrRAiDV7SttzdIxsbmnJj9EceW9nRHmLe1+W2r2fgcoCQvM9Sp9jTD\r\nyz019PXA4ghrq7Svr25hIBIKYTIwn80qLossgTTiqeg6nGsWxrgh2uNAuVKu\r\nIDifFA1YK0hgRD+v7vSMpwCWvcdfJwzw0Jo=\r\n=blU2\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.62_1680411820230_0.7429088055907438"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.63":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.63","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.63+b63aca8a","@latticexyz/schema-type":"^2.0.0-alpha.63+b63aca8a","@latticexyz/services":"^2.0.0-alpha.63+b63aca8a","@latticexyz/solecs":"^2.0.0-alpha.63+b63aca8a","@latticexyz/store":"^2.0.0-alpha.63+b63aca8a","@latticexyz/utils":"^2.0.0-alpha.63+b63aca8a","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"b63aca8a6705b3507ccbb1606734c0a0058522a5","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.63","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-/TQxH4GoW63NhDps5jst/nNrmdV1CsTuDqjaajC2mlKCwEX/ejCnP+UVSlyd0ILw81wDQJNc5oYL2ZA3yyTJCg==","shasum":"d06c322f347720d8ea66743a9fe37818e93c1a59","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.63.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDR9fQMSOJIRf9xuUfFUeAMhCwEggbBtGBvititds+oKAiAsirZwB99o8PK/Z1xLj2XzyL2umtv83Ou8EPFHLMEWZw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkKUXfACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoLHA/9F0aCJhlXMOnoFQmM1arHvRXp0l+liAh5QwVrYw+J81v5NMKb\r\nV742WdGjfqOhGotOzf6XbtKxQkA2rnRmWDUthSbhnQEIOCOGZBb3FaFHEK08\r\nFO5wcQqNg7mUfUNYRz5EcL6Eu5zLpjjuXMr8W1GQ/uqHBlKelqBlblYU26Pb\r\nNpzrE7YBv4tO8mELDyxvOAxgqJu5Zc/cLFo7w1j2rvpNNdmzgBEkX9Ds9Of3\r\nUyniIIDPKlnOp7qcuwUVWX8n0lbKBoj87a6JSS5t/VNg0zyFIlY+mMXOVveg\r\ndJQJeB5vh4zrcdfngtpDrlzCfgjRJBB0rIjSkDqVXLTLx4yY1tSOlfmklZPd\r\nC/oa/5H1mphD71RGzxfs57KPcMCIG8defJwdnqny3In97u2634ARWAj1kr7J\r\n8ZfJLcMrEyxL6377teDzxs/vk9uo1HDZP3foO6JSu0BDTvxOP1hJkMPS3//Y\r\ne9qTTdeTmT7py/kuPF9A41DzRcvpBd1AswbAOswEf+Y/cIkOJhQIdatPeE77\r\nPXL40hpEiLacSDZoa1Ykvc8vXyfeKbdRR21ywRhdT0TacdpJnESxeSzL4crK\r\nwgZO3WicVLRnzwM6RpCvYt6lpDT174DTVxoFX9A4LnRNIPOBdtTJhi2GWo7b\r\nG2jrFM/fef63uvnkEFd3z7AndJka1PjM2as=\r\n=C9fn\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.63_1680426462995_0.13009259706686271"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.64":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.64","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.64+3a91292d","@latticexyz/schema-type":"^2.0.0-alpha.64+3a91292d","@latticexyz/services":"^2.0.0-alpha.64+3a91292d","@latticexyz/solecs":"^2.0.0-alpha.64+3a91292d","@latticexyz/store":"^2.0.0-alpha.64+3a91292d","@latticexyz/utils":"^2.0.0-alpha.64+3a91292d","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"3a91292dffd93a4e40725fac0a4255daab450442","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.64","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-aucn0sx0fxSYf0lFZAmHZyDlZKQAXf0vltd/ImhncREf2bqXPdV8QWNqavAnmq2U6Yn2r8yCJND2J4fd/aPpFQ==","shasum":"405dc392b555d5fdb2feac16632e5ec5a6459110","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.64.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEw4gHiHoNMrOszH22X/Bvpih5nHq9LrJxYATuio/Hd9AiB7A0FEVe9yjPgcwkaiDwPzsMrNaW7mmk5j/peTZqpQ6A=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkKUa4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmryIhAAlQIotrkGO5fDpxSIoMI9+DB+FA+336Yu4MMbZ5lY/H9sYvml\r\nlzlFBa/ZnuthSnHfKKWuTW26fwBzDrhHHj85FP9tnWlEI5pJv95kd0391HTL\r\n+X0JBzWk9gh0lb+Vh/RUWn2uWNGyx1JCPtKkSG+/cynjnybGnYMMyFrkcV/Q\r\n2AmsoTxhUm/Ea+6qipbaz8ymaplPy5pjagofVx+wQzHrps3in6Zn3zkcy4jP\r\njs08OuGWydIpPQNNNLu42ArSU7nCFD6VFyAGgQyRYsxPIlKdjA26QpEfub9E\r\nHYSdjFl4rHg+eAbVmiNiEpHzydC/pRx1Oj7XniFnKaTboY3WmL0BhN/wQ8Vv\r\n39v7dTk1lV4kX0upvXW3uFqbGiNmQDLv+a4N+C90F+gvbsEMfPz6iDgh4Yuw\r\nx1gHPNHt5Qbu/FgiTqMG4aX+wpyNHrAEtdzQ0YufRwqrOWgrdtbMQ/Zp/+yA\r\n75SVULr6j24IIAuMOaI29LO1ht7AELMSgMqgJQKdeZ1DjYtN188h8gBLnnCG\r\nMpWwCHI1HOQio0jks4mzF8mfM/ToJLDj+/KZ2xegxcKRKuo6eAwS9UZLYPJ3\r\nRMcQPzx2KkUnI/IabW4Rw5F8vrpoQtx1mB0fUMpZxoPRIE6K2e6blF7Vc/T6\r\nzQiCjzlQ3s9tkmB5oo6yJ6OGmRaT8BM7KH0=\r\n=KSn7\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.64_1680426679816_0.9139945176984388"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.65":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.65","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.65+cbef50d0","@latticexyz/schema-type":"^2.0.0-alpha.65+cbef50d0","@latticexyz/services":"^2.0.0-alpha.65+cbef50d0","@latticexyz/solecs":"^2.0.0-alpha.65+cbef50d0","@latticexyz/store":"^2.0.0-alpha.65+cbef50d0","@latticexyz/utils":"^2.0.0-alpha.65+cbef50d0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"cbef50d07e65802dc49baeb26065d9a61ae59228","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.65","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-2ZqrawTJH4JPUXsLgDY3GVPqSd3myWVhgkM8wxE69d+iv0QJ+0I+5jJ7VRxd8tj4xXDns+LdQFNeptNUWVAYBg==","shasum":"3bc72668abff50c7fa23034fe46e04d129722b6f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.65.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAFW5yl4Duc5QyhsDOQC7fBXuBC3GZgBT6jWmim3QaBTAiEAjpwdKN7aUg1Vn2zUnfyXw5wshFobXrMHKXTFaiuNSc0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkKWG/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmonBw/9HF8UGx/vXqNzh3QuajXheAESyquZVHllayL/nI9TV9+HukLG\r\nUte1Ef90IiAvMP3KG85np2hEMheeexqv1W6fypBolAeHt1tIuLl405M5npx6\r\nhEBFaEDlCiz9RkCKqHXXNOQ30sTWLq6/Hlckxs6svpv+HJtOeG9S0dvku39O\r\noTWbANFQxusEBNw5gtHvY3uVhOmAMwM6KQzMoWNN5JoUpjfdBIragcEOJRyt\r\nECbxK8xfeNPC0yGiNtTC/pfUPtSMmglwkZDe5W//JEsP49grZYAreEbs08yw\r\nwyLF7y0j0ocGlUfEiBMM/e3IQvoDazdr8osAhtnSa2QgSRgILPtV2dV2lmxo\r\nNbruPW+jKB31EAWaWoqmHnQncMj7IwkLsYTF5W5nae7FnQTLY59pshilqsK5\r\nXxo0rARRgnMREhvRG5xvsiJtYjahdbHYOekJqVrLUbH3T3JayUC9rXahE/4A\r\nha+8kuy80kKXe/X5CIRv7N6m6O/GEJoY/bC/brD+8GUxrp9qMiZR6Tem2YAg\r\nueCbM4EaH3tQztuaYWM7mzIDai5RfBZf3LfCZcbQOrzq5jLNvx5/bA6Vscb5\r\nFPW9X0jqbKj68aRBwapuP8+1E0fFiES5V4OWbkZD3CWAIH6HOaRYt9B3fg0N\r\nPRLkoKAxpHMVWO7W86P3DEO5fzmeJ3Q855w=\r\n=89/I\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.65_1680433599526_0.0975357851570815"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.67":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.67","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.67+8c713f76","@latticexyz/schema-type":"^2.0.0-alpha.67+8c713f76","@latticexyz/services":"^2.0.0-alpha.67+8c713f76","@latticexyz/solecs":"^2.0.0-alpha.67+8c713f76","@latticexyz/store":"^2.0.0-alpha.67+8c713f76","@latticexyz/utils":"^2.0.0-alpha.67+8c713f76","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"8c713f7670c6e83411270764a77ae278fa85ad5c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.67","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-FHAz7KyjgUPhS9R+bjvbSJ1whezpjdUXcg41Hrl8OO7MdMSOc3XiRNWiVtFZzsIda74FYnM66NO0bze7noIWdQ==","shasum":"ce69fb1cc399d636fedb6dce200028641e29b4d6","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.67.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICkrOYbTm4NET3QRUmfZHp8OWWE28YOnP7bRKjWcYyudAiB4CRG5fki7DUcZFz7QD1VWuRYzr3QNcFdsQW5VTp5Utg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkK2ExACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrYYA/+OFslATRUoYRZ3HyWACAo9v/WsyTaMmUIEDl+00gT3PRdVmM/\r\nJ1919pfo0bLzCbpvkER3ovWehawUi55g0fEVxT1IMwQOZt1zFk1amPD9L/Ft\r\ndqTcnWcudFbPuyR6H2mkpPr4wdm5eKYGQ5JTMnvDkSc2++HjE9WcvGk1JOGO\r\n96KXaS/LHCESw9mlBQl2BeA5tTYRKIGyTWKVt2mL6GRzAsw1fbqepKr2DTKX\r\n7mMofbVWP7CPdwPzWWU1UzOi4C8LhSgvnh5aE8EOzeyxH4owosBa06+HQPfY\r\njVjscwTC+GvHF4Z1GMdgrw+QEinivkuGY9N7kYPXEEm91E+gRP1MWJkiTekF\r\nPXobJhF68WfuSRptXNvELVqWw7RoIcJjXzcmz5ZMuaORcm0vLCCFGtzpfZbm\r\nb9zqTHy9jJJHhUM/t8JzWgsFms60PERpWnjRsa088euqhZ0TjbRRZduiK7Fq\r\nRl/u+TxWVrs/cRsCprLUAoGHU8hEuv2CIA4VmEZR05tFd76wW9cc/Vt8kh8n\r\ndIgGIua8i3NLYxUnSmsQ6WxF1ieUyISgaMHYEuIL6zxNVuSbovHrrTvOcMQe\r\nqzg1nShLIjK5YUmAyY7fWXGdBApltD7EcTw8bOY/pYdMNsZvpJ+bNuFlMuaz\r\nVGe46GhBYGBO/TeOQgZqZm3+nmSCYLelVjY=\r\n=Y5HM\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.67_1680564528865_0.37431922124043204"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.66":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.66","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.66+e9b2fc74","@latticexyz/schema-type":"^2.0.0-alpha.66+e9b2fc74","@latticexyz/services":"^2.0.0-alpha.66+e9b2fc74","@latticexyz/solecs":"^2.0.0-alpha.66+e9b2fc74","@latticexyz/store":"^2.0.0-alpha.66+e9b2fc74","@latticexyz/utils":"^2.0.0-alpha.66+e9b2fc74","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"e9b2fc74bc440c1de9bed17f8a35cb7e92aa21dd","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.66","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-SPcnfIq1ipvIcRCxRrSc4pxj3kLU8zeWgh6ZK4qgax6DWM78fPn7lTip+O8k3y3SElGmoJZMYjgtfFbdULYECA==","shasum":"488304abb175e2772cc0a3f6166cac40d4068d38","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.66.tgz","fileCount":58,"unpackedSize":743002,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCNPsVE286lV8ckItEAPEyH4ikdfWzgz2htU2tkJpHpDAIgDfRTPLAodTATDbmpkOaMrA6OXnXUFh7QuIjEqIh91ns="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkK2HYACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqnohAAjlaNcrPS6vEf41Bsq0EBQYCkEIggU4QeZDMxiZU7kcOJb8Yh\r\nvJJGuXrk2k5FpW2EQqn4lYC6t7cj0phG0ktqEgaf7BqCeanZB8/YNRzJLGon\r\n7srAerHgCZsvkAV3xliIZ/jfL0wDysof4B07yNG+do2H9yzRc+1tNf/ofZPM\r\ne0KeO0w+f6Vrpg/uU1Enz+VSpD/7q6M2YTKfddx98MkeLL3xeEwT20FrzoSV\r\nI84YctIBVYVmkScHn6sDLB73cr6EoNl4t/SCQ2fRXNrrZkP8e07bQhhy711F\r\nDgSgpiL/HU4/YXwKCrFA8gxTtJjpmjjLGdJxKFN6PYYePDAA9RJbjeK1O7Mp\r\n9nyQ/ewxMBxYLJsGPrvrvH1svnG3D7ZgiZXTIc8zAUz5PvJxTxeFe0BsM/Pq\r\nwtsTwn/yeT/62NY21YHHkdLThBId8sBpQneCEWanCHwuXO6g9SzVE3JVpXsv\r\nMGz5J1thjie3yfkIToXS2ZObfspX6ZYnaQHreS2hI1CBbTCkwD6jYy9Skbfx\r\ntaiSd5dk3m8sf5BdaLFD1aTERE/Gfq4SVJU+vXO6jKWOiEMt9GgNu2bMbA3j\r\n/cq9LIu8Tf23xU9xcQQafC0BWXjPzNCxCjEYBbI47bRHpEOUGSFk6Z32e/85\r\nRT/IvQ0ryEP2BO+nCmM0VJFJmdwIGNXvmh8=\r\n=HAaE\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.66_1680564696507_0.23629017158091403"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.68":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.68","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.68+0ac76fd5","@latticexyz/schema-type":"^2.0.0-alpha.68+0ac76fd5","@latticexyz/services":"^2.0.0-alpha.68+0ac76fd5","@latticexyz/solecs":"^2.0.0-alpha.68+0ac76fd5","@latticexyz/store":"^2.0.0-alpha.68+0ac76fd5","@latticexyz/utils":"^2.0.0-alpha.68+0ac76fd5","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"0ac76fd57484f54860157b79678b8b9eb7a86997","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.68","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-t5WatSVtoeBlfVHJSwpglktHqJYOiqU0f+bMUIzvFs3DPKzTGx70KpH/p2hPWe+yc4WjxwLghUIbKxc/+l+JEw==","shasum":"8bbe94f38bc30ea8e6e715a728b80d704d2edbc7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.68.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICNuqm53eMNfZRv/xu3qPBF/FQO94HbqFD7BglR+zG2fAiEAjXr9/65Uuj5v5OFLuJlp0RviyrOtOMUM3NjxQ3rcosU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkLBBzACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo76g/9EnV0GFwCbfrEzvNn3wAPmDzmmfpiVw/a77xHyEI+iBH7dmw/\r\nflhqvjwG82Rb8+lD0Xt0F/wu9CSHNUTKSQ8/p8OJAnWikZrmyhFmnaZbC/yH\r\nIGLXYsalK+5mNaAB44itf2Kf08Zp5X5Ks6L3HRcO09f+xBf9U7NC510AoFam\r\nZRDbS5pU03uMGTmTC0eEw3grRdnNMwXeJxqaKtk5z9oqoIjBisIBKDg3Duy1\r\nlbYC9Fr00twJevb9pEYe65bpGhD15nIwy4ZEY0Adl/vh9bTbv3Ih9nDLmUrT\r\niFpyLDLEbjYbtGBOrAZbJH+TSMSRv6Sn21haspMPURnDRYveLAhBqVz3Q2cT\r\nHRjC32NHqJmN+r+FaKmjdwBiqpQV/CUuMYRMFEJ54d48vuRiD8EB0DQ+dqMu\r\nSnbMxJiXI3XsD8IVb67s8KFy79WVHRDqddFpR9tzR4Hka3U0yhYJ67pqkiIm\r\nGVXYqW3/CP96VGuup+2cSqqBiJcsUVg8n03AmFbHSIvTLOdrzMR3BWFFJxTx\r\noB655tRhd+w/Zw378LGNtqwrfjMez4O1EDvIpFtZJqSjffz6T5UtG9olq8pt\r\ncvUiNDoD+FCoNMNSosCxeSk02C4PDa4hOQPCI7owkA54BypXb5UnSzMetpZP\r\njRCby8pxjiaQTif6d8/lF/OX7jiYPg6nmZg=\r\n=X090\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.68_1680609395461_0.8269257196910138"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.69":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.69","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.69+983e26a0","@latticexyz/schema-type":"^2.0.0-alpha.69+983e26a0","@latticexyz/services":"^2.0.0-alpha.69+983e26a0","@latticexyz/solecs":"^2.0.0-alpha.69+983e26a0","@latticexyz/store":"^2.0.0-alpha.69+983e26a0","@latticexyz/utils":"^2.0.0-alpha.69+983e26a0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"983e26a0ee0c0521e99d09dd25ebb9937e7c4ded","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.69","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-t8lJ9t4jMWro4CFE8gWqeY9tc1y1uWB6jpYvJQ86RqAdnhKH+08C9Vw3CcfisdMRwqExG+vnI1lwkSZPSwuNnA==","shasum":"3f4fbf4879525afcac3e387f73e7282c23296b29","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.69.tgz","fileCount":58,"unpackedSize":739784,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCRQBmJatZpNeavefvUnIdrH/H4CnowKv7+/4X2USxS5wIgXESE/pVJOVeWELFUamO/f0qryMqhC1bqn/YE1ep/VZo="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkLCYAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqfhg//c6f/CFxuOACCOtyOcpX/pDpxuc/Ovc30IwY9SoGxoNdeB8Td\r\nA7/oauQ99Zdr+MvVivb3niO/fRltlOCI0EmvOCd/kNJLl7GRsD7hudEcJjZ8\r\nfAEm6wK0ioWVXSgL+h15jZn+XRmdrYeo1XgADW6nZxrz57yx8F+XiV0AyCvd\r\nQ1LULiI6L6COjOkQh0ieaI8kywwuqscJHWq9bt+0oi+C9fSQg0DZNb6IOF7z\r\n9iWRDY2EhRBix/7+7eJTgJ6/4W/jizZ84InfowC4eUsriFI8D+HR8qrYcwhU\r\nzJIVZVJ3OyHScV6TbuwmepSRxB36AcuGvcl4RP3/90WQzmScHf5iQr9ciaZ3\r\nQVTp5pEu3C4UQQ/9K7QkY/nbRAoh+O/1oUOxkeaOg9vU7pbNmCq++oHWjaW5\r\n8D9pRs5DATldInUkn+NcLS2bQi1y2MzllcogjLbbTvExH+O3A0suBCRUJEEC\r\nXQ7GECkiI6cQEOmP8krjuazot3fRm4GjNKPboPix/X1OFq8GLrMr15s6Im7W\r\n2QRk+IA0FgwYGnydwu3f7Okvrn/+PtJ/OOTSf6lWF0EfOtufHdF9V/Z6+NAX\r\nvgqXsafh2ORzAKVFy4Y+dTm4SAU8E3bl7946tFKH3C4yH77+Hp3H6TZCmT9M\r\nr+QHeLk3lViujEAYetQw9+Sq7mHWNZ3oZ/0=\r\n=g+Ng\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.69_1680614912064_0.848529251288878"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.72":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.72","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.72+2b5fb5e9","@latticexyz/schema-type":"^2.0.0-alpha.72+2b5fb5e9","@latticexyz/services":"^2.0.0-alpha.72+2b5fb5e9","@latticexyz/solecs":"^2.0.0-alpha.72+2b5fb5e9","@latticexyz/store":"^2.0.0-alpha.72+2b5fb5e9","@latticexyz/utils":"^2.0.0-alpha.72+2b5fb5e9","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"2b5fb5e94ad3e7e1134608121fec6c7b6a64d539","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.72","_nodeVersion":"16.19.1","_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-dZ9QOLNbzJjE7uveiyPU6rblmlZ/qTn9zBr0LP7IFLfBOP5LzEKmTZXEn3jykOqviUGUTEGmWW5Oe+A5MrFADQ==","shasum":"d44d134ae0f1a257424f599e22236768f4df1998","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.72.tgz","fileCount":58,"unpackedSize":744666,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDQRe6lYHcJhss2e4ORHEHQEt+YJ0zQEWdnR7DPYsFopQIhAPQWFG2PmHDLXtX7PwYStEf/6UoL+sp0t/8gNXPm8DDf"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkLFYwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqoaA/9GBK4y5g1HGVRQt6bwPsi73jhDndJP7SHk5R1Gbv4zkBZjHxr\r\nXM7l6ybwEqHcFICQw+ygbBD+bhb48RdVfxLBchxEYhQNO7hCumBWLZiDwqZo\r\ngUgarchZix133hLrUd+2AWoHftbdmRAqL6uGlGXdHj6X+UVDK9Hk5A2HZjky\r\nFIx14VuzaP46lsPn5b2nqrIXZjCWfVwabpCkXJ3gQDZO5dRc3D7nu3brAoiX\r\nHikXQaJFO1B2TVMrqLmmmLlOE5MeMq852vdNFWvtHEr5VlfPtMY6uLWJt4Ud\r\ndDSUIpqbSaL5FF/xIsBUds0f1Gl2c5xn0pBh2quyhyAee2awN5nmjwfay7BT\r\nqn2jGxHZzr/OtcgXoj9+Mnn2Ru1ZccUST/vDm2Tleyz38J6K+/cNUNMuMY9p\r\nryetKniLA1T4d0VYVurHeieqYZIYNPmlOCAjFKP3bdaAyiuOrSCTJwEYVGgR\r\nGvYL02UUmhqPeQ+Zu2RnOorHNYUVOblUNh/JfH/p0e2xgCLiCNKcPLJ39HiF\r\nLF1LDbfGTczB/eXIwax+RoyREsjvoxzeOKv3glJObsGYa1Ege9j/5VYa3Ib7\r\nSh8+/rX9C3uQbN32LLoGs/gXo4NO7hFAdKHpQ/ynEU/gBpcUid3jBhDZWrZz\r\nazN1SjTkQTrIuklSm3OacSDnWdXu49DeJfs=\r\n=Ille\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.72_1680627248210_0.4663613956061192"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.73":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.73","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.1.25"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.73+5a97bbfd","@latticexyz/schema-type":"^2.0.0-alpha.73+5a97bbfd","@latticexyz/services":"^2.0.0-alpha.73+5a97bbfd","@latticexyz/solecs":"^2.0.0-alpha.73+5a97bbfd","@latticexyz/store":"^2.0.0-alpha.73+5a97bbfd","@latticexyz/utils":"^2.0.0-alpha.73+5a97bbfd","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.1.25"},"gitHead":"5a97bbfd174c750a002514a15f0e88d444a44ddc","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.73","_nodeVersion":"18.15.0","_npmVersion":"lerna/4.0.0/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-AGQFYjaGhVq0ctprwGePffAqx84Q8nXr5i9Dlec9cN0/x0sRNy4MkiSZmBhoLKAqjYMSOqmgKqyhjvLEdb3BuA==","shasum":"c900c7526ce58160540b00aa4c0e80074575d4cd","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.73.tgz","fileCount":58,"unpackedSize":744666,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEBE3+yQneQvoTUE/eRLbgz+HYU4jakAJIYWPe3mm6C+AiBmc78dMR3593t0RE66VtRqJokZNuKuZ98zeKbxS+AnEw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkLFbKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpUjQ/7BivZa740nTKIFbdxPpedUlLznU3lgqF4n8rF66vkk6IpgthO\r\n4dIzD1N6Iss+SwIWYOhgIKXlWYGCmhOuPYMffrBZEypFvnfE58/Gzcx8k1xW\r\nU9oOViWCo53ZEYluhdoVgXrpv5VLQ+Np3DpoCQdHcD41Yiiw9d+Ir5hkaC3o\r\nj9c326Pny4FC2rshfc1o4mMLiOS6ARsYg7MeJeeAiEkiK0L2tuVRxlymxEIb\r\nwV5+poCfxaDKJm7w8eZfXRWrPZu9jyBtz9SB7KTHUQbTVj7c9vvg2rFeVvKw\r\n5/2TdY2dMdeAz13xzxYNliOgAYUviDm8v8lP3uNJEP8sym+Fw2M3TCsJfg9m\r\nST/rhdJVogY/SoNRAn+GiJuZi9ZNfwk1SdgKnDWEHLxmszybclNnmkTkY6cD\r\nV5OWo6IFB1ZFXlJ7hESyxxq6RP78kIE7/zav/Z4l448+wIklNgu5jmVtOUOr\r\nJtG3A2W7BoMdOUVauOPvdXam/9jyLTTSLiNusbbQ95dnbbez9XRczVYJJrYx\r\ny+th31gL3SBMQXqfph+Ms+rvhjl0jW9QraHX3rYVjiuipMc9lS5v7X4rR3Rl\r\nBfwsrqsADClNjUmE/LJ63ZzcK+UHLYokm4I3AAvai0l610OFJHGB4mqfanaY\r\nVVoHVxZD3DjNZ31EJNqAL7IkHbNlprtkf0M=\r\n=LZbw\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.73_1680627401787_0.9441171714094858"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.74":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.74","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.74+d5d22e0b","@latticexyz/schema-type":"^2.0.0-alpha.74+d5d22e0b","@latticexyz/services":"^2.0.0-alpha.74+d5d22e0b","@latticexyz/solecs":"^2.0.0-alpha.74+d5d22e0b","@latticexyz/store":"^2.0.0-alpha.74+d5d22e0b","@latticexyz/utils":"^2.0.0-alpha.74+d5d22e0b","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"d5d22e0b855cc9a606aa6e1380449a0840ea7343","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.74","_nodeVersion":"18.15.0","_npmVersion":"lerna/4.0.0/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-NUNFgZMIzqlI4lIcOAZVep4zvybDocfiLZDBNPv0EKJ7DUxkwz3P7/UU7JWEanKb+w/KADDuFsdopkwB4rja4Q==","shasum":"7aecbefc6657491c4c08f431581cee4335267823","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.74.tgz","fileCount":58,"unpackedSize":744664,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB0K5hm5f8nImWpqRFaBdh/UzlfpVSmaOIMInNWWsi72AiBrbL37k4e0K3kcWLEPB1fdWyBEFEb6P97UvVd4YqMbmA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkLFyWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqr+xAAoojWCSoMBLenEnZOoJwAoqsHwKiCSAy0+6qg4jzBWMvlJEC6\r\nuVdalNJs0zW5UIAYh9MAyOHCvAQUhKPAHSfES58yWhnDWBTtAPlJhqulr9it\r\nbHublK1PXLpz55sbaPXLM+pwU1Y6/yaH5eY9ji9qsRs41R5URflY597JxqsW\r\nBKpPsB0XsWwy7VVdI3dfxPC6NPZTfhuKsYkrf7zDv1xCSOl1bo7ZH0ZVv74A\r\nEvAp85fvNADOsswalc2XuW3OO8upg6V+ttotmE71HA7SoZ5D5r3O0TvJXBZJ\r\nd/ZvsoABkNx/gVSBgn2VKAqF+ZWN1dd9pURNYP4w+cthHcmTg5LPGrwlNGfE\r\nZQQJGEzMb2oL17AB2Y3vZeZnhwJWLxnSKNUWqM6umPd/d+5XUlIGlIq5W+N8\r\nhfrhj2Ub3R8nJ7Y2w0sp6/rfEvgDKA/ubef+mn82ybbEAvJQQM44KYZbNkKZ\r\n+DuCdo2VD/fvBaktJZvDzE5Sc/B2iJracklJHlea2YvoiRNH0YXtfgonA/1d\r\nmoZzFqrTu/GTuyxyGIpgIlcRaMP4UbhowXslvL4hXzAikV+3gY9mEQtCmW6s\r\n0foNut5YWD26U9OYA7qn8i1zmH9AcqBmRVRrarh/A5Pu4jKndZGtaNuWLSJi\r\nXnf5pled7rQc3gv4gd7vEFm9nf67WwBg8hk=\r\n=xtq2\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.74_1680628886158_0.12281530056420387"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.75":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.75","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.75+406a002d","@latticexyz/schema-type":"^2.0.0-alpha.75+406a002d","@latticexyz/services":"^2.0.0-alpha.75+406a002d","@latticexyz/solecs":"^2.0.0-alpha.75+406a002d","@latticexyz/store":"^2.0.0-alpha.75+406a002d","@latticexyz/utils":"^2.0.0-alpha.75+406a002d","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"406a002d58cbdb3f65af5bb47a2c7791ac93d5f2","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.75","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-1byGpGxk5JUKTwSa1+RzDuNS5a2oRpUsbclVPo04w5QXoyiZwyWmj5Ij4wilGEU0riTghtRsePL85EkvYZu/Ew==","shasum":"60830bb3c6a99cf23eac7540c53bd81d742f0494","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.75.tgz","fileCount":58,"unpackedSize":744664,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCkRBPrRIZNtmX5f1ZVOp1F1VPX1qnCc9Jo1t4bfd28QwIhAKH6hwMI0+jdzac6WdJZxjf3NvnA0l0wi+AsYjgMrMPp"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkLKwRACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqvEw/+JISZxjLs4J9luFsEkWG6ZAs0b2BRiAuds1biwt7h/HArIJaO\r\n6AKANHWqFCntbVXKJ39PsSabo2Lp3APJFqkTXGhiOba8aMSNFEEkA6qcp++r\r\noSSLvwswEqOdBX9EfBxEwijrRdoctKZoCOHsOPPB2Q6ctBRyA22IkLRGYgwW\r\nzcHwWFiFxZdEjWjrsgnG2meTIy78VXc5t1589cT0bz0pzrLicsGY6CqUid9e\r\nOb0PvEWtBbZYzT7h0xwIR+kDt3U9vWAflAxBAMMMst+vSRBDbY/Iy/sNS+gl\r\nilYZ6zbTRVOyn+ojk876o6ZgP1qF+jSJfFO+3AUexzaxcP9GY1DvpECWj8qI\r\nkWjUWBXgIBpVjx3zztLi8/FllFuUuxE9YVRa2GpqDfV12JnOj9+/E6Oa0tfK\r\nO81Y2ABkWgsgsCXHLyJdQ2qukSH5mNE5ARQyTID4bIwanWP9UX+JGaVq5qRR\r\nnm0xnJwglPrxdTBwByfQOMHwOJB+2lRgpwM9Gti+f5aik/SL/jPxvtjCu0yB\r\nXWP3U9H8TieL8d2gVO4+J2FrRiOwuujC44r763/JnDFk5Ecm+/QHGSsci7aY\r\nV2Lj22Av2On2iO8rG/KvIQpTdLBOLYbwIlKxNY2dDTjPpEfQIF9H0EENNSNY\r\nD8nOo5B4dowPcehXAwEeEXFJMD8TuTtIKb4=\r\n=yXBV\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.75_1680649232824_0.4865264735554782"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.76":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.76","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.76+7500b119","@latticexyz/schema-type":"^2.0.0-alpha.76+7500b119","@latticexyz/services":"^2.0.0-alpha.76+7500b119","@latticexyz/solecs":"^2.0.0-alpha.76+7500b119","@latticexyz/store":"^2.0.0-alpha.76+7500b119","@latticexyz/utils":"^2.0.0-alpha.76+7500b119","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"7500b119d727a7155fa1033b2fc3ca729a51d033","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.76","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-OeXcO3v+RsAJoF8MwKfnJYTAaKH3CSTg8AcB0fqKIk9pojJYR27B810v7kiQv/mw9tEAoz+ya3F2vPd4fjHgcg==","shasum":"261b5d2d9ad24f3b8202d192e03c924d7bf37030","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.76.tgz","fileCount":58,"unpackedSize":744664,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBlh9eirDI91oz5QdYIewbOVX5IgtcR3LLVqKmO4oAqOAiBdi/ueHZ2BqOHlwuJEF+Yo/O8gAG6541nwtoRj1FLL5g=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkLvf6ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpQtg/+OJFQBqf1aH9cUSMiEbxHXO2q/CF4VkfPoZ/MNH3UQCOROvNj\r\nF3pcY9Slj/CMRz2jKJv7bWP//UwFt0YFMfUOACyGz2JDbY3wjrDQzXjko5Jo\r\niBloHNNZo+OheHwktL1QxSiOqC1kqsRdh4j28XidcFV5Spp7SjnoQpyu8ht4\r\nLDh3CiFKYHy3Af+rvseWWfJXy5SwjK042/DdRaYqGko1e/iTxE84n0Ts7Li/\r\n5LC/J2epmKuAVUUKAgKxIHevg8eBlpRha9YYthzBKdlUJ6GY/lVwqyGAdJXx\r\ntOrw+nO3brQot9+iAAMz8yrdyE+B3RLwh9ofx479/6hGQj7eAzc5fB/jF5xb\r\noT8mhcHBAhnM7z8z1iwsNnEm4djOd3Z9vwmuieo2MWSfXNx2UB25mtwyBHAB\r\nNug8XMiF772a4lJDqVrjuGC4DYFPfsZOFDk8yFhPb1AzzHxygBWfH/nrfNel\r\nOmNZRKAdOWbrBf4rfuTLE6gK1bAtyuTJTvElO40NQCAqEqE1fGl/SgUvLb8A\r\nJ/xwnd/mT7sgR6vvDoCGHsPin3JIngSfUR0NAiypYdT6HZhpuwDZoxChhWVE\r\n/Eh96c3LszJopkHbHSXoWNUgCeK230zWfG1iLkAa9j5Rry2oOv6EIthzOlcM\r\n8HDHCoQOyayqjnm0xDBc9SOw8WfAcklSd6c=\r\n=zFsF\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.76_1680799737853_0.14157537571904055"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.78":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.78","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.78+cf5f4bfe","@latticexyz/schema-type":"^2.0.0-alpha.78+cf5f4bfe","@latticexyz/services":"^2.0.0-alpha.78+cf5f4bfe","@latticexyz/solecs":"^2.0.0-alpha.78+cf5f4bfe","@latticexyz/store":"^2.0.0-alpha.78+cf5f4bfe","@latticexyz/utils":"^2.0.0-alpha.78+cf5f4bfe","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"cf5f4bfe0d1d14e70efbf10ebef47d39f39e7239","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.78","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-G8NeznWmnIfQYGsGkFVOfmg3CzFxW79TIpHTMjGQuCEafHk/pe9hB7FsvPh5IPa94YlfMhmiSN8f1o+fF9Akug==","shasum":"652a78674672271fcc7fdd6285c79985f38426bd","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.78.tgz","fileCount":58,"unpackedSize":744664,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICp0kQJefycJ4AxrralkZBHjGf0SOK7udKBcuxv20bURAiBDCUaxLtAZ2OP798Msw6bY5shtMIA4vf5WmflJoQhmCA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkL1Y6ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpr2xAAguPUy1cm75WKKj7TGhPacQWdsZ7gmW/dhS6qrX1l8C5fNYIF\r\nH9NWbrqRbyHEdvUDFZdKQyKKLQ6fA94vUxG9RiWOsDC9l5r53Uy/0m/ovjFD\r\nzypAno8HMsHMYRZ22pvIHsyF2WS2TXRBF1yQ/rvRlpj7YHLI+lDyKgQ86mTS\r\n6Z1pWdoaaNjgMWVVryVICbJOvr8mLnNJK5pWogttMlDzQ5wmPY6JBzInbc2Y\r\ndjJVTEoEggQhIhRhrAeku2nHSAn3il/XGKcvCA+Ltm8XwLTZedBR1yVjPPrr\r\nH2M+utAWbWMOGjyuzbN1yRwhs+itrhNwKb9EsQBhIf45oimlw+sCbdEha7gY\r\nNQoziDXcxtKmVU00vb8c2y/RnOHnBd3CGe25Kz//LDF/1NJELithj02A/f/N\r\nR58rLGVb4gQg2NN1gjk4oTQ3efPEzACBW4FExY43wvd8wNrSxmu7qZkSIOxZ\r\nUiNtijEjZc5a98XbPwDKMJO8oP+tDKj0EwIACW1sS3TtkKdJlo0v4513F1/D\r\n6EbgI81CzZeFhm1U8hhP+IwTb52dKWP6AuWTSUzpZUd2k1aI0CqxV4R93kko\r\nkbD+NlImjw3rpD8CnFI7mrDPBKLoCjdhVy/pgrOv40roZRp7TV3NLV8m8PN9\r\n0eEUA2c0NRuVVU559tV69U93U3hEC5obmW8=\r\n=IUS2\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.78_1680823866387_0.5165308841357072"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.79":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.79","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.79+cd224a52","@latticexyz/schema-type":"^2.0.0-alpha.79+cd224a52","@latticexyz/services":"^2.0.0-alpha.79+cd224a52","@latticexyz/solecs":"^2.0.0-alpha.79+cd224a52","@latticexyz/store":"^2.0.0-alpha.79+cd224a52","@latticexyz/utils":"^2.0.0-alpha.79+cd224a52","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"cd224a5244ee55316d4b95a21007a8076adefe6e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.79","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-+QkVYZ9vPAclDfDGvUaSK78n4sSCzROCrdOZ/P+v8usTZ59yWy5LXIrKIg018mRn7oxNHDMPMvU0B8VGraTOIg==","shasum":"21246c3ee2dbed3e451bf734343cc9181c4fcd26","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.79.tgz","fileCount":58,"unpackedSize":744664,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGR/lUlgtQ4DjAHcInq+xOESx27AAP8L+JtANYYmMSm6AiEA+OX8fml4Q85usfpuGpraTofjbi2wA7h3NX0ZvqQDdXI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkMte4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrCkg//flOBt8frZLID2eVCreuaDn905CPI/1+9LkmFz+sIS1UXx7Sj\r\n65X72m46By+gg1vaRD7GTHrSWxXEgUwp94iolu/+3z+ASVza4hQBPqnUuipU\r\n4CcT9B2DV8pMqwde7iGCC1nY7vR5CjJk1As9liD7ou06lgzU59Sh/v6jqQ6t\r\n9qT+lO1dRnIwPkrGr4hnPTBl+JyYdVsF9J+atlApff45woZUYMZxVF5Bj6QW\r\nxvwyVw3JaqriOwdEV98xSgoceOotpIYMljK4dtgYM7GXEHT7MzvikG3oKa3Z\r\nkBl8hS98q5m7cX/INfwARjiWI1sbvtamYPJ+gDuffA5NIiFEpkIYO3zEx4c9\r\nYJVTUWMSTznqaLsW0OTVZAzlZk9eWuVUinNYN4bHB+Sr8D0kYnJx1AaZZnbC\r\ndqkKbOCul3+ajJIq3eNWHs3rnJC537JSggubUrQHf+oj5bH3MTo8VuMeEIjA\r\n/JutlVMtUN+fkBrKHaO0g0R9iulNiSW1/CNA76IMDjb+EB++L3wod7ly0mP2\r\nX69GxTD3ssjBkqw2fUgCFDMiZH1XrudC1JIJ4mtfO7rh/CIXfyTxCIOrFMTI\r\nxtdKg30+SsY6ya0PZzPGkLRvfQctLGSGTl/4qUHz7v3pO9PByMv40c4D8l9X\r\n4C7TdSVDFWWyqkH3uUV/sOyprki2KatxptM=\r\n=GAP/\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.79_1681053623914_0.8770885590830673"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.80":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.80","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.80+3eb8b70a","@latticexyz/schema-type":"^2.0.0-alpha.80+3eb8b70a","@latticexyz/services":"^2.0.0-alpha.80+3eb8b70a","@latticexyz/solecs":"^2.0.0-alpha.80+3eb8b70a","@latticexyz/store":"^2.0.0-alpha.80+3eb8b70a","@latticexyz/utils":"^2.0.0-alpha.80+3eb8b70a","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"3eb8b70a5f324f9b2fc98ecaf9c85fe8a9108dbd","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.80","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-1FQsxhxY8v8ND0pttVl8rHuMUWP2M+W1QigAoUi0ZpAlkDf4kJrKqvDXD2x7WJEnHGy1TmnZO87H/FVIi8Qp1g==","shasum":"54763cea6cff64db1b548d2218c1ba7eb14a6252","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.80.tgz","fileCount":58,"unpackedSize":744664,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCEY9z1qlYCkvkab9ttLZKQ1EZYLLxXvbYTlZRlyQ4RDAIhAJ4Ayu8PMGowELvTokDvecQIXgZcQSTRu6WYwqnMaLON"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNXJoACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqS3Q//ZHPdF7TjNBIsYXef1UekznmPl2Dqdg0CrFRVf/RgAnBW3s1Y\r\n8I6xd9m5LqL0pDa2c4D0fIsZCrtD5dK4r7j8v/oLaFOoghV2ffuyGKqq6Q5i\r\nRHy6tqbqHgCv0wParq3khNDuGuPb+/5OK+v/C/HzYHFcBV2aJ0TyWZ4x9OKy\r\n+GNNsZU+FL+ucW2kTA2CPOW7/kMHJIQaldWb+eZQi0Lz5xN8NxszlRX8elyw\r\nonYOmE5N+w5uCFgEV3oGKz033CYTlxNyO7e0wT+xZ6HlvDMner+whuWu6gAT\r\nAd9fvmGrSDlLcG/DGUTpuQGUFb0RHhldgGYga6QNKlBYEs62juBlZyOWhwFY\r\n4ZJlxTKRscW81lLs7FLPSE4qfZMCzsxWIeDPYQi4GHzV6eV/GqpCjmWAorKQ\r\n8rUt69urHZ1s7VwgzzC4mH1xeUOtGbtU+6qqn8nkbhIhW8FAleEc8KZYbRDM\r\nX0/zyvCagOZac0jSyYwA3ekdRRv6a4ixgQMU18rtRKSYIgJCh//NsRVgE5h3\r\nT4pjv6T5fX+QMPyTsgNFKc05mNEynkbupi5xG/QoZqzlSdevefqDoG9efCLQ\r\nO3f/otqLV6e1EBz9BNZ+Ri2LDlzP/yjuVcJCc+/Qny3RKTQ2kSCasmoYB4pO\r\n5YnowFMlabMBUFpjCN58d8CodNMj/k2qqQE=\r\n=G7YG\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.80_1681224295706_0.956010583594626"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.81":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.81","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.81+b92be71e","@latticexyz/schema-type":"^2.0.0-alpha.81+b92be71e","@latticexyz/services":"^2.0.0-alpha.81+b92be71e","@latticexyz/solecs":"^2.0.0-alpha.81+b92be71e","@latticexyz/store":"^2.0.0-alpha.81+b92be71e","@latticexyz/utils":"^2.0.0-alpha.81+b92be71e","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"b92be71e944ce4547193375261ec99649321b17a","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.81","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-Quvt4MN5SCEe+8j+LF522i6xMOvKLgCXEk0Eb7SFCoAZ7IS85hzLcQUUEeWHx5cgjS6S6P1/krxboK1YAWt6Vg==","shasum":"1ef0d892c7c4fc3ed0085ac135b7d0e63172670c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.81.tgz","fileCount":58,"unpackedSize":744664,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC4pWPYetXO2K0Ug/b0vAs/CIdOo5nNhQCZfzIgYORa9AiEAzpfMmsumB0lcawl2AwPZjHqcBpDYf2FKjVyB7iBtp5Q="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNXM7ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrsTw//ZfU/ReLlIizuX2TeXwdCZBBS2fGE7GJmvs/UqZbtw43b4kbh\r\niU/UdzB04a5RfqobjsW5Vg/N+pzfvM4031Wesa+KFQpj5vA9GrF6ajg4EeHJ\r\n01DBS8XjxTvIijVr+cmgQ1Yg/6bw/FheVPT+C1zmDp60aU1ZP+bOgQRfTxUd\r\ndJgDOfQiPKF25rzLXBMl/F8ugwR4cRFO46fEH+Bimsl6+z4CBNSjqaOf1fke\r\nVsDv4Ut+5Uf1nQG/0whXlcqfTHp3+HngnEkLLtW+Xz4l2Eg6aHAbZHPD0tca\r\nI4SJZ/h9l8Kg3J34mFLaFRjrQ+rZgiODsNUOgyhYwZJB//70E9sV4QbmmDNy\r\nk0fNF37/ah8M/oVOvRR3a5xxmykX+TESOTBevdXERBt7KdEoXtNoTbgJlL5Q\r\nYLJsi0SH/GeBfxfcRQdF2Tpb5TPwoyfK6OFfkG+LGquKnjDiBm/aibmC1Wzf\r\njJ5SbgQk9kMhH8tmbiH40Of3fhlR/PJ0AhDDIduuvwvVe1VDIspOvrxxzkRj\r\nw9brBzkFSkwp0h8b7bc+BZITEdHeYNSxT4XCnKxOIQ99mecXsDgrnmbjY4Km\r\nx51zcF8OTmc7hfOxpvhpFXr+v8KpgYUdtKbqSfT0yO6UbgA8J71JCudPa+WD\r\ntcbLaqfp3wt/Unt1hQuRhOV5cShCVZ1WASc=\r\n=8v2l\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.81_1681224507407_0.19600377091731214"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.83":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.83","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.83+bea12cac","@latticexyz/schema-type":"^2.0.0-alpha.83+bea12cac","@latticexyz/services":"^2.0.0-alpha.83+bea12cac","@latticexyz/solecs":"^2.0.0-alpha.83+bea12cac","@latticexyz/store":"^2.0.0-alpha.83+bea12cac","@latticexyz/utils":"^2.0.0-alpha.83+bea12cac","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"bea12cac16a2e0cdbb9623571cf0b02a5ed969a2","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.83","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-oopL78ge3BrIAGSm+Zf46j9eIh4JNtEUvbFD7HsFradf7ecr0mbhKEeZBL7T4mIl2jgQ37JbY24pO/lRvKhrPg==","shasum":"05010106a9fbb7819b258dcd196c987437bad98a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.83.tgz","fileCount":58,"unpackedSize":744664,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG2TmGHvnk8Cyy8bbc8ftz8GnO/gtca2oaiQViGRm8OaAiBTKfU4ShKyx+XazMAdmET37f8Lh/0jS8ixtanFn9n4sw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNXXuACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmocLhAAkxjvrDt5645XsbB2QgTb2QeDywLVR0cuBbYIGe9ftRYk2pT9\r\nJ4fznvljxKWbLDEm4rud6gtIJk3WlVAAWMGvreuDQxT70LEkJhQgZeQHFemw\r\nAqp3twoyRqkGkJ5MgI3Y00wz2YoXgg4AyTDFu5mw54QuqJUDzeUHJ+Q/dxBU\r\n5Cdhv6serexzIbZvI+a7iXTXnVGCPXCEhI+CHlSsSIaS6jbAkjbYuKXGhBXW\r\nPKpVGVJMlh/xOv0bCBKUeYaCqdEPNCaxVRlOqTc2mKR4zSaGmqvlrG77ObKr\r\nePt8no4ceD6QbSpm7Ujp/hnha20OusK2IgC037Hg3asGR1uBTym652MQVmRq\r\nm/oay9QzIVFxWBiZiwW7zuvbyU/LlZYOSkvE5Q5LC/8l0rOKLsOce2//CIkg\r\nPlypTMplyzAKkPkyue3vTl5E73YTZTphJAAbrnA6amBLP1BR0UQugtdwfFU8\r\nkE36G+J/uLeBx4WfIpkBy0iZYmHAJRhxMpuSnpU5Yq30n8/QKW4/+yVIDRgv\r\nAhYJaq1QWWRihQyBmt4Gg8im0DjdRXJIk2q08DHAPsNv4NKdfT44hDBz036g\r\nhqhOA/ATMsvl+mYYlnnaf1tD25IQsLfpZM303rh/p6nyaeap6pkrFhUI4WOE\r\n4LWcZ0ouHRak5bOc2kEAox471DdbyjXxs4Y=\r\n=Gpil\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.83_1681225197713_0.01928500993376403"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.84":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.84","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.84+089ff2ac","@latticexyz/schema-type":"^2.0.0-alpha.84+089ff2ac","@latticexyz/services":"^2.0.0-alpha.84+089ff2ac","@latticexyz/solecs":"^2.0.0-alpha.84+089ff2ac","@latticexyz/store":"^2.0.0-alpha.84+089ff2ac","@latticexyz/utils":"^2.0.0-alpha.84+089ff2ac","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"089ff2ac7168d1bc5568b3b78cc73e14cd8ac95f","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.84","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-w+aWXvMIqPNFwtssRmUAbXjL4ts/D8Hx/A8HFN1IvNSVBmuo2BzuYM1OryMBE2wnXy4IemAxKHPxlFLnaR8SHw==","shasum":"3063bc55087d80be8d916cc75d50268632c68288","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.84.tgz","fileCount":58,"unpackedSize":744700,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBztwLQXhhgoNjU/NVTlhXg2MVuwglV601BgikycqYGWAiEA4kv1OHa0w+U5R/BwXGlwFZo0yoZn1Q2aTumwS9ORBrQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNXyyACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrq6Q//XPd3fDSYUJK+5pF/E0I5bXaNF+JTKEyzWlgZdkCIxz2SEc/C\r\nNyNyZrcDSG+A8NHk08EJ596hYNoiIYuNxQaHNzAVxHuOkYmQOTRSNA701Cf0\r\nnYkP8pbslVDKImkzMLrn7TokhlvUSBs67w6XKHT1iqAFa9ZuKqkLFXgXdQVc\r\ngXcqlzbeQcIgmrdJZ6/RHs+e5dtc4kN3+7bIn4wyO+zPVO68JIBai8kIJ1kL\r\n4aDf6c5Fk2+0fhbAeRWz2Yrq7UBojQgCJJ8KavU9c2Ghl+n38G5z9PElZ4Df\r\nOnS2xu7V8eXDOYSeUjNjxLPdzvbmyvNuyayxZCF5JY601xhLuoVrVkjJVgwq\r\ny+RpFxNRki4EoSzOi5yYrJpirMTgztswgV4whWmlnmIcMSTUhYNw2gzM4Rel\r\n/4t2BAP1hj6Rs5TtNk5KqEpuTa3hUUUMa+aci4aS/pIpI9CztpiGAVz+POwD\r\nEMnsebguZVFfu55mR/hY1m0y3Uuk6eMcr09pwO6BxwDao0lDBXMu4SWIg0/1\r\nVJ04v7tisqsQNxMHRjllK/qu+wOUKG3Al/0mnFL4SjmVyeD/THfOxgvqvR9S\r\nfDGkgsXEy6FrmItXqaq4GVek3hLjUBCkgjJ8FJ4yUfy+6IpC28+zvDos4r3t\r\nNkyK+EyYfoQd0owMHiGv4NU82bFtL/LC+Hs=\r\n=K/LA\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.84_1681226930550_0.2770220924032152"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.85":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.85","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.85+4b532bee","@latticexyz/schema-type":"^2.0.0-alpha.85+4b532bee","@latticexyz/services":"^2.0.0-alpha.85+4b532bee","@latticexyz/solecs":"^2.0.0-alpha.85+4b532bee","@latticexyz/store":"^2.0.0-alpha.85+4b532bee","@latticexyz/utils":"^2.0.0-alpha.85+4b532bee","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"4b532bee7fb0445ed624bd456b97e86a8f41e665","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.85","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-nJg3dHiAk28WnKNXsYIRo2HnY0LaKKp0d1y8s//vjEMIK+T/g7Vdo6EEMvz8kiDc/FgSdBOh1bdmKNkfPSk7lw==","shasum":"0f5ac2e537dbb56c74c9f4d69b71f44018239758","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.85.tgz","fileCount":58,"unpackedSize":744700,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBJmRmxcAbfW6KeJ/URtjWR7Gh8lD9egnr/Juv+R/T4mAiEAvojV2t3J3lL1D6lBIhaPZm5WuLsRlYAlvDcNwrSXXgI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNYhgACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrs6Q//Q9PK8a8RcxjyE9Uscv/2/ljpoGLZBYxQx3iP/76O417AU+kY\r\n7efHW1aH64L7qX/2l7Y7j26ce74sWrPAOqoTVAcaeLMj+cRNzExURyeS7QXB\r\nfhdUxNQc9Nd62MD5jqpitW+puCNHLebI2/gtgp5EP/U6mg3cMBVOHrYVXbkg\r\nxbggtxQvw8Q4lndPzcYJ0K7FpnsPO+MVcg9YVmzKwG20FUvcGohM6jIBUqU6\r\nBM8cYokg0Bxz3FmiiiezL+nL7Chpf3wjZxW998CUNcqTkYZC19jI0yiha4a2\r\nNdyLHVnD/4BPSUlmpQj0IXm0KJRMzC/0u1pC7cq7R6BA+ejiwEv5vI0iUJOw\r\na9G17pt9bYSuWeXxbnLM5BBAahZDW/sp1ee74ETKngzWgXROP1sdoDioRnFO\r\nq1CGavxnKuzWOkfMQtDIqAvM0lR94xxa+ov4cIz/OHvnWYSsQ5s9iDzh0DuE\r\n4CI2+0gE475HokCF2/ot3kHZzPXPj20+XEE5/ysbMrRGMcn43kBW2lkvGJ2Q\r\n32P78eS33I8ynN3O3q7Bmbl7Rvr2K/8U2G0fdfzaje6Ow8iO9vwEGKyTloLY\r\nyCfUcDTe8G4ZOoQPpoRgpYcOLxCuzFkPXce0tu4wD73LC54wIPgXE3ojsL/E\r\nP5C4kZbchi2RTY/qYA2YM8r72dzKjbjDFI0=\r\n=E5Ep\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.85_1681229919961_0.8843404032473436"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.86":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.86","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.86+98047f77","@latticexyz/schema-type":"^2.0.0-alpha.86+98047f77","@latticexyz/services":"^2.0.0-alpha.86+98047f77","@latticexyz/solecs":"^2.0.0-alpha.86+98047f77","@latticexyz/store":"^2.0.0-alpha.86+98047f77","@latticexyz/utils":"^2.0.0-alpha.86+98047f77","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"98047f7779bf60c3758967bd82f5c191a882eeb8","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.86","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-QtpYDvBTbT+aSGSRsVUBZGTACEY5rfYB6cNIfdFp+Gjoi1+E0bMtgpw5opy44CsTJZcI9wQXvOvO0vI+aS2VrQ==","shasum":"879514c90ed783c7b26180c910df674edbef5be1","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.86.tgz","fileCount":58,"unpackedSize":744700,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC3GVNvRKGw/DngmB8Y5fToZ1kAM6RKidHg5xu7SufiyAiBkLJM12Vf1MBoNDzq1XhHS+5D5KEdkXcZPGmNYz5XF9Q=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNZVXACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp/aw//Z/DtW5afS6QvjeK4KFvKU79uZrIsp+rdQSuzb0zT6a15tlEJ\r\nhw0alMxsx4rtX/z7TE3nt3ZJHllLmG5SrY1qpHPkZN/947FZW/YBrCDyL7Ip\r\n3yduUnVhP3+omOJ9wxQ0dXIzHfs4WpXCUcSPec0RKOu6uawMZv+q1v7UnZpN\r\nBT1FyQKHXuJ8jOrJ8Z2EhNDTJNGveSoHa37GhmmGTDjIN5Fz76/p0+Tgqfaw\r\nVHZnQE5Xs80tl0VUl6QVrd+Y3JOyKGSG+uTvCBFI+3+5rNqj3kJDyLd5SqQj\r\nozs3yO/H5zbQNXB/NiM3nJJ4aLlOEOsjnEp9DbnOnbBI62Q6LKH+hVFQwAav\r\n9sbmC2GpzAlAPkzJqdiX1hPxsYpzpfrucEX5Eri+cCeHqrP4Pvu8IwioB5yv\r\nCq6V5x8V6hnKz83hf0+z7PC+EHOcFD2RYMpovMHu62R9tJaOHTEZ8sZT6RXB\r\nlCZq1CDOwZ6XCYUU0ZaGQocmCOQLU33FNFueCKxd+/dxzh9q/QGxv0MK05CC\r\nMYmNQs1+mPQ6N+vGk8SdutM94d9bTbl+iq72cwF888K1DMjQgD1K/+fZuj13\r\nvxKY3HrNuqUp3U4IEI92tVCubffgAy0cRlh/+dM4NGJrckSbBviPtySX65kD\r\nM8xHgtCvuDyv+rQxYVYp7K9RyXq3OC6CUbY=\r\n=MQBL\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.86_1681233238776_0.37692344578953585"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.87":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.87","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^2.0.0-alpha.87+fd912b14","@latticexyz/schema-type":"^2.0.0-alpha.87+fd912b14","@latticexyz/services":"^2.0.0-alpha.87+fd912b14","@latticexyz/solecs":"^2.0.0-alpha.87+fd912b14","@latticexyz/store":"^2.0.0-alpha.87+fd912b14","@latticexyz/utils":"^2.0.0-alpha.87+fd912b14","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"fd912b1497bdd4af4de7c77109ff4a402e3d646f","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.87","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-c8b6IJh8ZvjgXj8zMpig5zdICEUJIZH36uq033efsGKDFkfYXcnKC8zTIlkQdFFNbNhzBjIOGYZZvxlbma3ceA==","shasum":"43e2e9570f4c873a8d388ecd165a6402d80d0ce7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.87.tgz","fileCount":58,"unpackedSize":744700,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDfPbtYEfhyRZRejKyOp9NgdQ8AtPDR2Gkl+o8/PRhBFAiEAwjVmJtifWHw0rBop4ffSJotCh76aM02O1+qBOTehs8I="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNbwgACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoF7RAAnL6VlZ2bEausA4k6VDIQf6XrS5JaH5uB8VbQ1gKUmd8Dcjcy\r\ng/ykx2TtB4VD23xaku0xPW6EhvYeBwXRThawMllpuvF0Fcqj2FVJEPR/UU0H\r\n5I5RHlo1u0saXSRIwDu3MyI1m57sfsByv1aRa4oDrbOWWB+4AGUepB6+DTiP\r\nKh7a24shu6TIFKK5FUryc3+CWmr1WGPmkvLnhKucWIEcVzuFjh59xgEMkjhW\r\nAuZLmhAO0aGn3YOg7cevHq43vsT3R6/xhavnZOtbhXChhwnX+6GLw19pm+Ih\r\nmsI95fEsUcEw9HW0m6MLO4Arv+n9UD81/a2JxI7SdrQLNLwtb0efAIT04Jr7\r\naT6oi7E8LhpmfkaRkV5UGT+AQKnOduK7Xd1PgHBbAqwji7k6e/5PVbhD5nbu\r\nT6+EkhxlmxCwMlEzOTtCa6vc8Pm/5oydZdo7dGVC3+CtYVIvIzuU4lwwfhjq\r\nYFK6gyAWl9Ud89dKl7RNWdb3L2HF0LonMQxG4hJI7gJNJamuRw5WSaCF/OOB\r\nlddFBLGKHZWahgmJMiqsXNMq8iH1HD7mG5wzSZu0/8GRPIgNapBS9/aNutun\r\na+/mfa72+om1XeSgPWcR2PRA1Qi7lMFUiHJjq7DZe3oGgt8As6xUllXF6vgO\r\n7L9bshzhk34B261vGqa2/nauOfRBFmywHyY=\r\n=nIuS\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.87_1681243168262_0.03228249582630882"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.88":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.88","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"pnpm build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.88+4fcf6eba","@latticexyz/schema-type":"2.0.0-alpha.88+4fcf6eba","@latticexyz/services":"2.0.0-alpha.88+4fcf6eba","@latticexyz/solecs":"2.0.0-alpha.88+4fcf6eba","@latticexyz/store":"2.0.0-alpha.88+4fcf6eba","@latticexyz/utils":"2.0.0-alpha.88+4fcf6eba","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"4fcf6eba5e602ec6e07c69fc6f975d857547522e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.88","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-/lJk6w7BKmc9IPrBSLtdBDqO13PKxd1wHGpTwUjx0IbfU7isfgY5p5kOZtHNWJ9EJLOPwjffuBUmCjIz6NAdow==","shasum":"2447f7a3aff87ff664cb25c06ccd9520ed90cdc4","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.88.tgz","fileCount":58,"unpackedSize":744731,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD3h2obk1C7k78RqJKakTITLC+KBmlag5GsnHZe2xn3LgIhALbGtkbQukSXBQduhqfxwzOpxXJ5GhGC5qJfmDYzbxV9"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNvYXACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp7tw/7BUySL8sUXPVDNv7Fhf3YfRZAlHLUcfG8CcOH96wtveommO/v\r\nConsXSwQyZJtss0cRIgoroU7UCYl60IP2UYbV7KBvVIRnK64gBdYWCjSt+wC\r\nyUojhlelcs4bAq9I+MNFwQC5sIq/66QmJx4nCE5p5QQtZOjmHCzriRStXFi6\r\nXVwfzxPKddn1vp0hC/iQrQfpdkQ5Z6scEqZFWeBiY379g5FyKrSof3CfMFiI\r\nPdibk0++LcI3u8Yw0JFrOV0jmXCEYiIqUOhXZVbNCCL3EI9gQXABoVCU92Qm\r\nf+Gv4kVO0eZYeeGnYmqw5rmxLmUjVDbEzeXq3jPGcuHJXUgW20G4X+U8Ojbn\r\n4L3eNPymOeRI1vMtuM/9tJT6tcMt+cyBUuUOG9XGCl89m5iDMrmX8E8DI3oQ\r\nTYC4Zs4afXGHoRhYCGkQ2j+b8Mkzqi1H+xFY9MiZpMquOgj04Kt4TFicsXTM\r\nmO/b5f0am4ER2EXUZ7d0GAZX1RS2NWVVouRk5jwcVf2344RhDbyXRCtf3u8h\r\n/En90QbeV/Tj8DLVIUODMmT/rPaVMUSKLZP/Sn62nP6MZjc2GGLLIVqnJ8SU\r\nCZksk+xZuydYhAPDsa4VsDKzR6zAks38GCqCjxxga0defAc7HJ0qs5+37stw\r\nZiBZ7WZZGFWTClIFljyYNKymEQb8WSYtw7o=\r\n=rPjx\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.88_1681323543218_0.8899170483353362"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.89":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.89","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"pnpm build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.89+53df4745","@latticexyz/schema-type":"2.0.0-alpha.89+53df4745","@latticexyz/services":"2.0.0-alpha.89+53df4745","@latticexyz/solecs":"2.0.0-alpha.89+53df4745","@latticexyz/store":"2.0.0-alpha.89+53df4745","@latticexyz/utils":"2.0.0-alpha.89+53df4745","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"53df4745449015c8b09e0a234fa6ba2dcba4577b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.89","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-B/GH6BDW31FrBaesoZEbdV0T72EkI2J6A41PdQx5TDlUhIq9BClpEBycJ6aMDMME1XNbfBOrkX0DpHiR/f10GQ==","shasum":"42202ebb872ee4e5fb395f4157da286aa828bceb","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.89.tgz","fileCount":58,"unpackedSize":744731,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGUXz2hq/lo3TGFTnQ+dvxyTt00N9YyROPTf5707s61GAiBobICibBpU80A2acjK3aUjjHLkcOhtLEM+tPhbYX7TGg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNwefACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpvhw/+LqORPrrt0lejg2PE3FVgQ2tuilkXDzZ7qDx8byZBRxSlKAOb\r\n8GQhZbUPolbcqMVA7Th8b0DB0vMOwjdKe9agmLJhlzbo9o3oMQSpMniA4xeQ\r\n87izdDwIz8SAJAwe36n9kHr3drbx3V2wiKLq7AEEiOcw6uryuvwqqzyfGmhY\r\nNXk+CBd4vsiJKCBvQUk3aPw1gwUGC8SWCcAzjAYON0PKADHEm2ecH7Ca6B6p\r\n6SEz7F+AkikmEYF3eu9dMjSDrS9FGiWhFzeJrEAVu0TcFOfyJ+555qkC0DYA\r\nivm2qLDsUAEMHW8uGGuQl+nQZcHE44POnTI5Z/A5wGGlZxPVrdRUOO4rhkVB\r\nzmivTE5JrXN1vxf198of/CcB0cQgsMod3YKudWw0kBk/03EZmSqc6k+cFpJZ\r\n0cpNc1U0QvL+dIvWk8DFK6dIbRRf4+8YaetbvtgzgI7Z+0cmVZEKgG2NO+au\r\nVfJUF/AarWQ+HB7WEW8q1r0GDEktt7Y0PR1tcgQjl3RtwbuxIRd2HIpNRlKH\r\nMvf4q7bRt2Iza5SHHVj5Iu0kdDEmovR4bn+m+3HG6okKla3DVuGqu3+2Omb9\r\nQ2bXpoPvXOdbS4y0zRgHeoRzdrx5gM4qsDWeH8J08eZyDaiJefSICZfJ3Jv+\r\nUJw2cjrDOYD+Jrtg+8f2W1fwAoDUYp/R67k=\r\n=32uL\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.89_1681328031713_0.5614314618199436"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.90":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.90","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"pnpm build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.90+26195b8c","@latticexyz/schema-type":"2.0.0-alpha.90+26195b8c","@latticexyz/services":"2.0.0-alpha.90+26195b8c","@latticexyz/solecs":"2.0.0-alpha.90+26195b8c","@latticexyz/store":"2.0.0-alpha.90+26195b8c","@latticexyz/utils":"2.0.0-alpha.90+26195b8c","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"26195b8cdb6d3411153e533271f44b5ef6d3baf5","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.90","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-ktT+b+63DEelYME0Ezqoj4EaqcuFO8roMygCWGuMhobIGtTWW96xNkC3YM/wXwgJWUYgzKACWIkjwRWy+f5uBA==","shasum":"8cffd05121e99114f15ddacddb4026f6d6095624","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.90.tgz","fileCount":58,"unpackedSize":745245,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEIvWNQIN+KldmErZA4R1fk2rWBaqlaCJqYYR5+togv6AiEAkDQjEgVFV1N5PEg1jSSI08gLbH+xOuBiLnK7bkv3UHo="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNw+cACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmojWw/+Kenw33n/H+p1grbbm9l3dVvtolOvFnKTwGh9L3ayCUeW1YRk\r\nk/ywY7cGtCmN6LBwOHqZvxOXIvpCdMMNeYVStdPQt7sCv4Ok6HbhPIVC8qm5\r\nwIA9GDCNlilxB7xFIFerRJfZzZl7RK3MVQ275QRWAOzJpXDJ1AQNKluFBpsP\r\nqEJ90irVmwo+5ZzVeM6b8tZ7Lb9442yQh6SAxqUem/2vfvHpXlhXKuugXlrz\r\nhdURqaNeJAOTBmgEq1B1cZxgJqQ0lUWxVvIf1VoPPOtCNiCTMeXtCU73Q+At\r\ncjCwo3V16+bBm22+E6L5nmtWOAvxsZj9ascpnt8aCscWFKdvg2HIB14i5ffI\r\nIddGeXXbZUHmPwdfzIyfBwcFSLzogyvb+7/es6K2yLXXJ9yr23oJe4NwRaFv\r\nJP/KIB1hkpgngIUwGPj9A7wiJn3lnyL/ETPNdAdQoxzJi0Chg2iQLhF88S4Z\r\nTMg0F9+UIKT2DWRV+FgZojWGdnY/wHhbTE6yffEZg6urN491twg836Z1kqfr\r\n6PpPBywhd4sMmAFQneeGSFCl6g9ojG7ZgOJ9uxcX03q91M9zcRGpXhmKbTJc\r\nOQZlls/gTuKkoRwKeFdCrRT5FI/x1SzH9TIuI1v44X059lMooGJpbPMUvc1v\r\nZQ1YWF200wy2URU3bGNbbHhUrn7hN1G5AV4=\r\n=YACm\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.90_1681330076401_0.9223800867411103"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.91":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.91","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"pnpm build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.91+5da576b8","@latticexyz/schema-type":"2.0.0-alpha.91+5da576b8","@latticexyz/services":"2.0.0-alpha.91+5da576b8","@latticexyz/solecs":"2.0.0-alpha.91+5da576b8","@latticexyz/store":"2.0.0-alpha.91+5da576b8","@latticexyz/utils":"2.0.0-alpha.91+5da576b8","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"5da576b88d9b8fdaecaaa90366c2b85b9dad762b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.91","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-1N0GV2Tz0vJcupmJAgpArpsyzqddRUHISDaJeAebao/CRWMHg6KPTv7xjT7+UZyoiUgEF8PblFlh/sOo+yuTZQ==","shasum":"91f76cdd2794d7bfa9eee5550ae091ca479b9c5a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.91.tgz","fileCount":58,"unpackedSize":745245,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBtSIjWmyTtoHed9DnY7CqUEu1HHxByrbELJfz8sjVleAiA+TB4a5KDTE8zCMmnKnKOTDC8lknWIrIZupIkYaCeQsw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNxKmACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrsVxAAk/2YRFhzEFlgxqPupBiQeWJ7IcRbOhfd8LnKSed6b59rrK3f\r\n6dm2uJ/vaXOC5uJUBGCc1Yw+n+pftFff6PT4tytqnvfN7eIlSHx0qtTPERWN\r\nEMlSYrgP9QiiFisDDGSAkdP0HJPhANGyGGpjlovJI1EbNd5RCGD5VrJI04cX\r\nf4LIKn9n37rh2w9DZVG71Lnf9/G8ZGP6t6Dj8FUuvA0YPq5r9jaMEX59qFCN\r\nMkC9FmjLnvSuO65uUyg2YwXIhcNVWhAkmAUHSOzTcCLbrLVPupeFpNAVl4OI\r\nWRw5YPjTKq45Kem89ieuMbOKTVFNxdMGR14O8gcSDcE8tmRGpbYBz+gj+m1e\r\nObNAcdVecm1GRElxsRbOsggyX9/JaN/XJstSvgv/4n8PuBBFMCEh8PtZzFky\r\nTYPLySF9mAuOO3KsTENTUH7gzBy9BbAaa6/51nFo/U6m1TfhGO1XLmYWG3I2\r\n0ydszFejZ7yJjqHAMKKLRruM45J4aLc/bctzvk2VvOX1yRBNBjrWKQ0goma8\r\nk4yTBx9F7rZSSzugSw53YWq5df42bnShEdqJBzbtGzx7ACqZDdFukhkvanRM\r\nkmYVA+ayVBFg9yZOxbModnPWxhJgv/RsVjw5VqQY4CEpqwCLTqTolVHXex6C\r\nhjLIN/dg9zQ1YBIgUMb/EeoWUgREMIot3Ds=\r\n=Io2p\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.91_1681330854379_0.7583214533938409"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.92":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.92","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"pnpm build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.92+2b4e0fa7","@latticexyz/schema-type":"2.0.0-alpha.92+2b4e0fa7","@latticexyz/services":"2.0.0-alpha.92+2b4e0fa7","@latticexyz/solecs":"2.0.0-alpha.92+2b4e0fa7","@latticexyz/store":"2.0.0-alpha.92+2b4e0fa7","@latticexyz/utils":"2.0.0-alpha.92+2b4e0fa7","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"2b4e0fa75763d420d95ced6e477a2c038baba6f4","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.92","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-QWQsICZABK1Bq9jwBN6zGyVuXQmrIBr6P26JvsLKZGf8+QnwkrnVTBCZPYL1nBQB4KHEqNVArUn/U87/jHLV4g==","shasum":"7e60b977147d852b4ed071da2be9fbb17df4c5ec","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.92.tgz","fileCount":58,"unpackedSize":745245,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDDTpTplobOPm7+ep8v+1cpi/PGECYXU/pqyvF1g8vjcAiA9OiVMnkynQ9igvGq9phX+mbQb/wedpPcB68AMV7LmPg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNyCGACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp3UQ//d7qqGyIU4b35Yo/CnEUGkglSuthsCGr/qKiGm2YfNVnmnx9M\r\niLryDViDd/2z3Et0oj7H0+H5XjASYT1c111bklyrAwuPNQil4tqV4uuCjeEV\r\nEox/h+PX+RfGFTdJDBDxcnt7RmizgmojHu4t+kJoRDsrthzPWmo35/AskMMe\r\nY37EZmwd1AA3qvZ74D845CVtk+RXXvGd67WiJS2+QdsHZ+0AzHKyvBMJfcpV\r\n/WrHfKu12MqdRhnYxeRWK+9xGknWlCYkuaADkkDpYHUv8Ba2m3hBh9ENZI+4\r\n6W0TVfPnq59ezIF/vf6+8tMoaGNyT0ocQxUVLunstqNgGIMdk3HAAz7dqUqu\r\nwuyA87TwCoL0EJn7x6J54ZX5Yr5c0is7NbicC0VqBMfzX+wE1XYPTnvqlQnf\r\ngfQGuvdG4K+yQ7zaALdWrZJ1jsBdXVyHxi90MrRCfw3APRTsi0+eZ49VQ/72\r\neIj7W0YiVxpP6oRWcSMCLmhBJvuXLkZO7gignKQ4w5uQOqI2+EwAi9eryHeB\r\nA0q0HF9/V9vHepS1Z2F7JkACK8cZCpAskEmKlilUkHhGXM7mh4zUEyhP5Fjw\r\nUQ4YxO4V5r6MLEk3tGtQi9n48mlC72xycGAZXd/89C1HR4e5KTSBc23ctNc/\r\ny87UkaB5u10StMnY3owdqTDKmgnTC6G4YoQ=\r\n=5T32\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.92_1681334406668_0.07124829319482062"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.93":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.93","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"pnpm build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.93+16190e69","@latticexyz/schema-type":"2.0.0-alpha.93+16190e69","@latticexyz/services":"2.0.0-alpha.93+16190e69","@latticexyz/solecs":"2.0.0-alpha.93+16190e69","@latticexyz/store":"2.0.0-alpha.93+16190e69","@latticexyz/utils":"2.0.0-alpha.93+16190e69","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"16190e69dfc58c20b3cbaf7628bb1dc1da9ed441","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.93","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-by/fp6Kpz5AICZFUsm2a53GtvJqTSwwjmEyMjOqSH5q+z3ggLFpq/wrvKucBbI1yT/FSdcf2uGNJtT0AldtZow==","shasum":"57eafb8de6883f3c86a77c40df6bdb0568d9ae07","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.93.tgz","fileCount":58,"unpackedSize":745219,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGqseya34KXTgDMzyHr/wDLng6Lyl4d4DaIGyv3T7svSAiEA3dOwU6ciZGoiaw3P1hiJjk8S/f3poYPZj8lH54lyNEo="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNyFcACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmotLA//UCNdXhcdsy2EJsbf+RVl4/Zryc8ZuDV/NX0Bi7Im0QRbsnaX\r\njis0xPC+HA4P4HpgswIL7wTmZtiA4MoGHKiPkhNw/rjSE/6rnxuSTBhGlHSV\r\nNzOZoGkurWoJGWFjsB2hiZJngGOEUUlhEnd4F1YZdsjLUSz4D5ddQ+TGU4Jr\r\nkHvJNVGFIEaHF7hJnhlq44UYcxvlFeCA4avauS3meh7nQqsJu4F81HQkF/l/\r\nsnGJQ3FhyBimvxRj0ut2eTBqF0X5tIJ/NDOq1zmohfeT+E1Yl7xPCxRngjU4\r\n/ie1if5wHLtXPAnp/LQv3gtp0BHKW8XMhc6ibHWwhQg3JKHx3XZJTmWPWZMq\r\nBJ/26H+A7hxVlfGi7P3/QB8mcaUThOJLp8gZ5tm4zez9F8Aqa4JwsHT4dK6/\r\n0SA7dEBV3BjthQZaLAsOND6Sse/vHBHeRfy6LlFdbal6mpOoylclwNy6JLwl\r\n5HaKmyG9JWbxaXO2HmO3vnhlGDIZN6rO8d6Sb9p+aBFZy5EbyrJHslX3PRN1\r\n6FowTf4buoHIGpuIvOE3l/cbzNjn82FzAD99yhXyVrYWWEq9WChXktvHmmtT\r\ntfilMbCuUexRoWQFdCbhIs+8ErcycKj/We1YNKbdgVM8hAmgS4Pf2NO0KSiG\r\nq9LHtGnT9cVavvD8p7Fl/Rf4xGm7DXYSc+c=\r\n=lu0j\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.93_1681334620534_0.019086084673353598"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.94":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.94","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"pnpm build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.94+010740d0","@latticexyz/schema-type":"2.0.0-alpha.94+010740d0","@latticexyz/services":"2.0.0-alpha.94+010740d0","@latticexyz/solecs":"2.0.0-alpha.94+010740d0","@latticexyz/store":"2.0.0-alpha.94+010740d0","@latticexyz/utils":"2.0.0-alpha.94+010740d0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"010740d09d40d4ff6d95538d498a513fbb65ca45","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.94","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-jy615j5tBzcXRMORpE2fND/l0hoJgqPPMR9/q5nb3u0WenYL9Qop/wnVZKbV0xP+DoX85fsqUzo8FaGFJ8EFOQ==","shasum":"5510616e0a7fa85d5737bd800880b53ce93fcceb","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.94.tgz","fileCount":58,"unpackedSize":745233,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFO7+BohEMs5PqeYCQLxHEZD0o3+4I2GntB95VOcl7D6AiAMbcHwaVRxd2UWziWXaMPJ3SVhdBJjuQrbrh3KIFsXxQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkOEFzACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqWdQ/8DYSqXplWP5ecsGKMHF6Pf/VDnWgpm+JpfxtCEiFy2+39qPn9\r\nflASN/i09H2PnwVskvKJ+DOePDMY7EHZDKuWkDx+4Gm2+hkXY0IiZwMhnI5/\r\ngZSRgU5hwg0Bd92noqc0E5NBZHs8OwriXBusY/pMaJvC0rudKRWGDy3iXO9w\r\n0woqATnsV/TvaS0FSDYs8ABxDz/hR9AwLoy2oBjxxkXxeV/aV2hEM4RWUuzr\r\nr8O/1Wz+aGxkeLA7FAEnXwqBQdmZhG/2375vmV7sca+odCcQGG7DPR4F0HUC\r\n7aAXeDLCt4FxGgMyUx2kkVu83BMuKrChWtfPA1f/Y/ZK3IRX01kMjFC1sX2c\r\nuwvKk1czjCBSE3dgoeQkvZSkHXHxuxjIow+OcZByMn5VW8fGp/WIwtZ3KkWI\r\nL8AjGicVMqWxzF4snxHk/OScTbOK3f4pTlVW6b9hemjSrZe8Fejn/n9LZWIn\r\nf1dQIEuJxZkTGl7xzvuy0xIZBIUY33x+LRYt2XpVLyZI3whPLQFMxC0s8TjC\r\nCky0rXcoAy0GiWhN9c2u8dHoNrp0QwIMWHKFzaDe0VPZn4X3RrQfrEKjQnVe\r\nEUqQtCj5uSN10XD0vT5mRseeluIeTmUbtgtRiDMcy29kPjVITqhFO6KjK1Yq\r\nMeLF76gS/evFXIO5cZqQ+3wbd97tD094WSU=\r\n=A8bn\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.94_1681408371032_0.045688584343400285"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.42.0":{"name":"@latticexyz/network","license":"MIT","version":"1.42.0","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"pnpm build","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"1.42.0","@latticexyz/solecs":"1.42.0","@latticexyz/store":"1.42.0","@latticexyz/utils":"1.42.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"ac0a61a9131ed2225a5342bd14f2d1354040511c","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.42.0","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+arm64 (darwin)","dist":{"integrity":"sha512-ddNelbk+4hTZC2qIze2mhwPxanm5jRALhrKjw9c1oe8ZbdEQQ7FdgO5I1094QeJB41CZT9k9zJLQoYoNDKHUKw==","shasum":"1125b45673acdd76d803e7f3d59e44a44e368971","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.42.0.tgz","fileCount":58,"unpackedSize":747551,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDBIoAtfiecDhRCOBqdAULR3CDmaeMp7ntUotbYNs7G3AiAq1u4iSdVEnQqCZumBfoAlYP7eAHi5EwNi+dEolethlw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkOEryACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrugg//VKxDYhOD7ZrckL+6ZrMhg4B2MTpMrAPQOemZ4gL61Zw3kOO2\r\nVcWFhLk8N1JKMVzE/3quoX8kSHR+Ual5e26oYVCh9t8coNsBjiJf5845elpb\r\nXv6ELflrF/RkYCc3vj0SlUou4G0BE1GBrJEvR4hEIyV7AB7i0H9iv92+QjRi\r\n8ezYY9dlCgdfdsDrn7XZ3trYiAaAYc99CPgqlirMDHEG9fPCHfOqWA6bSgOI\r\n6P7HwTWTVF6+e1yY4wvmCI+yRsDbEiXXzPYvHVTeDa0puGQdnRWNlQ2vP6k6\r\nHZv6XXMB9Bd7uWMF0NFYUNub+tfsGIaXmJvxQaJP9b0TYrY+8IjPXeyt8AFk\r\nF5bHroqRWkYggcsdwE2Me0MIuHJHI/isqhfpgvFvNmca8fOXo+Aqvx7dB1yQ\r\npHPeayC/dlYgPPs18SZg7ylBlJo+0+tfjM+OpJeh0b5FG6nq2QY0rlAJCfwj\r\nkM9f8eNsescFybVMkqz+A8Lu2ih3zhp2dy1Za5/SPVHDbpXHtUNv3NuMX4D9\r\niQ995QiM+wKSe3BlWVcKae+hY3EeeaABUFVbklwGJHoR83bHt9aIULto5oq3\r\nSuDVcaF7D2SbsRMzPoDSyXclBCh/N7PmKwxmUds/UtFnXx2/gJYeR7kKhYho\r\nMm0QPNkGT7duAuPQ3VSafMQrU8mW+5X35oE=\r\n=B4+U\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"holic","email":"kingersoll@gmail.com"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.42.0_1681410801789_0.8947984017898345"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.1","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1+68a8837a","@latticexyz/schema-type":"2.0.0-alpha.1+68a8837a","@latticexyz/services":"2.0.0-alpha.1+68a8837a","@latticexyz/solecs":"2.0.0-alpha.1+68a8837a","@latticexyz/store":"2.0.0-alpha.1+68a8837a","@latticexyz/utils":"2.0.0-alpha.1+68a8837a","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"68a8837afadedf17cef13328e8b818b068a22765","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-U0MKrZ7DjRjhOz1/AuXiZkO7hUvPmVGDrhxWBujbGfys0U25HniDurprHpUpN7raXd21neGCL+Md+1kY885J/w==","shasum":"20762f76cf042f3ef4c68e0729aa56fa1a287bf8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.tgz","fileCount":58,"unpackedSize":747634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCBnTRHfhLwXKsB1AwmDebn5N9iCutsWTynEykGsmkUewIhAIAylB2KEIu0EZ+6lRepb71dCe9itEZZP9RTbbngtrph"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkOFX0ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqHrBAAl/LScgY0KO5+boC0CpTyAtHK68l3/SExYkHFUntaNhp3DS4h\r\n7+UrRwZdmLy8WUc+QomAd0Snsl8yqbkFFDSdoa0Y86dCvHY5D7dFNHqG+Mbi\r\nul8wLue1ADMCgWnvdFrYeeYGwWdp119VM99AXEPeSGXfdgSqDXXSHSruUyhn\r\ns1ThcEtjjgd3ukWis9LUfM6TL/D2/GaKn0vISE1QcfpHXsJt3O4E+dOYoHkY\r\nLyH1TkngfvTJ15HTA27zJm2FM16lXv5FV1MkjlSAatIratCN2I7vIeReU13S\r\nwlgAk33ZQWUSyWBmJjZ9XmYlSjYjYRmcR8NeYqfqlciFu3zhCfDCQHB8e+cc\r\nX5AYKUXFSypEzsH4+XLbB+IDgX/jym8WLQPDytNBmr36qCdBvNWqxDi6kmZC\r\nBq3W/gFFsOOgHTyR+unLXEYjrGJDcgHcUdcTOg+VKv2BIRLHjSHvsG1WhSlH\r\nxedom4msd7BxwbzjCw6+DHtyDOakZ1syq4jmoTi9zLF5JCz7R4n49vTLow0W\r\nIYh8h9xUA0Z+ZOpF2qbdCFTr/+Ol5M6iO4E4gL7gWXRlM88r8txvTnKRLecR\r\nlguNj1tZ8Mki6IiLZKpqQv5Iexarq3yuDoGb5JCy9bsKiy9iKKh+37efYWlW\r\nAdGAcBLBVWTOQ4e96rLar2JM809SyCxvNTI=\r\n=wTfZ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1_1681413619858_0.5037510008903758"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.2":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.2","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.2+3be1cb4d","@latticexyz/schema-type":"2.0.0-alpha.2+3be1cb4d","@latticexyz/services":"2.0.0-alpha.2+3be1cb4d","@latticexyz/solecs":"2.0.0-alpha.2+3be1cb4d","@latticexyz/store":"2.0.0-alpha.2+3be1cb4d","@latticexyz/utils":"2.0.0-alpha.2+3be1cb4d","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"3be1cb4d811f002e7f7b12cd9f4d4eef8aaf28eb","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.2","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-6C4X+nMU3fsNX6mxRQzKJ0lySuggUYd0C55QoRWka6fikJ5S6+02nSKofSUT8bNzaHitVJnH+L/ZMWqUp66ovQ==","shasum":"46ca130c3e37561aed5216f945227392ac62ae02","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.2.tgz","fileCount":58,"unpackedSize":747634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCl61U3PsT1v+FN/aH3Vp0qETbcCPxbychXLdylF5A6MgIhAOViEtT0ZODtGue9lhG+54ymlrsoeanCbo3ywEqaRXmA"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkOGQiACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmolBRAAoT+fIA1kLWcIoYzsjVJWTxFuM8fpQx6NbW47eZlPUF7t46KV\r\nvAPPPlwDct9PlzO+5kq8NqecuZAmNsD4QSLm4zknUSPcOvLhhYh14ZL8hG7P\r\nUasUOMTqATZju6YronHgNMLpUT5RH/U3eT65S50fToQ8h7W5HdBFWfpownTT\r\neBMRAQybhl8I3/BXOZT+dZIWDYB5XCNq0iE4ZRcSndkfpAwD0rpfmJLnoF0S\r\nR/pLk9FhYkjFtG0+ZDJf2HO243qG2MbKC8xFJYcycCMX0ECKy9kSiCC1Qdwl\r\nlY+OYrYi8t1eE/D0FlyJTWC3c2hHTgFamB4zlF3FyaEvk8McnRq7jp+EHWah\r\nq7PK/buJzX/YVKQG3CpWafry77u9mDF2eNLXZnWLsBH8Ivk0a4qywQ1kOh61\r\nNx45QsLe8j7FuioDksQIaqbZc6RADNhdPRzGSm7qofvKOTuQFBUsQpFzzdfH\r\n74G8zDDtghH7YfC7eyUJc87TSEQVfln1uoIdABouKbxOqzx2VwZ883n2I5S7\r\nAn4twK5gZiUkKSHwbUbnCNfB+8/94OwzF5yIRrKCxDsG6lwqkPDuIp39zcJX\r\nlD4WybPiefylwVBEV1FGHHbt8BydOz9LDe/3HMH5T+zBQIz+B2Mg0PqVJUtf\r\nQ/jqhkPazEuCQkGC7/Z87bTf0XZ1eiWuktM=\r\n=DYpC\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.2_1681417250708_0.3329040017813787"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.3":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.3","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.3+5fff6670","@latticexyz/schema-type":"2.0.0-alpha.3+5fff6670","@latticexyz/services":"2.0.0-alpha.3+5fff6670","@latticexyz/solecs":"2.0.0-alpha.3+5fff6670","@latticexyz/store":"2.0.0-alpha.3+5fff6670","@latticexyz/utils":"2.0.0-alpha.3+5fff6670","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"5fff6670e3dc3887a0af75355737e6874717ee25","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.3","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-3pa08oJg9vOdCS72GWgEh0gFFUiZRiliNTk5TD7eywI8+6xp7CulpsFEKkdVQz9YLhWyUumrY7otHXvYSq7OYQ==","shasum":"f0a8651d126ce0412ba7fa656741eab2ddd95ae9","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.3.tgz","fileCount":58,"unpackedSize":747634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDFA707DZSKnXR3jD4YwHrxRdhISyoSq6jvnyuLov+2pgIgCQcgzm4qEqnA1TaYrvAu+/wePNXTBwR+5AbSGE9G9rU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkOH0zACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqL/w/+JXYvEpknAxUobS2AL0bgPsTKfECriDE+kyPUgV2266b84VdS\r\nVx55EPrV43FrgmjsytnhBPE+6P6FY7NZMgHuoRLJO2wUazdtGHTY9E/26F8n\r\nYvTD+aJ+ZO1/CQELpqzONv1+Kfz/jSzBcO8W4DQqRmIV+MwKw5f+/UpbpicL\r\n9z+E5P+LyvorefNeo/UYhSdHZ9+AsybD2Q3ovBMAj4yIME8Zk8pgsc5rYNl3\r\ndpCQVpSgkvYR/vABmMc7N5DxD4A5hGwI1Q3iGWapTKzxNfqX/jeBb82jxszw\r\ndfZAYNtHJm1/LEep5i7ZMIzc4MJQZdQg+UuhNNW1Eu/KEYtLgb+ch5DVAt5v\r\n1aaiOf3KK0mhE/bqNklmV4Z6bHvzTsMmN94fU239REpwSLz9rMKdqUdAKMeb\r\nADv3/8t0m02eG2WozrCr2SbqdcbMGTjd6I88XhDpXqbbx5dEo7P2EHXGW6bl\r\nggZ5PLNgrcHVdtqG4P0F38GFPqbzn9W390EmBvlDPTLYbAw+/RduJHLkOSB9\r\nDBTRxDSdy9Pt8HWn/B4W9v9aGUqcc4K4AmHGmx65nCNjNGD9Qh7wVIPDC+A6\r\nCTY6mwwaVjejm5e6FPccHUg9KiOULJAiay/pp/mOmgLF5DVnYKFNIPrfJaBg\r\nRok3pR/InOTDPuj5goGCBRe0SUu4D2PUXWY=\r\n=2htd\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.3_1681423667094_0.45262741808263796"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.4":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.4","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.4+af04096a","@latticexyz/schema-type":"2.0.0-alpha.4+af04096a","@latticexyz/services":"2.0.0-alpha.4+af04096a","@latticexyz/solecs":"2.0.0-alpha.4+af04096a","@latticexyz/store":"2.0.0-alpha.4+af04096a","@latticexyz/utils":"2.0.0-alpha.4+af04096a","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"af04096a50fc903d2fbdc97980c8894ee06af287","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.4","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-1x/Dd5lNP5/KcojdC3+GI9z2kLJ605u7qe2DlIXdEiurF+kgR+7dva8y6GJ07dDYjaJDLzKPU9Dsz98+C1CkxQ==","shasum":"072f35c61c18a4804c8ec11a6d4e4ba33008b600","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.4.tgz","fileCount":58,"unpackedSize":747634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDeUkD3SC3asg1Qszoz1Qb1pIZAhlUB8YoD1JbjHD+AxgIhAIM7t9nrZd3yLlYEf9y0Mc/nGyawk1JQYx6InuH5kPh7"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkOZ0jACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrgBA/+NftcRKnFpm8uXWnHQStmNcTl6cejeYktWk9C8CmpQJZuRLzd\r\nE1d+NFMZ3DTUNnoPKs+Qz06nl49WIZWehWIfLumwchW7A0tvoKEVz0yVIIyl\r\nuIZQAD1TlE1jmLI2N0P1eHOkZzV93lEN0efjDuI2q7CVk43LIppCEDmhiiE5\r\nYtx4kv2iftBQZ3t5aqtg9YncGApydpYXwo3r1cioqfdaw8ijzCqw/NzySoGI\r\n4Zvi4kCvbRoNMy32+VNQj7mNkzjCt1G/Z6/AbAsu3djrntr5jZNA2eyNJG+4\r\nARltGnKXxlhqq4v37aFE8C4Oj2f4znzACcvKAlBiDFZlAP+rTJbeEiqL7T4I\r\n9OHx7kzOME2yBgBVivYJ8risPTgLipysBPdS2PV8F8nlPtl8w07dd6XugaVX\r\nV+P70AKCP+UBA6N8wWLSxE2oUyZaqaMMNlfZ8WJTg8NgFqp85iB0XfkMKy9i\r\n1kCVKWjsvTQKnc/CLUG7BnRtKY1I9qd5WHpjcdJG0rsY+ob70lq07NggqvW6\r\nBVimoO5ZjFddV9Zhu5CYDAnh3JYoDQMMCq/hIuniCT5BWJ8s3Gqm4nnry5BB\r\n06+S6KrIQCirRQ2KwPxKQBBwQDQpe+SsEvtAg+KRPDMpl1Aip7N+RhH1XngJ\r\n+HJqkpoP/yMrUBZCvoxaPa5yag/rHvIl1RA=\r\n=UBSg\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.4_1681497379146_0.28813569855507937"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.5":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.5","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.5+01167ab3","@latticexyz/schema-type":"2.0.0-alpha.5+01167ab3","@latticexyz/services":"2.0.0-alpha.5+01167ab3","@latticexyz/solecs":"2.0.0-alpha.5+01167ab3","@latticexyz/store":"2.0.0-alpha.5+01167ab3","@latticexyz/utils":"2.0.0-alpha.5+01167ab3","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"01167ab366c9e677fd84161401c07e44066f5f03","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.5","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-yM12DicR0G9fDJFgtvNG9sh3odoln+1EZoGOOHivxwaK2qph6qPfvmCRl1ro3rgY0DNFvO8ubiqt7VZVw6zYag==","shasum":"2ed8d3ae746de134a2eb4db0bab1c5c1e62883db","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.5.tgz","fileCount":58,"unpackedSize":747634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDKsKXdsxvBJqqjcAWH5rPSWTmlQR0EMXcYBY2z5GO4YAIhAKJRSonCR5gdW8eaWSJpwBen+m5yG41JLJuJ5K1I4S8N"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkOb84ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoQoQ/9GqKrMWQD4bLnu3gq4TQ5v/yzDMGRlH1O6xIl8pkU8HJ92yHA\r\ntZd8cpMcFnGkt4D9Jt57KCRayVaz7wYZQFtMU09q/rqDRP6Wz8jG4yojDH+2\r\nmh1+7oHsCdC1pKk+EenfwZeMLFu9JlhbriLKlMNjvBaccL/o5tFXS4f3IAKh\r\nyjlGZQcEc1C68yQrNpEouEYdYk83SQTzM+xs8R8nWfowDZaYzSycpouYZe/E\r\nJDOAS5k6yn3lJExVV/7ce0/UHk/E/MLDz/3pVIRSwJWtR+VpPgXe/idm47vR\r\nM/bcjgNC0+VqPaCpWNjgTH5ng5JzCgOVHRboApdESmIo9SNi7x+42QMrRIU1\r\nWHsau+dfUoIcR4rubtgug6zam9UTw6Tu5Cdo4lCvuemqNyI7tFzvsFkCByd5\r\nCm8DPIg+P0Zmafhm42ObILVAT2qrLUrcUHkaAn3LmdO6pnvF09AE28Q6RjHy\r\nTGhG2rWmTPIlzovG5D4DvehD2sUemW/t71CkffmcG1MUEhNouneLBdk1Lter\r\ne6n+NR5S59MZ6BDM83SH8/xCd2W9vYcq2joNdSuWCfh7gbB1wT5JzOJMetNO\r\nG6RUB3AMwD+O2PKm3wcVUoPzAXVhHCIFncdnRnXwFbTipyo/lolNXyhhQ9ku\r\n4FGqr0m25iH9HXVXZwlm94WJ93AEgZYR4oA=\r\n=sBvh\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.5_1681506104731_0.5946722730383234"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.6":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.6","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.6+d3c59fc3","@latticexyz/schema-type":"2.0.0-alpha.6+d3c59fc3","@latticexyz/services":"2.0.0-alpha.6+d3c59fc3","@latticexyz/solecs":"2.0.0-alpha.6+d3c59fc3","@latticexyz/store":"2.0.0-alpha.6+d3c59fc3","@latticexyz/utils":"2.0.0-alpha.6+d3c59fc3","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"d3c59fc36e402c232845021eb2ffabe535bd2910","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.6","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-3d6c4oDPHtTT6IH9lUDdcFmCb13NTfJ/Dssegbs8327zn870hoEu53Cs/iJ8xEEVYy9MNC2+0OH+cadsQ+pW2w==","shasum":"f27d0fac85c50bfc37655d09237b05ed99074923","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.6.tgz","fileCount":58,"unpackedSize":747634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDN4sxkfKrEJgnFXp++EWhu0YTN/k/f+5nlRLT3NxJUOAiEA9ueoaQ9+PSWiU8xxcViIa4f5oUr6oirArHRHc6YpLYw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPJ2hACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoQHw//Q5Pt+01YLvNqn0uYe0TUUpeIIUo3ukZLjNvDWQPjvm4edKAl\r\ndaU91fj7K1FK6TG4oIhp2wCSZjGQlDEZMPN99ix3cFXPxhLwQ0k2KotTdAee\r\nnklZp+DwRNNI6LkuC7Q4Y7K5baVcACOdKjapNK9HgPYZ872kVdvRuYJspi/R\r\n6JSSZFnRm9ZWv4JQVhdwdLvOz/cJ/N6/XW/sanq/83G9P0xLhW1Rf1Tk8+FN\r\nNleBs4duZMGtP17LRrdo009uTdfNRsjpmMND7sTTW3N6C4LaVhgAlKRtfMNq\r\nCFuN9Ac5NBZTfYJB01uKsGdlQsZR84MgMvSt/b2/rmFRmMKiiHPhAVO+B2jJ\r\n0+c4eYstkIW8aP4SEd14S5A8nz1gwMx7eop7Sc2p+3LZFksrRFwRfLodHOXm\r\n6PFjMJNMh77vnraznZilyg7yk89m/JOWq4wvTJNzni43ay48m6wNMs6oYKQ0\r\nYIvVSkGWRzHbnTn9IFhtK7IoZXo2PGpK0EgmWMdK4CL/DFEEcSJsFApEyzA5\r\nUzo1VMWumuYkrYdNUMX9qYpNugSFmbS+489e2BEeEyZ3sJi20+ZoUQh4JxCy\r\nIJmP+hTwZL2BJ9v3Nj4FyS5//BlZAmeumnPaCbxUkKrKDBfqOF10aL0R3XpX\r\nJix+Uvy7LqLwQQswoxGOiHKy2Nb61PadSFs=\r\n=ilRD\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.6_1681694112956_0.4570972063662535"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.7":{"name":"@latticexyz/network","license":"MIT","version":"2.0.0-alpha.7","source":"src/index.ts","main":"src/index.ts","type":"module","engines":{"node":">=18"},"repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","release":"npm publish --access=public"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.7+766e1dec","@latticexyz/schema-type":"2.0.0-alpha.7+766e1dec","@latticexyz/services":"2.0.0-alpha.7+766e1dec","@latticexyz/solecs":"2.0.0-alpha.7+766e1dec","@latticexyz/store":"2.0.0-alpha.7+766e1dec","@latticexyz/utils":"2.0.0-alpha.7+766e1dec","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"gitHead":"766e1dec7bf74fe114480feae8413dfab12e36f4","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.7","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-2CZDJ5tUnrz9PQiPRJPC9Lp3Ya2/Z7sesLsLYGsd1sgjaHZZY7WyAeiFlgdzc7ikDAgCqKvfq4hz2lANbWuivQ==","shasum":"426f0a5e1ae41387f2d5fae50f74077f182db243","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.7.tgz","fileCount":58,"unpackedSize":747634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICcJvrdCR+DDZUSysNeJd3FM5QvumOOjIv3NIapveQ2mAiAF/4zpvwLgAEUiJuSoOSKdbw2jQhhVVUupDcCc4Qu5uA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPKADACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo4vxAAmPI4BDXLlyB03oSf2qBMS6edx73dzqJaVX2Je3ucPJUHhyud\r\n+Rso9kyxmbvDJ84J1emziC6riDCGRv+WEpjhPdLxI/nwhwgOezuyoMhKl0QX\r\nsDZvza/LoAfDlazvHqS0tRrWhuSmImgElACrmUV7d7xw70SKr5B4ZW2tczSY\r\nc9LhctECs7KX3QZ4GOZDsJMRhqIK5pHyGXieBj9StdbViTfEzdwX57ynbHfa\r\nRkbv249W13BuFZwT+MxfQmc/BV5/LrfNxSNjPNGo6H7uew23VUmUZgssxDV4\r\nSL5ItIlKFPOkXVDgNFql7qk0RKehuVkJ7/aXHHutLktaLS8P/ErLFYddyA09\r\n9YYWhifsUshW+wePxwbYlI50VTUieiNiyfrcKNitlDwmi6W4gqKhZZ+9Qy5Q\r\nBUWXHGnf2NHnM0hpSSiZ/K2lLuZVNOW3RPY5k392WnqzQI7lFBx+lVAq+NbC\r\nTFA7/Rwk278hFrGV1RfOcma9gBOzpdcTdxHM57OShx8+QffqoVm05PIMkSyB\r\n42Q9bqz31fe1SXYVPsMFp9nLZjYj5qYOEzvDUlE2YTpambjg3FG+D+7kLsI3\r\nFRbWlqA+C/YeC3OTMhtzR7bg4a2EEUDy7q51ktxOkPiO6F5RpfcIm2XlFypb\r\n7mmlmW/0A5alGmeh4NnxbXH1hqD5lb8sNE8=\r\n=bugO\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.7_1681694723148_0.3911963727578551"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.8":{"name":"@latticexyz/network","version":"2.0.0-alpha.8","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.8+fbe2c897","@latticexyz/schema-type":"2.0.0-alpha.8+fbe2c897","@latticexyz/services":"2.0.0-alpha.8+fbe2c897","@latticexyz/solecs":"2.0.0-alpha.8+fbe2c897","@latticexyz/store":"2.0.0-alpha.8+fbe2c897","@latticexyz/utils":"2.0.0-alpha.8+fbe2c897","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"fbe2c897aaf2e88c02ce9031c06dae4560c3cf69","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.8","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-kZVYEHDyedRplr9/NItXJ0NxwwxcdsOml7Vkt8A+ANzctRSExEnKYLs4XP1um94FUY8LNt/9cc+DICyB1M8Isg==","shasum":"6468aa93ba81f11dacc0af6b600d9d52481da7b5","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.8.tgz","fileCount":58,"unpackedSize":747634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBwKXXZBhOYXFq/KrMO66qyBkdP0X/evvPu5qLsOJFSIAiBVSR93zMNlk1ocSMR7Ko+aYJPOuLhvGID+xvruWVfyTg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPKfpACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrbxg//V6fKScfp159EHP1yNu8nV6c5X1Xe6ZvkkBqto2PQMtw4vpNi\r\ndSU/VTWSNOBc9Q40nd7PmTNXgds8PzOAORHV+uYOY+BXqPmv3ItJHFZ4Lda0\r\nLv13UDr8MQbMbqCqNvMMWO21KSIph17QtEhqZAuWzKi0eQQaqdUnjjWAhR4F\r\nBgIO2Ka2AKwhcRy6xNX+V1G/CLKGXt7q+OQzI5tjtKUsEBHcgzJcN3oTXWo9\r\nAj60X5yMJYnw73DWtTKrqtw6OWr2kAJH+tIk0Imb7g1ZF3i5CCV3hLe7s8Bx\r\nywjh9Pip3z3W9xc7LRpvUEcL5ZS6SsnqH3xgSlS3NqxC7gmbMAfb4LorrfKa\r\nBUU/BokMiDJ6aTeUlxpyRaS713gXNFBPxJQTkVe6tKmA1nBT/5pqqvbKtr7S\r\n49rzAYh1OzrAREeo0zXzV/MVEFZ+IRyuA072wkagW0ELSq+tSoSRk+qlS05e\r\ndAQ1pRj7bbhZPiFNG1Oh4OCfV47O/BrYnT7KJwv7Bdq9+t235nI58o+l+XgS\r\nRjaaZ9lQg3FJPrbkYSZUYxep2jZ85nwFUl1HxG2BdW7aeg2EPIHxbb6ZhvOh\r\n+EqtP0zq4uT40fnH1O0IIukFG1UBqN2O5WAA/3MkcAaWRjs4f8zJjyLYMRpG\r\nyBFJHBgAnne093zK9+xiaeD3c1QcNh7RUdY=\r\n=cZ8y\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.8_1681696745086_0.13446474377331752"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.9":{"name":"@latticexyz/network","version":"2.0.0-alpha.9","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.9+dc76f2ea","@latticexyz/schema-type":"2.0.0-alpha.9+dc76f2ea","@latticexyz/services":"2.0.0-alpha.9+dc76f2ea","@latticexyz/solecs":"2.0.0-alpha.9+dc76f2ea","@latticexyz/store":"2.0.0-alpha.9+dc76f2ea","@latticexyz/utils":"2.0.0-alpha.9+dc76f2ea","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"dc76f2ea99e9d417ca8b216cea84e1ad8a1782eb","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.9","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-BH5FRkvJVk29WM8e5rr0gTkeESz8ancMuzWYTclKLRBV7avsYwev7rL8D2Qs7jbKK2kMh7CMEJPabdW5iE332w==","shasum":"5e3665870936d49912bdea47e93e821f965a0f67","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.9.tgz","fileCount":58,"unpackedSize":747634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAL2CEWzI/5w7PYtzr7r9y6qaJKR0oDbQ+kMchSa+o+pAiEAgU+W45FudOoaJ60eLxG5jYiNVFTvseLspkouA/Vv0rQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPRr8ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqZ4w//brQyZ9qakWDMdvNnBOfYCE1rYTnMeiL77VT8igXa340VZqXz\r\nMLF4Q5gD+vRACvAFK8OBL2M/m2h0BkoAGRjFaHlxWpl0Ob5aj/Xw9TafRPdx\r\n7/CoJJnrCj/QOnSNURxT8dM6mwDTJa9AT2U65PX2sYXKx2J8BgMpAVrBXpAw\r\n4ldCJt3kLkVB8EmpFFjFDU2tg6G4UZJ2mVB3LXSBdjEnhFfjkDDWpHX6qe//\r\nDi/OvjpI8ODPvENY8kGzFwqRvQV2ocMQIExyHYOHKmNQQayy52lLLDEXpQG5\r\nv1fD4wHhZ2/iLHJCAI2PwUIKFIT6/67L7cieM/0bnAndh4t0JzakuWQEQ3YX\r\nA/gPscQsT4hBZXPtOUUExaK6eDlORHoX6b18cIs8ZXnjMhZZKjTxD3qrXtbz\r\nnz43KrS8K/dEv+BtFR1fD/yZoYQoMrdViBjPklhheoSpuK/gStBF9ZPLCKvF\r\n+OfIKvp+7kVLk56Itd+ac3N1qRnDRDOO88+1D90PEkxCGGfWEOkYZYp7175J\r\niVO2mppXXYYCFV1tr51rJMWgM10+eG1KgPgcwvS9KKMxR+CmXk5Ov7qFZUVs\r\nz5eO02cV5lwF/vxyfZy2Tj/+RfRSd5LCBwJnR3+Qy7utrO0TijtXFjOlNOxH\r\nxqV3BPdeL69vCZUIduwEExdbE+9z9pkT0/Y=\r\n=QBMQ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.9_1681726204119_0.06011623757844031"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.10":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.10","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.10+30ac8842","@latticexyz/schema-type":"2.0.0-alpha.1.10+30ac8842","@latticexyz/services":"2.0.0-alpha.1.10+30ac8842","@latticexyz/solecs":"2.0.0-alpha.1.10+30ac8842","@latticexyz/store":"2.0.0-alpha.1.10+30ac8842","@latticexyz/utils":"2.0.0-alpha.1.10+30ac8842","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"30ac88423e92161b98d31751b0f6cc99ea60be82","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.10","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-CNKaf9FVl1RmwZwW6GAjqKhPTELqx2NeeIo+0MWCX9XdjdhgNpF1LBEDojup1drWfNNKQI5pU7e3weg//6pySw==","shasum":"1f334b677eb7bebb309a9a8ddf0125985ab87ac6","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.10.tgz","fileCount":58,"unpackedSize":747655,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG1dtfMX9HV6iRNuS7nY4F1IEw7A2/tpeQjhOmG0TSn8AiB/3tmHpI+44jZn9vVH4MWjD7K8ZIxJwe0bqgxBKpmumQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPqFXACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpyxg//XmT0S0Kg0jKPYyDCOGdVYKNP7ymjoD5nO0iH9HyczIUWHq1n\r\nQ9n4L8Bi0M5lVfu9MV8RB8URFFzgNlVJH0mEW8DvoFa3taCTJn1WA3tmbtal\r\nsHmT/RGVKQS4aaDLJ+r0nzpExmcpJ49tQA96PCvkmoZsiLIyezDZ3Fv16R+/\r\nx1SJtLkzHyGwG2NGrC2YitmVBZk9rOfL5D8a68r32cIbEOiY9f0aUgCFUn3e\r\niFG7uHW4K4zcWvSECl8L1Di0lF4meH9xqR9hacslbukOyyAOu6AeGizh+jFA\r\ne74CXEupNfpIRsGI/V4k+54DP9TcyR/Nrf0uBUpcEuytMHLumfeB4jX4liPE\r\nX62LDN0Pzquwjl+C7j7x93SI1z6omv6O3xwkijuJKXHo1BQN0ZRT11E/6ehd\r\n7UqLgoWHBRXlTWhzEyL14gjvyjUxOjX6HMLAfzmW0kQfOBhWEUr5SIDQrH4r\r\nmZcZ2fMrdK5gmILuOy/8DnxpaU4ocQ9kUQgRn80acCdfyqKh1QOXX780kCB6\r\nELBV+vXAqG0tkhtsbcLigt8ChCT7mSHI/3tusm4F5s2RTy8UcrnPolknPE4q\r\nyu0umRAuEgdFSojoupcUohzPHS8OT073EyxVCMqwUKCQ4hh3pArwKMCnC5Ux\r\nYk2ZbAM/rt5RxhvZ5AnKm8NbLrrCvosFbAE=\r\n=YCuX\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.10_1681826134904_0.24716710559367927"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.11":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.11","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.11+64776b86","@latticexyz/schema-type":"2.0.0-alpha.1.11+64776b86","@latticexyz/services":"2.0.0-alpha.1.11+64776b86","@latticexyz/solecs":"2.0.0-alpha.1.11+64776b86","@latticexyz/store":"2.0.0-alpha.1.11+64776b86","@latticexyz/utils":"2.0.0-alpha.1.11+64776b86","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"64776b8691c005fa8a38bfad7a7113c5829039b2","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.11","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-0N98JCS+3QgkQBNlIhDJu+PVYVLjCbbowyQyfGAuKBZeHxm/V9IxMjyZAZ+C56JBvkOsX7hWVC542OTTB3dyOw==","shasum":"1f0eb541e9283bb55abd5bc4d121e51f1f78eac7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.11.tgz","fileCount":58,"unpackedSize":747655,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHEE1wk97bXjSbSL9MQ9TmgOfsztCdmq3Kwi6s+nZqoMAiB/fW+XBpnYMbEfDBjVFrqCFpyYA62WmhRKIBFLyHx4kg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPqLPACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr6MA/+KcK80Yx/RLwzkd+EY1TkAmvLFXa6h4sM6G/hlr3lYrlYZ7EG\r\nVGr6WWxPyFK5buStspQqHSbVD0Zp5aRuZ3AhZxeurrfQxpcVr6myGPRWM9Ga\r\n2u7bYqaTujhZX4b78xMV09b2y4WUUxjL2WyUSdh5ZpOk2V6SqtkmvCbwF+bF\r\nib0OhhIao0JPB0A773oOgFVtTs28ls3q36DziEMaWXnm7afzcWm5Px5UVteC\r\n06QQrHwVMmhi9sosWOdgNcR4+qg0bhgo6UVmRTAddP4FMdj731y10eymbCZu\r\ngqgbLKxHr743NwRkR1/di3FpsxJcjedTzn8JfMccHvEThnY6lxTc5sg4qI33\r\ng49dE2lqVChRAbDhflihNPcx0oAtuIA5YopjYbFz5Po2x4LsEx/+Dqa0qRMo\r\nL/CZQab1VmsMxO0B2Q5PsiKl5Jgo9dTFsYCrn9vGu1su9Nwa/IP1irN8CWrZ\r\nQspJCT4C1e3nqIE6IKjs4gblbMF/XeVU8ItqOpKQAwBWS6ET1TDQX7snoaSS\r\nFVJlyeKJqXYL5D5mvAlA5xtAB1yaK39o/5GZwPOM54+cDsX2PkkhUMTSMWsw\r\n5Ideqx3x+6eCg4nkYitNmlpyzcmR+sYf96FjcIvZcDWa3qOvrdqEDR8gNepX\r\nj9GqpATjxonMMyZF4PBLre+rmYzdMeJtLJg=\r\n=atXg\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.11_1681826511132_0.3870219672718951"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.12":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.12","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.12+711df0ae","@latticexyz/schema-type":"2.0.0-alpha.1.12+711df0ae","@latticexyz/services":"2.0.0-alpha.1.12+711df0ae","@latticexyz/solecs":"2.0.0-alpha.1.12+711df0ae","@latticexyz/store":"2.0.0-alpha.1.12+711df0ae","@latticexyz/utils":"2.0.0-alpha.1.12+711df0ae","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"711df0aecdc2c9a1ea8a743eeb4fd0b63c63b010","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.12","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-9GCuRaDymtaILDqeu3pc/YAznx3OGwRrni5eHqexDN06x1IzJGUReKgioR4tE3neNFclalPb/uRbe6zyUQopvw==","shasum":"7a7995dfe872864c2cf175e74b0a5b8aba658c4c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.12.tgz","fileCount":58,"unpackedSize":747618,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCB/uNw/GxtHbSAfgsIb9XeDMHiTNZ7Uw60/VIV+uTQJQIhAPDwB9R+CuqVUzRT6Av2rw62Mrbs6Ihh3M+hg/qm3VaV"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPtT+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq01BAAj9T7+WE/FyYSCs0QV5m/x9vLaoAIXCiov028bqGi5FHxB9b9\r\nUc8MjvlK5WibldW8EhO1kj67BGw8fArgZWYUhaG4KgEv+K+Vs6fQSpfjlCaZ\r\n3NSvw/KEkx53VySID1QNht8CsT+xaWPLRb2pf8FAhwTwxoX6DffoGkysTalM\r\n75CfI9SSllzhVm6KpRFcON2EIyPEGZrZAVLKqBq4ZOOtbeGyzuencT2CPtRv\r\n4aqn6GsBTQVj8UDnrQZLCpY4K55QUPD8Q/e6aFfMhwdMWGzgRuH2HSIXciz6\r\nTCrmWQF1XhrSITZM0aKLNgc9shq1+zX4NYaftoUqx0Yp5rQeBt64JT16CeWY\r\nEhCXV1u9Mm2TzC5bqz1TfgWouRRFjx9G5sjQZtvi9QE7M+sCkpaNze4Zhn9n\r\nM/IMUjn65ap0hL6TPaD9AXe/4Ztyz0o4k+ZP+SP9HiY8Jd5psCDh89git2Jt\r\nmHAuGzNlPnq2avmEAGaWZGDrsD+zdwht4xI2e0+RMvmE+e9aIXb93iHvB8f0\r\nJ/JycMFtHjTLaRIhhAa4RxEHpinlxiHRRDr/2LA5ZqFLA07tqq4LEVfMaM9Q\r\nFKRS+e8NhJkNrMTU4JTHUWfq7zExXQgsWqOkI/hsKioDHwssJkSU2P7zBnsI\r\njgm2ufzSGfWJ4gUG8VTQadT5DqZqNdb2ui8=\r\n=s7Ec\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.12_1681839358390_0.7762085190717214"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.13":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.13","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.13+43772dae","@latticexyz/schema-type":"2.0.0-alpha.1.13+43772dae","@latticexyz/services":"2.0.0-alpha.1.13+43772dae","@latticexyz/solecs":"2.0.0-alpha.1.13+43772dae","@latticexyz/store":"2.0.0-alpha.1.13+43772dae","@latticexyz/utils":"2.0.0-alpha.1.13+43772dae","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"43772dae011a438710dc513b786fda0431a5951e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.13","_nodeVersion":"18.15.0","_npmVersion":"lerna/6.6.1/node@v18.15.0+x64 (linux)","dist":{"integrity":"sha512-6NQm3ZCp0hKkdAFNSf19rQ0wBFLfjxKOjEqVlH/4i0fuNLpwq1a/XcffBmkJd4r55XdmYYMeOi6mr+X5+Ur85g==","shasum":"49abd5dc9abb0e00b34237733d9968736a5bfcf8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.13.tgz","fileCount":58,"unpackedSize":747618,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQChzu/S4ETR3Q9Z0RiSdklpluYmufqp5j2VLTqz2KGVgwIgR6TFvmIVwUmnQL6G77GBT0Wl5rclGAugza5TbQvJFAk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkP6ANACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq21A//awcOub8XAyYMm+qakGWLkEv7xfEEZg0IeLwz4pSG09/Pl2tT\r\nRiabbhF30n2eNVXcs490ywZshnqVrHFoSfbvJVpqiuNSzLCaSuHvszsR5imk\r\nzczxpcdHUtdkcnbl78TbCJw1CVPpTgv1fc+3hPdeATOW5jlmTsFCbUP4LdTe\r\nqNd7zMWN2hRgk3+hSfoUCr2ddSFy6GERWREveabakqEt0vCPimsXF8WHBh1H\r\nrMo82G0P+9LtqUAbbeYZUDh/W3EnftOrIymJu8rlfRVzWNPhUVvN6t7A2sUc\r\nF/lhAILWM+4ZaW3GYwPm8UMsxetv49xGLw6ZiuzDtp9NEOgCHepD4x0cpoQJ\r\n8PIPdBTgKAaAYI4VHBxVFMNJOg9DQ4iRtBgP9XtuMQ6X0Y2neHYEVa9UYB8K\r\nwGwQqicGMqm/fOb9hufekI5dNbbF7jpuA/Et3ZURUKmM1zKZbnGsB/3vdoSW\r\nIa9Je+5zO5hiB0WaV0orE59EUASEjyOmfldCG/hFF8plUR2VC4TDvhO6NyGf\r\nZo7HlxZGWJ2EefIYszryuyMf4xLU86StuY2Qb898xSXkCWPDNfODGhEMQEDo\r\nOUNS8jKyosTG8rUfTQPSfuepmsHg/Ogik+gYtlEqNNGbrIJBN8a+/SIKcPzo\r\n7XE/jq2CqgkdaY/pbwr2+o/DKtbCzIpNIPc=\r\n=Jzfv\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.13_1681891341509_0.5079195319044556"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.21":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.21","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.21+4ad66187","@latticexyz/schema-type":"2.0.0-alpha.1.21+4ad66187","@latticexyz/services":"2.0.0-alpha.1.21+4ad66187","@latticexyz/solecs":"2.0.0-alpha.1.21+4ad66187","@latticexyz/store":"2.0.0-alpha.1.21+4ad66187","@latticexyz/utils":"2.0.0-alpha.1.21+4ad66187","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"4ad661878bcf916a9ab7fd4d72d051b372af74c5","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.21","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-3mrg+phNv9oOSJQICTNucoXpauY2go95yOt5WA8Ghxy5olWpKuAO3xWYyyAoTp7/Ild6tb0vhdw9JMaECwa/uQ==","shasum":"3214207e46b04b7b7b3b6369977b8d409be6cd87","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.21.tgz","fileCount":58,"unpackedSize":747717,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHtO5VA/T92p9V8Hk7oc9v6N7DlHkNTDaecjhMZNKw4XAiB2YmuNLzHoDdq1Wbyf2AdEo/wNxLHSVaRgwM4ZbMXRzQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkQsapACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqqLhAAkoLVkHorjnYpX8cj+gKakBVbqAi3AQN7E1laUphAT7TsBGRG\r\ntOncr5BCnV76Mmd3AxfYAH0V9m5wAz5B7uwnjBOcJn3jZI5AYphICmr6A5X1\r\n4gQ3mXsPFXEjX6ZnIkXZNdPmBOnl2QZnaB+3utgLjFUG3gqjZeble2leajjc\r\n+yf8u4Ej8jzWn1l72VQvfPjYWfhSZ2AeD0oIqLJEuL3ic8U0sUZDOpJUtRr9\r\nqc/hYzt2efMX+yh8f8keeQRIxgUZEeLPE7glOUzoRFzRFLD4hgdr4c59qPj+\r\nOzM83IO6MfgRT0w3/SNAcnAPJbVOTxHGMSyN9gM3QunomlbeJIOKUfuDWncC\r\n8wq8IzrGKCGuZTcEAQHRpFHkyONdh+vHdsRIZfQbPvZkrDpltalhre+ZhJ8P\r\nMKbSXA5hPyzt/9TzxV2cautzT35SIki5SwLLFN60YD+JM6TDESGMu4dfq18U\r\nAIsIpn/FstAF52alaVj+UBxaT0L+7ghRTg+sRh9/Mn/n4OvJn+vv+Z3ovMc2\r\neFv708NTAd3LXpLOaf/y1HQ9wkLZc+v9IO8qSeNB4+iVCyWDNitHgdEHVbJ3\r\nTkwl6TPOkY0L/fkfRVaHGPzKOwDFLcvnQlAzaQdAYBdfVA83YHqltf/ukhto\r\niuPt61d8lFZm9yWRx7gOke42FMg+GinZP0A=\r\n=rTEL\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.21_1682097833255_0.010101547119309995"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.22":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.22","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.22+2f59f2a8","@latticexyz/schema-type":"2.0.0-alpha.1.22+2f59f2a8","@latticexyz/services":"2.0.0-alpha.1.22+2f59f2a8","@latticexyz/solecs":"2.0.0-alpha.1.22+2f59f2a8","@latticexyz/store":"2.0.0-alpha.1.22+2f59f2a8","@latticexyz/utils":"2.0.0-alpha.1.22+2f59f2a8","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"2f59f2a8c127fef3154e28d672f53ec96939a912","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.22","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-8WIHbYddlEsqEriAZh7UiwYxdf55DUsc6c2jODOUJhPafDqYm5F5ezhFGB43g5TJnwRq2zs10aNRFs+x/DOtMw==","shasum":"82adde005e286ec2b60904b251cc070e9b8d3d48","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.22.tgz","fileCount":58,"unpackedSize":747717,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG1/zD9Szbyv4KsrkKQI87mF3Yzt8iyeFNFHqsmimfj6AiBPY2fCu5fvOHOTqwJyQeCQrLiqXGk7TPQGYxzhkVw6Eg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkQsodACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmplbRAAn/P7tSypqK3aVAJJmZ3JTEOZN1Mc3QrJswlakXTOIqxP3fGJ\r\n+0blW5EX0kGY1nGJaT8hFbmstDtRRgukx/V7EkjgjybkOLGMBvjPpVCAQhJ2\r\nAlUtHnfXU4lb99FOlzqlRSWyQrB6hJplYgJE5uub1Xz8WUxHl8mzpAAPKfjD\r\n1RvuAs5GtnhvQltmYjgfyIUE79jVpi8bjjwGU3dB+/BG5dcI906YASSnp29Y\r\nVEgWj1nsvIwfJu8s0rIZIyCUkCP9OAzN75REf1O99PBfUw2CXbOvjqErnQr6\r\n1a+QbUUSCDu1nNP4WAfPdUEDC2w04+Pg9149DIcrxttJE09EqsJ0e/uLJQqw\r\nIXwAki1Z5vMb29Ixm9dnDBo/I5r2Lw6zfoqImGVDQKsfzKn2Cgl6XLTeM40m\r\nOL5CQ1VNsFo1TY9fg/QVCUKVlikaPgN76ZHJYPZ1IB29G81ezZzDMu6zHYrQ\r\n0QA/noA8LwpEy7yBY/Fd0BVUwDHjQkxrERupU7G+JHoSe6DPZpLeAWP4QkEh\r\n23q0Fr0d1iPUnI5c+EGszSMZvLN/ur7NSGPZTlXZljoAuK2P+Aqy+b+Aj5ba\r\n2ZTkwHHVFz8BRn15dYhKgANaNji+W2Ja2J6llWXC2i0PllQk7C5Y2H8K0wxb\r\nrHyD+BEbu9QWflGpDkfwbYZTlecLI3ugiF4=\r\n=oeX+\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.22_1682098716779_0.37054081597116983"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.43.0":{"name":"@latticexyz/network","license":"MIT","version":"1.43.0","source":"src/index.ts","main":"src/index.ts","engines":{"node":">=16"},"type":"module","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"scripts":{"prepare":"yarn build","lint":"eslint . --ext .ts","test":"tsc && jest --forceExit","link":"yarn link","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\; && echo 'label: API' > API/index.yml","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","build":"(rimraf dist && rimraf ./.parcel-cache && yarn prepack && parcel build && tsc --emitDeclarationOnly || true) && yarn postpack","release":"npm publish || echo 'version already published'"},"dependencies":{"debug":"^4.3.4"},"peerDependencies":{"@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.36.1","@latticexyz/services":"^1.36.1","@latticexyz/solecs":"^1.36.1","@latticexyz/utils":"^1.36.1","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"devDependencies":{"@ethersproject/abi":"^5.6.0","@ethersproject/providers":"^5.6.1","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"^1.43.0","@latticexyz/services":"^1.43.0","@latticexyz/solecs":"^1.43.0","@latticexyz/utils":"^1.43.0","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.1","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"^2.7.0","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","ts-node":"^10.7.0","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.6.2"},"gitHead":"752860500ad08d3fb59383f59574385a0b9f8f03","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@1.43.0","_nodeVersion":"18.15.0","_npmVersion":"lerna/4.0.0/node@v18.15.0+arm64 (darwin)","dist":{"integrity":"sha512-ygtgYYELTc1ZvtRSvgmOGfLIzybxKJf/X/7eqaly2+RUqyRTuWXy9ueQoJ+fJhU+nuGjzOzdIl2YBg1YN+Xf7w==","shasum":"aceb12268f6d011580be1d376901ea8931aaed31","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-1.43.0.tgz","fileCount":39,"unpackedSize":558213,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH+UVZKOPdMNWE4rkqsIbpfIOKlDridlr3mBA31Al6ZHAiBdnqEqKe0Q5lbD1GA4CkvgJKZyQ+VZldrTsGTTtYRXDg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkRYG8ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrd+A/9GOV3M4/QuSIu2xGDzSSP104gyz4PqAxf6DxX1qCjtjNIL22F\r\nuQ0k5CA89GZcIcU3w+CqpEoNXkPvh3B3x9X4PRmA9CmFh9nZq3W1sDSWBWKZ\r\nbKLZxbU3jgjS9/7AWjk5dF9L6nQoTv6gmNKq6U9SzpbWCKuJm2ZWl8gQaxkP\r\nLKxBbqCh0/qwrE7VrCGne4AvEDRuKcyY8m18S+NoM50Zb2tHK+YXdKF/t+5i\r\nyJRq5ApphRgMpEpfQlAgRjocK3luu7PaF9OwJLzpQDyquY6geVTxpemzyPBD\r\nx38Ro9VEMGfXA5RRyyjOaQloF3PNtGYUAB8WrK24rKp8+a0tpqXoT1zTHhV/\r\nuu8wDX16uT+dz67N3U3aW2OQqblvO+iH1iEVse3pOeDvXz0fTSBOmPYTdoT5\r\n7vuLo9JGM+0pl9vlHvi/IeLKOPRIcHVv1qusbM6zCpR4597Tn/FpR60B8vpa\r\nGR7UHIPZQAv0otYn19Gx/C+JB7jXqM5YewKQrYPLvZ39z5y7uNeaDPB3iWM0\r\neeCNWbxzdoTHCGQS5r3MS3TB9MCiyvuWWxqY5JlD55G63pJFiCStgFlk4TaQ\r\nFG5TAZfiIv8Sm5mK2VxpVvvBOyIDqo635+WlewRsfK51xHqw9qZp8vn0cdHN\r\nbJUw8duntQu8p3zy4tQvYOqaI0rfWopy6AY=\r\n=mPUk\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_1.43.0_1682276796123_0.6744276195264869"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.23":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.23","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"(rimraf dist && rimraf ./.parcel-cache && pnpm prepack && parcel build && tsc --emitDeclarationOnly || true) && pnpm postpack","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.23+9fca0c94","@latticexyz/schema-type":"2.0.0-alpha.1.23+9fca0c94","@latticexyz/services":"2.0.0-alpha.1.23+9fca0c94","@latticexyz/solecs":"2.0.0-alpha.1.23+9fca0c94","@latticexyz/store":"2.0.0-alpha.1.23+9fca0c94","@latticexyz/utils":"2.0.0-alpha.1.23+9fca0c94","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"9fca0c9432f2690c0bae39f5fc0818a8e1d22554","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.23","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-v/CRb+SNm2fANtTYOLPxVNxgUk8CmmlepJ9AeDnTJl6lCTfx8IHPxjaW5UrOaaTTExhxDrlSFFG7Ye+Q8HN57w==","shasum":"8eff8e58272eaf8f1decd14a3609fd8ae35c00cc","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.23.tgz","fileCount":58,"unpackedSize":746794,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCyFjr357zE3K2vctDw5NruW3K69dnl5q4RwLdMR8QrjwIhAI3YSG+85k1gX1ya8tq6nViviV2Cfbzytt3YbOHfmRuJ"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkRsJmACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrqGhAAhMtdF80zPGOKXA7yf0nh2HNYDmK9JAFNSkLLKMcK5uJ4wb0U\r\njpQiF+6U6Z2acIFCVFdc1zaLVdVyZKhyFaZ7DNRLvmwEXkybYUyQRvFywxZ0\r\nOSpLGEogB5z3pwwrhaBfUu4nfByJOuEpdCIkvIyce0tpEirCAoDJYNwUbtGM\r\nle/txnUycS4Kil2LczkujKr2Ix11u6OFqocgQU7AZUas/HAjfU2uzUc+7bwr\r\n3sD1LQfEHGZR6o2Xp/RXjzTczc4Zp/JWcKPSOOwez9O8YrBhNYpEgM4CxilV\r\nAawkqE1FL6Vqh8lXtCVfTkPIF12Lit9CdCVoMG84ZTmSVTM8aDot9Bt2mJ6+\r\neMrr1vVaGUNIAEXwqDZboT3gVOXrYcLn1dMrGuEaZCI6sUcrN7OWL8HHOvQM\r\np/nFCfl5X0DVjDonHRgZlvDjpXdz8czChxvQ23EvfFMJz3mPvVrZdVqACnqo\r\nFhrQDhFGyFAx+u33n2cb0ETYaR9YlX14WbPBCYjlqF/GXBMBqo57T6hPAZk3\r\nhw8DWZwpowe9YjFtjGYAJxVFtXes2FN0xW5H6OlkFB+CH70eBZHX09qqBwuF\r\nXsbIky7T+M339HpfFcDT/rEcbjibkYD7qjF2eOps50JiEpn8C3r+nV7kZKIK\r\nEOBkWFToMbr9uds4ls/ZZ830GGyW/5jAftQ=\r\n=k7av\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.23_1682358886444_0.09348618575932321"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.26":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.26","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"pnpm run prepack && (parcel build || true) && pnpm run postpack && tsc --emitDeclarationOnly","clean":"pnpm run clean:js","clean:js":"rimraf dist","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.26+1e3c134c","@latticexyz/schema-type":"2.0.0-alpha.1.26+1e3c134c","@latticexyz/services":"2.0.0-alpha.1.26+1e3c134c","@latticexyz/solecs":"2.0.0-alpha.1.26+1e3c134c","@latticexyz/store":"2.0.0-alpha.1.26+1e3c134c","@latticexyz/utils":"2.0.0-alpha.1.26+1e3c134c","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^17.0.21","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^27.5.1","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^27.1.3","tslib":"^2.3.1","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.5.0","nice-grpc-web":"^2.0.0","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"1e3c134cc53a137ae37d7f29c51452ba9010f60d","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.sol/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.26","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-fLmTtEFMtfzYYDwJ5VQ0rrSMs6NXb7F1B8LdV0Oa8X/9yLSqVvx9s6FMXgaSbWtB3omJuGEt89OYr1UYyEGirw==","shasum":"a2641a1d14da060520eaaa0a750c7f0c82593cd9","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.26.tgz","fileCount":58,"unpackedSize":747029,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCGN9RiiicQqvdnOYAJhfyLovatG5/4oy+rKGXsT+juvgIgdJtw0z+zOal459w2iyXnaIxu27ydQLnKCDzQVrcBHbo="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkRu5iACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpXuA/8CJHJsUuGEPCOMVqapg2Ch8J82+txIx7aKRfPWkZ+BhPwDrPY\r\nFHtbVHnIXQJKwgaJe5g7O436RL544Siu2yq/+H+kPGf1Ij1zwQFHtJk01rWN\r\nps0ucy0q0dJAprR2Yf6Hh0U9Dt9EmwMxd3s+U/9nH2DWzj1Z3WkCwXwhmtWH\r\nfSSc367PXx9HtYtGoPMePQ81PbnR80+2kF4rBVQE+MELXp2Y/nO+eCyHm2TF\r\nEuv7dI81U6KZtjovcbyNbPDNB9w8o1ygFTNvHHjkXIh6+3rAAdN12OXBpvEx\r\nCV0EMdLO3oABVynvEHiwWtU4XbNuwejK3Ddf+UYyyCMwL5rRXCYwqdfQhzo2\r\n60YYrxUam+kEIwED7vgGAdofjsWhjSOGNULbYVp9hYoDZBloZhGKt0YFIbLZ\r\nUG3LTnA9/4t00ko1Yuc1mXIh2wRF4+KtCJQ2Q5ghLT5SRE+p2mMiBR+Z9VjC\r\nLVmAoOyjjSaginOKScfrCbWilUj+Rf1pO82qdO4SDbeT+KpnTx9Ic1UqfOeu\r\ncgU0TIKy1d5ZfODy1TD0apApmC/z5zBVZAjNLVXpsg9tgfS5J5c0Q3auGcXU\r\n6HljoQvPfblB8T4j5DsytzHzlUPC6yY6gXUSib2Uc3UqVIrKLqKjkoKongi3\r\nz5Ofh7zC4fKueo3W/ig5g1HW2VETVS9p+wk=\r\n=MtK8\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.26_1682370146623_0.7024825356415687"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.27":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.27","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"pnpm run prepack && (parcel build || true) && pnpm run postpack && tsc --emitDeclarationOnly","clean":"pnpm run clean:js","clean:js":"rimraf dist","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.27+7eaf3d0c","@latticexyz/schema-type":"2.0.0-alpha.1.27+7eaf3d0c","@latticexyz/services":"2.0.0-alpha.1.27+7eaf3d0c","@latticexyz/solecs":"2.0.0-alpha.1.27+7eaf3d0c","@latticexyz/store":"2.0.0-alpha.1.27+7eaf3d0c","@latticexyz/utils":"2.0.0-alpha.1.27+7eaf3d0c","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"7eaf3d0c4fa355297a9b385a5705905f3a696227","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.sol/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.27","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-nCYKBsVpfoVy2HULdxvGiTnUnFq5Sz2tiGW3Hh1vIqKxYjdXUX3KaihclASqBd6diyp4sM5pHzVOdAxpmzKm4Q==","shasum":"12184cfe023910affb3b31c6c7a23ff7189a6436","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.27.tgz","fileCount":58,"unpackedSize":747071,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAMgZcclWgNzq4H3WYbHXYSQscwpmRFnlXYumIuix9PKAiBiOc3YDgjNlvF+MnKjTyjV59JjVTBJmTkhOlXwqJ7lrA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkRvKGACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr/GQ/+MZrpvWawQDzsotgF4kYqRSKhjiq0BgeNCCHmTPH05YTGZ0Pw\r\nC0Mmo+aFJ20xDHWZEUURfBvT4xnOXrUUnaaIbrdlz+UkhiIOtwfLs39LuqqX\r\nqZrJUewrS7uwptR61Qp5xFcXzYJx8+u0xQeLp4j0Y0/TOxWHzuvgtLvk/d/z\r\nGMY/OIfLorfHi8SQa/ZATiy7yHDV92ITv2WgqffkFjBEaU8AwNDs+TqEKk/j\r\n+ftJCgWCAYNVYHOkzvpDsUO9g2FJf18/a6vCHb0CgggnJ7EvuSOh5DWWVL8Q\r\n+kwp9amKbI79+QXVvrJq+R1Z7eHrMdYOI8NAx3g8IHAfCHIAkzj//BrgBHif\r\n4RG1KrIDTO9VIBuaf9MKds/uqvXMazadoxhvZN7gJr6DA/W4uMbpgFTvzQsu\r\nmlPhjxo/ZEtH4X5n+9Z7tiIemWv1c4vLkt7/rX5x566iuz5f5K2rn40gA/qy\r\nZ5HGSDoLRIBQEQjBOWPL1yCj7tf5nvzE2mbLj7t8WHgWmnXmBnXWdHGCG7Pa\r\ng3vFDhNxD7T20mxdJdpj61w2OBeKUYtPF2iQJR7GiJuXTrtpS2nC7AGSbmbg\r\ngM73xZJFyaxOzxHzdY21ke02jT2TPMZ6KpR3tjUCiZEdc7MVo8n5/oGUgrNn\r\ng3gPutn9xhXnP4gtcX1SHyoI34YIG1Lf/lI=\r\n=YQJ0\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.27_1682371206717_0.5408151546553914"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.28":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.28","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"pnpm run prepack && (parcel build || true) && pnpm run postpack && tsc --emitDeclarationOnly","clean":"pnpm run clean:js","clean:js":"rimraf dist","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.28+b94a4c68","@latticexyz/schema-type":"2.0.0-alpha.1.28+b94a4c68","@latticexyz/services":"2.0.0-alpha.1.28+b94a4c68","@latticexyz/solecs":"2.0.0-alpha.1.28+b94a4c68","@latticexyz/store":"2.0.0-alpha.1.28+b94a4c68","@latticexyz/utils":"2.0.0-alpha.1.28+b94a4c68","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"b94a4c683f2784d00b4b4469234e55bef2efc9c4","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.sol/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.28","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-7sEdP2aL07V46cPsDh5aNuL1EfWwHQP7AU+oe0bTEI7FylhP+k5Q6uvEZacDq8/xb6DmcMRbUQM5BvrkBEY0uw==","shasum":"c02ef5b33a7aba9b7b418bcd69d29b929b4a05f3","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.28.tgz","fileCount":58,"unpackedSize":747071,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC9bDpS6z1Q27Dh42YzUmlIX56r9L1iugSbzG6JLTARvgIhAMQmp2FgPDT9v+4i+F+3/FTLsqPI5eNoKxmry2trBT69"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkRv1/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqwyhAAmgCYQBwwMyuuPHiY+yzaX9CEBVjyWI0rMSVPXL92ifDLj0JF\r\nrs/CRqGkXmVqDZ6hM48234KROj2cNNMokmbSNa17/nq45d+Bk5exlnWETuIf\r\nwdf//FQyF8EyvXU+W1yPL+c9z7hbUA4WpZdyi77m7hljFdx5Tb+ITv7QR8LG\r\nqKiBvC3ZYiHqxP80EGH1WT6Y7hHplKdpVGeirPk2vauyVMRSfur58APiCdDR\r\no45BZXUWI/HowLpjlDwrFZNxyB7Wlw0BwqIeNcUBuOQStJk+nvwxe6RSFkdk\r\nuS11Ym4efkYX1hwAAHX3jrlzzZ+szJoBumfEJpHMTs2HqyERTkN1A3grsg6s\r\napmq7HlZwey5+5r6hNOupyxgx/i2CdePIq69MS+270Lu50Jv9vjxVemtK0zZ\r\n4QF9bMTwye/8wT3wwCGLRGzpBmFDwGJIH8ut8m9cn5d180xFZO0wtIF1aU78\r\nTp84a//70bDee8NZjLJPoCYT1nxOqd70rgY2U8SV765gxOQnFbfUHwYTzYyz\r\nMP6aMmYnF3cYIJp2j0/+nR2v3FkQ7xk43kfFvqGyWTz71MTGfY88US/LSoC5\r\nx4h1y0JY4UyfJGQPiPALQptclrN2oPml1iO0oJPIU0yv9ZQk+dpG1r4wgo7F\r\nJZoGDA+bkG7CKGaNB/6zQOT6HlcpJhv8TYU=\r\n=8l/L\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.28_1682374015052_0.4313216043105863"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.29":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.29","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"pnpm run prepack && (parcel build || true) && pnpm run postpack && tsc --emitDeclarationOnly","clean":"pnpm run clean:js","clean:js":"rimraf dist","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.29+fd08d805","@latticexyz/schema-type":"2.0.0-alpha.1.29+fd08d805","@latticexyz/services":"2.0.0-alpha.1.29+fd08d805","@latticexyz/solecs":"2.0.0-alpha.1.29+fd08d805","@latticexyz/store":"2.0.0-alpha.1.29+fd08d805","@latticexyz/utils":"2.0.0-alpha.1.29+fd08d805","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"fd08d80511edfd891b63c132d1ee7d9c698348f3","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.sol/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.29","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-UJh76labvH3pA6j3F5bpgaG7i3eNo2ZKeqd5/O2rD/VngwQtEpFG7OIu3iMMLl8q16OAyLQtRxz+fCgGEA05/Q==","shasum":"59e41afa2eea7304c38f27201086dbf90183b6ad","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.29.tgz","fileCount":58,"unpackedSize":747071,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDSgbvz5+UD7rNlYghD3FN65aUj4PDD/sGoz+5I6O5G6QIhANzlH1grhNDamaMInkQryngwi0jOKj79LKaTytw2GfOK"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSBSwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp2og/+Olz4wEHlzXy8qD1Y9kfVxXWMVnm7I/3K9JTJt5piv+yYX/IA\r\nC1BX58EUqmPiWb1Yh4pAgei8+P+XVwZt/zOS1lHufpj2+Td2pPrBNIrHn7Y8\r\nw3asPZrxqWjlDpXPVs3rTtskDyp6j3oB8Fc6AJUQm9PgU72xwjTeRFHIFhGt\r\nsSBgRONGlB/mW4bRsYW5gyvWiCPSGRo+Xg43+EkdIHTqaDWdpVrcb2PpnVhC\r\nvCb1Yw9GqDS2UcWbgup86MyA9WonQEzXax0+2hS+NMn61jExo0rHoWj+TG7o\r\nSxI9sicFB/QJKjU7C4ws4ezFpCUfd/TdDSUxEpY4ppQcDXszZYHn5fr35ezo\r\np6PneoRwLQltrnlmlh69Cn97CZlg7Tt0B1pyqfcVNpYfaSYPkSx+vrnWb+UN\r\njmGjotNADIN6Ny5cOJ/GvFKYwqaLORLdjLro6bWFHK6eLTyvK1wi7M/jPW5T\r\n05FcVTEjvH4jpwxxktfpyuOt2jodLlsB6L/7CVpH0o7flF2s05Ku+3jy7d7F\r\ni9om7MScQWk7v/hzt5T9FEpT/T3zPwCaCZdGb0PgCI1JF0pYzQocmEdjaKlr\r\nCtGZflDchjM+wV5kcM9BmyYOFXmlTzHtjDXXGbgfsuY+rbjj9lgl127BObZR\r\ntBuIsXrRBddOJvlMv6Pkckx1ck60zPKrUGQ=\r\n=b9A3\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.29_1682445487903_0.060670844169324445"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.30":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.30","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"pnpm run prepack && (parcel build || true) && pnpm run postpack && tsc --emitDeclarationOnly","clean":"pnpm run clean:js","clean:js":"rimraf dist .parcel-cache","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.30+09b80e62","@latticexyz/schema-type":"2.0.0-alpha.1.30+09b80e62","@latticexyz/services":"2.0.0-alpha.1.30+09b80e62","@latticexyz/solecs":"2.0.0-alpha.1.30+09b80e62","@latticexyz/store":"2.0.0-alpha.1.30+09b80e62","@latticexyz/utils":"2.0.0-alpha.1.30+09b80e62","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"09b80e62eba2e6066062e397615158b674d931d9","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.sol/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.30","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-g9PrSLBmBTL0ehjuLKaTU5mEDapxTFKGJViH0ZT5DRLCk3HOe8VTv3etC1HkntJR9i8m0WqTSrKr9rsV/s1/KA==","shasum":"84d5b888aa309761419cc6bd5b1125ed147644ad","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.30.tgz","fileCount":58,"unpackedSize":747085,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDknRqU2FwJaqHtoIrnF4waUXKYsNJGpLAcqM2O7DF6aAIhALeflXS/4HwvjeUfH/NZMGKsiFfz/kq5CbskkpZL19jc"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSDO5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrNYA//bro7YyQu4ticFvHKRUu79+2y5vzqb/CxiLQt6bpgqVl8y8zt\r\nf+Aw+kBbq9/6OwqbDTHj8PlngbGeEmf4owTV4tGcdWBUtnDbVP8UsDebX0YU\r\nQWI7o+IpYZwoGAgiyx0/mCjEVdSO8XrEkIkTQ5R3tDsvEh6rBI2IFATe+SKC\r\nNudu06MbYkk+NMA0bNQ8Gr9u3t15QhL/mdkjvdNP7QRdBfEaoH6BhGhiMIVF\r\nRxXrLYmJ6nXNaMJKvfbllpsFmZ6dn5VJHV1ASFO9F4Mh+6cg7QHTcE48+JU0\r\n6regB+6kBxSrI4eJRmnTa4eM/DuvDlx+/kENHPpKE4Em/exgqDNjcPILd/rr\r\nJ8+rKtN3mMWJuf+V6akhhUDD+TjK+k3rggZBynOiVEp2L7cxwjUCeIRz9Fac\r\nprX75I9QPk6y+Jv/1BNHv4acZwDqgh8PXniNuQZd7tnGi//63paV+gl4KblS\r\nL3erHBCJ0e1AbWp1vfpzqHA4nIjZWwK/ikB4rJ+q9TmLxU/nLnDi9NtGt0bs\r\npkNI1f6Vdx2kM2jdY/Vev34+wAE4Cou97XdFNZquNi1oSMiUDS+pVue3/xT5\r\n+05naKuU5T7KMpITu2UquelWot7hdlOz4K294jgLv0yeoX2JqZjBmIyukfiu\r\nXY17WMNeHNPVYZmcHBqRBCyxQOSki4/DwIk=\r\n=4OEp\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.30_1682453433098_0.395941828711458"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.31":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.31","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"pnpm run prepack && (parcel build || true) && pnpm run postpack && tsc --emitDeclarationOnly","clean":"pnpm run clean:js","clean:js":"rimraf dist .parcel-cache","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.31+b0ff2e74","@latticexyz/schema-type":"2.0.0-alpha.1.31+b0ff2e74","@latticexyz/services":"2.0.0-alpha.1.31+b0ff2e74","@latticexyz/solecs":"2.0.0-alpha.1.31+b0ff2e74","@latticexyz/store":"2.0.0-alpha.1.31+b0ff2e74","@latticexyz/utils":"2.0.0-alpha.1.31+b0ff2e74","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"b0ff2e749134fac039f1394c3384817522192850","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.sol/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.31","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-wewelvWJQkjH7WzjwUujpMgxsESw5bgSI+OHytEi/kxVqu9+lxo5Vtj1hAonSE2OklpXub/cAxY8EHsNSwWOsA==","shasum":"59f089118892d8663b7d95c4f24b924ae5e40f7f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.31.tgz","fileCount":58,"unpackedSize":747085,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDpgXGXLySwLpOvWdZbmdAC4lIgl6xG3G1yFBkxvLxd5AiB5ZlwFnJUlSSSdzSCaW6TTQsov/1TfOSQb22QTZANQ5A=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSUhDACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoAlw//cnoMicl1woXLtsvpLebo+vcgD97LTi2JN8x7/t81KJnVvdNF\r\nHUIKvBdILi1RLK8voBOOpy1r2v9gbpS/KGifXSQfW+t2AFIkemDFIhPBUljW\r\nJ5ftZFTyfvWIfXKeIjy99srX3ttJ7meUt3NxRGgE5J11Mj/NNGFEZPAeSCv4\r\nS0OUOhNxEcB4ORbC9unSQQesE2N0ntKIipPGibjKUTpc8RsMMxHZ2vl1VP50\r\nE12yHlT+JgX7+BSSrmtbXRK9Sohcon7g9hhxtfg++xX2OfAXnXZyX4TxjUEd\r\nnFxipC8ehqFOdNdjKZpCvc3OBlftbhE7WZ+D8ngBR2tdduk3PUIzPJ77kyae\r\nJeayjCtXO7nctYW0t9osvDikbhTKkP35r7Pfj3f1e52J2Jk4v+fkKgBqeqWx\r\nujAERXm1D9GpoWABdOSXmGYJ7UbT9Bz7xnmZqAcvqkXnWEaPlaGEzk35x9uh\r\nPJoirtYOMcnybTvCKZDlHACbL1puX+wIhGTodqScOSbwRsUMqKlOD7+h44Xt\r\nEixN7dy/xvusgCg4OPbTk61Iwxip9nElv38bqk1OxrYzbE8q2SLPqHMntu+K\r\nzKINme/Mack3fy02Uh4KjB2XdqHgwyIPQdx2s+rWpPygWA3x2PZ/Y3AaugVQ\r\n7uAdEHI/g6diyrdYDriZZW4cifMGKg8bPeM=\r\n=TYVa\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.31_1682524227257_0.23552516401487456"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.32":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.32","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"pnpm run prepack && (parcel build || true) && pnpm run postpack && tsc --emitDeclarationOnly","clean":"pnpm run clean:js","clean:js":"rimraf dist .parcel-cache","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.32+e636e9c9","@latticexyz/schema-type":"2.0.0-alpha.1.32+e636e9c9","@latticexyz/services":"2.0.0-alpha.1.32+e636e9c9","@latticexyz/solecs":"2.0.0-alpha.1.32+e636e9c9","@latticexyz/store":"2.0.0-alpha.1.32+e636e9c9","@latticexyz/utils":"2.0.0-alpha.1.32+e636e9c9","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"e636e9c9a2110664dfbc18397981126e816e597a","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport { abi as WorldAbi } from \"@latticexyz/solecs/abi/World.sol/World.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.32","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-CPRSjQFe/PjfaBMyIIuu5ROsEg7UXcKpL8QGMuQON3vZhdgNzuTr6xQmddtNtbtQySIB/oBeL2QDl99YEg0G8g==","shasum":"ae6b8c232eb00f7b9f1eddd9218f6a9b7d0ed62d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.32.tgz","fileCount":58,"unpackedSize":747085,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBolPxbEwULQQgNkdAOZ+Ombk+wwGDbgX8YikCvu4hklAiByoC0BhxxCgvs7B8tifJ5NU+3kqhYUMs4LxYDDKHD+nQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSXCPACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpGNQ//QH6o3S0YdAx6/9FTaWSeWA6CIwNnHKqvd1UQJ8xCB3uRZV0k\r\nM278pYHsh7BFUf5dkz6wPYyqOohZgYFECnGBtP8BSzWEYro5mVnmFZ64kcIC\r\n1DzfnWdnaGCQ6+KEal3X6bp/yJzJ6Zy3tU3ge3Cqvt4CrrXqyiMTBRNjeSIQ\r\nP3IXlGBdp7bLn0QTwhWrqPeZuZtwPUwwDMkJInZB6YTRG0lwbfPddcWjyRNu\r\nio18OpWqFe0cWtUkdBg3biF9dHENU/leLwpxV1Uo/Z18ZqeWGwmbGrRL4tXm\r\nkzVEeSFKkUpCHLLCGh9wOYVpN9ExWc9G1uTdzYgNSGD2QoL9uo/fbvHI2rob\r\nY721iEVH4t6SyRv+tnD0Brrf/maRNAfBBdbAqSn+EZIb3MeCncKFR14z43Am\r\nO8pRTCTENPSaM4odJ0bQYjecqiqd93xIO4xG8SBVkjCy99pTEcJwRV2HDrSy\r\nnFDNHtvaOnvFpssK6cj+FStcyFLgrrgiWXkaLXt/7l9z8ctCxh0ce6+4jY0t\r\nnfwKyVy2oPu+LCRG9tQ5qHoCTrdnuHfFzixGoPff8jy+k9W+l1eP/65J4h5w\r\nrc/el8WO4Sj7EuNNUWuP6hX3NWu96I8Sppa1hcgIc4YV8AUvynRm7b+vUjTT\r\nxsC/h6S8sO8CoQXJvfai39Op9ezeMB6WXTw=\r\n=Orqo\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.32_1682534543509_0.758041907361551"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.33":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.33","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"pnpm run prepack && (parcel build || true) && pnpm run postpack && tsc --emitDeclarationOnly","clean":"pnpm run clean:js","clean:js":"rimraf dist .parcel-cache","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.33+ede54c31","@latticexyz/schema-type":"2.0.0-alpha.1.33+ede54c31","@latticexyz/services":"2.0.0-alpha.1.33+ede54c31","@latticexyz/solecs":"2.0.0-alpha.1.33+ede54c31","@latticexyz/store":"2.0.0-alpha.1.33+ede54c31","@latticexyz/utils":"2.0.0-alpha.1.33+ede54c31","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"ede54c31862c4ce9e519b9b235dfe8083d2d4643","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.33","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-FlGgygYLGHv/OpdHbwmqZy/pOLyCSj/khlJahyW95yzADXsveJXYieuquk1LLIwkWD5JGH72AQTwky7chMthSQ==","shasum":"22411b59425cf62606481208b1e4c48f32f8f5ba","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.33.tgz","fileCount":58,"unpackedSize":747520,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCo3Nr4l9mj3qB3bp1RG2zY2DS9jhDoxBbtk12W51rjIwIhAN46pT9c+7l+yHrJZ8oGv9cgEZaPlOypcp+oKdaCZ/th"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSs7oACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqyrg//cudCCkowN7lC8HDeJrcZFgeUkogILshaH4CBr57og01uCNPa\r\nH+ghQ3KxAJftPnoXHyHpPh2u2ZDRoLjkASPsRFJ15u/LWiPrJBHxjcfK/J7Y\r\ngiwyebV/s38vOZvHbcY1JF0ZE+dD5epCcLyckIy6FWradxSHIE8o8Nz4xv7L\r\n9uyd1LtpxNG83+XynwPNaNrpAJXo+S5i0hU/nkkjnXp4YoyC8tgwl7M/RyEz\r\npGiWCcd1fnhHHHyMa0GOMPDITaNWmyDu/lyX8ezzvcopuqQWQVw6fRRahE2R\r\nTFNOdod95JyM/lwzJs7y2d8c4jWB4JxYNTvY453hQ493IaCZBCbxGmjUfrb0\r\ndRF6gH7ONud/6dOsITmFUkfjKDVl8o6A/pZ33z2VuAQ3lSVP4NUTyffPhWob\r\nOQRAeILCUZqeVYQk1Nsy+QXAkJmKyxTAgzd6LvcgcI5ZOZPQipJOChN8v/0Z\r\na7buJttwv7MmrslMSEWIqd9bDz3tCU3EQynsT9F0OEv5ASXoddTSHPy6kc5g\r\nWCTRTxkz4dkgP9ErUjeJEJYsZ840BE5/bmFyelJ+6XlUeqpU8SWxTUuTJibx\r\nn6O7gxTBfRl0wLMsoXa5huN8f5K9mtpTXrBfIFo1UbtoCbyuH100CUEmDRmn\r\n2ma7VEowMjhBmZX+npyTHvqpWtNhe3taKGg=\r\n=8W7z\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.33_1682624231644_0.08227076569871183"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.35":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.35","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"pnpm run prepack && (parcel build || true) && pnpm run postpack && tsc --emitDeclarationOnly","clean":"pnpm run clean:js","clean:js":"rimraf dist .parcel-cache","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.35+aae67e32","@latticexyz/schema-type":"2.0.0-alpha.1.35+aae67e32","@latticexyz/services":"2.0.0-alpha.1.35+aae67e32","@latticexyz/solecs":"2.0.0-alpha.1.35+aae67e32","@latticexyz/store":"2.0.0-alpha.1.35+aae67e32","@latticexyz/utils":"2.0.0-alpha.1.35+aae67e32","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"aae67e32337d6d50e52a1c6d93112dbec5f55cb0","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.35","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-EqYi3kbsotHH9BxP+mYbz1fujM7dA32QF7p3VM4eYoJGZ4cYqNlcHtKAnQiD9zbZ8j/Yhg7O6kQmVqYg70TanA==","shasum":"2a85e9a9f2013f6ab1e66ebd6b028b3a555ac2cc","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.35.tgz","fileCount":58,"unpackedSize":747520,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDly15xSvBhIKMgOjuknOeenc9ZIuxdbEPJIdaw4rVMtgIgRGHHYy+6GpuWOCpSDojcqYRTNAs5u5MHiBmtO8hSEgQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkT+CwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqJmxAAj87eqMjcOvNyH1S4TNQ5ns0+1INk+kAjRHnJrzwgTKCHw6jl\r\noOYvG8qGWByKBK1S5W1XSmj8Q7CS9tjcTD/vJJfnZLmaYmAZ9eoN7k0/x3Vn\r\njryCDmHxhOYi10t1q0vw0AY+/R0LzJKHqSjb/PjsGddeParb51y+EUTVWHza\r\n2b2LA2mJn4ClwfW7EfaLHU+HKB5R3Rp9CaL91/vzmv9mO+3HSBKT4J8Nb/xQ\r\nzMzU8WSZ5AmgGEpowLmX5fdf3c5h2rJFnxWP8HrN+Jvvy0Lv9absmRmZqceR\r\nRd8mpu50UFQZeHdzzJVNN5xyExqTCDYeh+O08hOjexeylGXJYYFNWjgBD5M8\r\nA5MG/hTwM+boGXT7Kbm6DehDz1Tuk7umEICdB09SMh43OR3wxmcPU32VrTlg\r\n6B+GRa4Nwv8mOeLxgzWtiPrIErnNcKfyLHOVzaipnuBEEDLJ0g3ft2wYDR71\r\nxgoY2zBsDLY+QOO3YmCSDG7MXXHszjdSLy+m2OIfygH6exwEXWQu+DDHsHZc\r\n9OGjZeXMZenTd5ue9jH0r1bY/mS69YcEtBDNu16FyvCsYj19NmGdcqZD4sHQ\r\nD/KpWFW+o94dtvpN44GD1gChss/AvjHegPjN3GOEWGjQlNgmnVY3vISY0AZh\r\nqi1JQzm2UAjoEXkKjOkY2rCXSGQR/15I3T4=\r\n=8QzP\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.35_1682956464077_0.021862606667600426"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.36":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.36","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.36+1bc70a97","@latticexyz/schema-type":"2.0.0-alpha.1.36+1bc70a97","@latticexyz/services":"2.0.0-alpha.1.36+1bc70a97","@latticexyz/solecs":"2.0.0-alpha.1.36+1bc70a97","@latticexyz/store":"2.0.0-alpha.1.36+1bc70a97","@latticexyz/utils":"2.0.0-alpha.1.36+1bc70a97","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"1bc70a97fb90bcdea12ce6e23a01b4e66d892d71","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.36","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-n93Bp4S+2GxO2V2LWw3I3WA7P0FNvtSqUImu36Pu8mjy5aRu5Gx0Ib8imhZNQ7z5LGid5KixuWqG9f0D9l+Quw==","shasum":"302a8348a6abb4944f544c11256520fa211b4454","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.36.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDEPHqr8v2jN2Q43nni64fY/9k27uCIvlcBCtAK1aiD9gIhANgozgNmCl+Oblwf6LgVaCqGmxnDEgaEwE+dB0cEK3ON"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkT+D9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqPSQ//W7OdTPPr0RoxN6atHEutchGzi+76FxWPCgYL62T5sUgDyXgG\r\nMr3mtWuTbDDPQysdIxGF01tPHazGqu1rwwVeJhg4I2ucn3aPSgl9UxYIawqj\r\n9UIZWj8E33k4LS8oT6+bsmkGS1lrmxM6HioBeaeknwc+vjnusfZUVVy/Ds4S\r\nRr5vy9WXvVqvtd8UDO8MnmHJ7Ui2Ol2W0FDrCAykQu5Cp6OsGRvSjQq2QfeL\r\nBKgWSG4g69MHiMjwpvTs6cy31MZFc47YbgiVxJfQOXVare8qGgXvxdQRbaEx\r\nErzcl22kVPzIgl7K7F8+0JyzVr5MtoheNWNzw2Wv3fPzpGrVCzChM0mE7rjI\r\nrUpqgJpBgE5kKfwhIsfdaPWjEdR81M1k/0MzbcHL1uzgHsle9z72eUZyb/Fh\r\nqMRSGtC32m7zgFMNWjcoZ/Qo30G580QXpu6JGf8Gke7F7UPLGOlWn2oFjkmm\r\nhPw0Ut6rkpbeeENefhRGGu+l+ZVNcavoH8bIOF99drEIuDG35d8Io6jU/JJt\r\nlNc7vOyoIXQ4JbuMRZrozIlgSnCFPhMFdqT/HeAlTpA2aURygPS6IE3OW+2O\r\np2bbiZGE8+mvEsY2H85RU2Qsu7505ETmVgS/gXwIX4AR1JvChtwPObElHbfA\r\njv4V4BjKlfFeulGL3kYnAw7tiMRqFDy7zrY=\r\n=SY9H\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.36_1682956541438_0.2933406873117228"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.38":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.38","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.38+66c15a33","@latticexyz/schema-type":"2.0.0-alpha.1.38+66c15a33","@latticexyz/services":"2.0.0-alpha.1.38+66c15a33","@latticexyz/solecs":"2.0.0-alpha.1.38+66c15a33","@latticexyz/store":"2.0.0-alpha.1.38+66c15a33","@latticexyz/utils":"2.0.0-alpha.1.38+66c15a33","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"66c15a333ffeb3bd5dbcabd68544acc9567ad743","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.38","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-YR2CZu3kNnHKVLWtOAvU7LHzZjlIRWd/QQv81TS8B8WM6cG3O+y5z79ONJX9hkgzUyATbyRZnd7iYKqaz2pqmQ==","shasum":"a58dec839d55a57d293245ac320bd9c89ccc3c2c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.38.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC8uwxs9aRXiwJHtsMJlVKk9Rd2vTmhw59GRoTXuS0pxAIhAPmG4aA0VR7nbR4ff+z5MCTv5LsN3+a7+Lmf8BpLOA6d"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkT+EVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo0CQ/+LDtVD3kW/4V7SJttx1uzykDz3xk0PCVjMmQC/sK8pNnV9xUQ\r\n6y3twPH7ir6uCTCJ5P9HYoKpjp6xua/SboNNweGC1AceiIdqz+9wF5Rw7v13\r\nx6Ek0L3bY8zAd90huipfBi7HHNGWfwSN/0yqzY+x0slXZQgfXsbeIwcYkr5t\r\nIBvH6y06SAGABLjQ4B0lFZ6lbRRc6KDbDt9dtikMSBdoznoW8fG4FT0t6/x9\r\nWRnSN2yxN/vXeQVXMJUuwjeE2JXB901TAvizkTpVHieGfHd7CdsUMSKqoHqz\r\nv5X4Oq7YddDS/Sl+bs5moBhdgD9mUWztwiAe72GyiJYqTtK4U/jA3eRJzlwU\r\nCQp4GxWa6B8+LM6aZUtHYjPtJYSWMN5TFrd4vMYLvG/qjNKrQNevtv2Yq7NP\r\nGuv626uzq8Z/C9QLWGW04lEwZB0pBl+V6fNc2E5Lr1G4Vf4RoAIczfGxXFtE\r\n2Q2WN/MKLaQbDNbcRTV26x5+37ggQy+NTzW31RKk00ZcSP3o0l3B7NEqR+HW\r\n1O/YdWabIUr5Jput+5L4ONJWSjInEK1a5Qk+3jVeZBE/zdy3hsjoNTzVxWBi\r\nQ0GDI/+nU4nOfTwWP19lXbed9K74a8bTRl/l2byb9IjEy86RVtJegKtcTkNo\r\nCIEF3xG6P89jHaIQE3nOGjk+sFx9CO9Qprc=\r\n=zDdf\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.38_1682956565426_0.8358660106476852"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.37":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.37","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.37+c179bd4d","@latticexyz/schema-type":"2.0.0-alpha.1.37+c179bd4d","@latticexyz/services":"2.0.0-alpha.1.37+c179bd4d","@latticexyz/solecs":"2.0.0-alpha.1.37+c179bd4d","@latticexyz/store":"2.0.0-alpha.1.37+c179bd4d","@latticexyz/utils":"2.0.0-alpha.1.37+c179bd4d","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"c179bd4d22a1c927949cf1f7059220abbcf95980","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.37","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-dSSIQIjbn/1+ShC8efU1ZtgKnTbqOQ3xCXVzXgcr1inAvNRV29o+myF6E0LHns/twjzULuPaB+8vPVuMtfeIEA==","shasum":"1a129fe065e3524e4702c6fa5b7a310f71307c58","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.37.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDgjAtbw6hNXxAD7kLLbtLJ7OSrXjFO81Q+2rIXqP0GoAiEAgbIoOI9F2TirdxRvAK9zslghLf7TLS10fNefWm7HSwQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkT+EaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqR3A//f3H1IuWlDzmkicoQdCBQ0K3W/pA+BBa8sOQZz9s+1BCMKyrH\r\nyYAJ6AntamvjHgcYx5oJCbKIMFbooAeOTL4mFvEACE7ciemOhxuKW3p4dzU2\r\nXOVHNA27640RJ5Ud99MHWz5vaA0mqTEcs0pB2jJwes8YGXbJavMzCt9W40ho\r\n2ZxYObk9XucZORyYEXFrvxsI2vikI9GHoHGlqfgQiFYziOy+/Px1m9X/0JSX\r\njtBLPL5CFLSlksvQQ8yUdeDL1aQL1iO/VIjOKYccSQs/vsI7z9l0yOG+UraY\r\nKJn9QJIDhdWDbtsUincPs0SxoRVdx9fJ2odwuZhXUX9YSRAPhgs7dsLWsIGF\r\nJtt+fQXvPd+UuwNfSkDIKr7fbhcqlLbB5j6zwYpjLgzgvHC3UfiSJOYgSRxz\r\n+accKKj5UoFNE6gCAo7qv8mHJ0a5Lgx5LeQORwaPO5EoDJ9l2HRjFgoEmrrn\r\nTTMid/NJCpBZ2A/ZCmH8P5Z0MEFBKzyEc+ZAyglRonHO+eLinXSE19HSdRDv\r\nvrHp+t8VwqwTl178yDSmsuTL3mwRnh7A/yp1+GBoFcTwIBSzS+eZHP1+2K49\r\n0r3zLwJkITrnfUEXRFJ/7vvvgjGyENBASI+7XV9EMNwdSuqdSm9D85SwshjK\r\nw0C3TdccC+/rqdw6nSyI3fgpaCb6PyAicqo=\r\n=ZiOs\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.37_1682956570379_0.860097622276315"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.34":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.34","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","main":"src/index.ts","source":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"pnpm run prepack && (parcel build || true) && pnpm run postpack && tsc --emitDeclarationOnly","clean":"pnpm run clean:js","clean:js":"rimraf dist .parcel-cache","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","prepack":"mv package.json package.json.bak && jq \".main = \\\"dist/index.js\\\"\" package.json.bak > package.json ","postpack":"mv package.json.bak package.json || echo 'no package.json.bak'","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.34+3d69f92d","@latticexyz/schema-type":"2.0.0-alpha.1.34+3d69f92d","@latticexyz/services":"2.0.0-alpha.1.34+3d69f92d","@latticexyz/solecs":"2.0.0-alpha.1.34+3d69f92d","@latticexyz/store":"2.0.0-alpha.1.34+3d69f92d","@latticexyz/utils":"2.0.0-alpha.1.34+3d69f92d","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","parcel":"2.8.3","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"3d69f92de42f695185a1fedf468694ddef36cc83","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.34","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-38CcsNAiPdmHFHzyNhmarPZZOVWWquMcJOLMyPSlcDz/+LikmQeLQ6Z0ro2vDNbS+LfHbl27nlqfJcRDvSS0Jw==","shasum":"403a47b3f498fee299c2533ebe5cc17f1275db8d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.34.tgz","fileCount":58,"unpackedSize":747520,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAwQdDedZKSPJ4F5QHu2ngDUQUaMTIy5yATnGdJiauInAiEAnypwisXmLIV2Vc7FbbE0ZvLzRDi3PsAPhqaEqcmPGhE="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkT+FVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqM5A//ZSYznad+NgouCNesFMFf9nD3CJxhNSJLeO2gCbr33bM7xqvg\r\nNSML7ZM9pVunSABbLqlXnibD9itGwyL4dpr0wmyormKvEWpdB6qMcgy++piM\r\n27XT2DD6E3KntdGjsMt+pAYIz80K1zipLWdwVU351N0NqkJ7n4ew6N4R0S61\r\njDcPu0oO/PWwllQ1ITsSMLuEk+zSXDI57luwX3QGlpuTjH7OayOvZWTwi4mT\r\nCNoiS7C37MsUErmNuTXEF+NOCpPbX+wSc/lZ4Yv/G1Ds7PZEMZbtcJCO9e1k\r\neSpX+0TLPmHPXbukPWOhc4Mc/4nz4RaPQdh5qSOcmPo06xbt8r4kq246ktqu\r\nUOvygSDrve2Cq5XxCumsXuqhJ5aTra05fIb7m1tiB4N+4QPlq/1kwkMEMlJ+\r\nQfawPXGpC5CX7ZwIepmYyDhp7w3ZKsJo7yG40C3uXD6dmh5LoDPpMroTzz7p\r\nQVhVC7DkxxmEcd8FjuK9OZLAsD5rJQ1EOJOzp9tdXIc4iTb5Er2y5I+FU9na\r\nqZMxxo+dg4DQDxZ2ZPUZAuuKbhvvpU0nTdpZc4OVloEGztSwJVPwQrcc25Pa\r\nlrOI8XI41+N3E8A8BGM4S3iu76rR+gO/aVNf6j1sm3WL7xtvafDIhL/S4u2R\r\n8u7zpGl5QxlRZAc/X2l6pS/8s/xqDhDVE3Y=\r\n=gWZh\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.34_1682956629665_0.7313402598619538"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.39":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.39","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.39+9e7e4b6c","@latticexyz/schema-type":"2.0.0-alpha.1.39+9e7e4b6c","@latticexyz/services":"2.0.0-alpha.1.39+9e7e4b6c","@latticexyz/solecs":"2.0.0-alpha.1.39+9e7e4b6c","@latticexyz/store":"2.0.0-alpha.1.39+9e7e4b6c","@latticexyz/utils":"2.0.0-alpha.1.39+9e7e4b6c","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"9e7e4b6c32cedda6b0b0834f75cc1090d62d44db","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.39","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-2wNgxvpoTT81NMQ8+LrrCNqg3zBrbd19e78wTLuCXUw6d0AtHCcSskJdSz1k/g/JbAwx/tKKLcYOkQArgXJ9Mg==","shasum":"0c9569a85fb4cc93b1a7932fc8abddc5a86267ba","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.39.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCnKyqNrSNFkNy0mkvrl8Y41Mj3qQJe4aioZJPeccJE8gIhAKn1h5xSW+GgsnhIjyywIhsIlnRc1rRj2h8FpjZLSJqo"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.39_1683038295290_0.46742750982955106"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.41":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.41","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.41+8d86974d","@latticexyz/schema-type":"2.0.0-alpha.1.41+8d86974d","@latticexyz/services":"2.0.0-alpha.1.41+8d86974d","@latticexyz/solecs":"2.0.0-alpha.1.41+8d86974d","@latticexyz/store":"2.0.0-alpha.1.41+8d86974d","@latticexyz/utils":"2.0.0-alpha.1.41+8d86974d","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"8d86974d5f30846cca10cc9b74f5c12db0be442a","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.41","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-vXpimzzh26gXZKBxniw+sQn8qedUHrb6fdalPjOBfDcnc/nn9darl3wagF9PXC91k7hOdOi3ntT9MBhM0xU1zg==","shasum":"a042718840b86206c05beb11d25161c435a09d5a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.41.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH1E1/f+fYm7E61t0c1M7FEVe7vhho/8/XijXu2O1ohSAiBsaYKibMZebYgDalqIOEXSSaG8iHNHSXDnERUHSIpxaw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkUYFZACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqRYhAAi4U/8KtE3AV/CRnd89bmuVQvSDxlmu0/R+4oljSocBfuajkF\r\nWqvWJGEp37yGUY8wlXRH8vFDo2LgkMG1DFlsSHpQtoVibn4uRAAM/U7v3SDM\r\nzF1PiNHedRVPZ3QsbzEYZAM5UobI1x2QUDO3yiV6UJcC3EPbjYaElNr3xAnp\r\n6WWWPAA7NpMy7XVQb0WitiNthdud4ihiJ8ZeTV5OnWb5qZ5YUhjowjoTiKjl\r\nRVCAk9yPFfTSIUkKhD9wp5TjICVw3cRkyNN+a7negpR9vH78tQT96xp0QO2x\r\nGmCoKjBXdjJO+LH0s2EDBokHsjBp98fIQ8HKx6/6Ha0k7HKGZGXpa5kr2OfX\r\nqEa5QBPm9KlGsVMstamq5qus7HfKDCjp7/7kr7KtuuyiJCDoQqCRu87ZLViR\r\nDwP/jOAXU6BI1KAU5/f0LRUI8qlNCAEF2HSyOhalu0RcRAbqr/BoSWzfozui\r\nf7PjW/bzFUJpLhdS2wRJOM+1j7LgEMYQGVlw5wajV4T2JFYJpTNRGaPmvUja\r\nVvvFFuDezkN4oQbqLhJzNVjEutmW1GaUgTnZjL5sjqrn2xkwGSG5+TY9fSAk\r\nA/mmzG28ATryOFjQzyMBLwmAapTyNhRkOYFZ5sxXH+jcmcSLqZDlrpHgCnM8\r\nf6JvTiugHDR33HO3gENdyDeGwTWJ5VaHbOI=\r\n=nl5l\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.41_1683063129732_0.4691677163977219"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.42":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.42","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.42+d2293fd3","@latticexyz/schema-type":"2.0.0-alpha.1.42+d2293fd3","@latticexyz/services":"2.0.0-alpha.1.42+d2293fd3","@latticexyz/solecs":"2.0.0-alpha.1.42+d2293fd3","@latticexyz/store":"2.0.0-alpha.1.42+d2293fd3","@latticexyz/utils":"2.0.0-alpha.1.42+d2293fd3","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"d2293fd3d946055b1938435f5531fb6d406b38a5","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.42","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-rFF+4QnFwweB2fAy9Kw3tkRRCf+D+4Bt5ukHlzf08syQZEF0RSXwMAZrBKW1W5W91LnWpv4AUDhtdDcM2HTyMw==","shasum":"a2f21cce893fbd50bc89fe485e25932c2b7aa484","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.42.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID2icNnAHvZvps6Ltz2KOhIvvu4vMSXBi/Jzcy0K9ID0AiEA/fSY6duPebW4UydIFfTxrqG2GTCLaXdOSijHH4xZn+Q="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkUmq4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpz9RAAgTHfs8bTEm/UYLXEPSnEeE4yi7N3bIRC2sFYLn8ajz63OGU8\r\nK58xA5mN4cq62pEjICUShqSXzytwNSeXOSBR5KiIHPWBz2kRQnmLz+PffVyj\r\nrUEvQU2/bII9zdVtHABRMJmkcjazH+eDGv3YjOti6QS1syIxVl0KlKCKb6Li\r\nr5DZt3XPlvqJfc7uje1T8WqHYNJti171yExe8S6cD1WyfHf2QGrLRCojj/6p\r\nq7364hRJviHG8miXI0ftQe51KCNxlE2ycE3ykPX9e9PxdyYZj/+G6IG6Smk9\r\nuJrMt7OqKcSGQDoYjWOI+8n7hOQAsTXTisilA3GCzFzghjt5rNKtV1/0QPEE\r\nwS2HDq+zU94y9jsa2zadkKKROZOkpNzZxZPeG8IApaRzKbz1b9jqflWxrNO4\r\nGMhhF9pCm4iVGk5Ka6Yzx2FhzOLzozUoV+dXlea/kTn2y1aJuSW/Se0s7sV+\r\nOiRthAgFZsG74mtuYQc/LbO1MnEPPV+oKlp1Pln0V6zVkn78LKbKMDRU0VgB\r\nM6S6gMi8dwki8v/y4Tnkje6HtqGUlfT21xmIkhDa9whU11beUz3+U2fWUvs5\r\nwtMVUXIvjsVCN7AKK9YCLDHFI65aBY+om1KuJus571rvG4N6bwaks+bwPox5\r\nubfUazbGt7y6ImFfsY4at3g0lyJpmHrAw+E=\r\n=FM8+\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.42_1683122872583_0.4259639126411543"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.43":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.43","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.43+97d2ef3e","@latticexyz/schema-type":"2.0.0-alpha.1.43+97d2ef3e","@latticexyz/services":"2.0.0-alpha.1.43+97d2ef3e","@latticexyz/solecs":"2.0.0-alpha.1.43+97d2ef3e","@latticexyz/store":"2.0.0-alpha.1.43+97d2ef3e","@latticexyz/utils":"2.0.0-alpha.1.43+97d2ef3e","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"97d2ef3e9989ede6c2a34bf92e7088f6273a33b4","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.43","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-+K2/UVfkhjzOKHOvJSETsqGtZjZKvYCYzEUmgf/UwZUx8293+6A1pIZy7hC04c/ov0NVaNn5yRlEMmPUmadmIQ==","shasum":"ab9e92ba3cf19aff6251fb31be49278c6a7314cc","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.43.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBrTkz6uUbt1gxXfNeyJ5n9BRsPyM8K/ihUxNeehON6iAiAuqQpNANOAnCsxjSIf481FsPD46iBuJUzKph6G3qGBBA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkUof5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpilQ//SiRlJ6V8mNr6faoaImRrAaPdONwYjLeDJI+mgNJNsGlb3Ube\r\nMmZ8pecIPK3AfzMVOtQ+Ku0a3V9870ibPCxZvVGzmfVT5Sd+BCHXqg+rgFFn\r\nQNqfYWIMwW/RkF5tfz6QqEhV9BJ2YE7KWFsXCWFc+V+cy44S4+RTAlA6cotY\r\nBDIX6rwnAXtOLuUNGomFpAZQ7QVZIJLzgTB/dvnAPkTsO7AIzaaIdKWQhb/3\r\nWLsQmq6umCwfXW63RWDMBweEimBaKrTbv5RbQKnLa7quciFa2aII9W60nIsG\r\n8uy9cTZE9J/wSeNoraou4Ehd7JL1ahYaI3YtvjfcN1+0VDrjmRrie4pCVYSR\r\nVgrBnZySZL6wVOQSs7RJw6ZCKW+w+sc1SceQlMYMEBhV4b75gg4ncZjwfqhQ\r\nw/duOoUGWnzlw7EiXC0O/PxRVcVgH4oqyCXIP+AbRY3DbmVuW9RRyqRb4VuE\r\nURIN53IckkFj1WFaRneYUVdbPooBpd0N5ezEr+gtqi4LfVsYlifZhJnJ6m+r\r\nymDIeFCQ6ehsjPHPQtRLVcexb4gAaM53oIQecqYPFcv1gWSo3aqg/VapHlEx\r\nC9mpLszhpuaHhw6fU/V1ATLQxQvgCV9v1h5EwX1VWF1BwCrPCmvwIcfgB74V\r\nWwdQDwbY38cac+cY6NbVqekbFe2ceCz/+As=\r\n=xhd7\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.43_1683130361201_0.206151504749863"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.44":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.44","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.44+4b3b4725","@latticexyz/schema-type":"2.0.0-alpha.1.44+4b3b4725","@latticexyz/services":"2.0.0-alpha.1.44+4b3b4725","@latticexyz/solecs":"2.0.0-alpha.1.44+4b3b4725","@latticexyz/store":"2.0.0-alpha.1.44+4b3b4725","@latticexyz/utils":"2.0.0-alpha.1.44+4b3b4725","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"4b3b472541e8f933051219da1e52b876396c58cd","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.44","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-cidpYZNNMR2kYZg3NOXoZpfAvwvQbzqhoLt6r7DsXINYSox+h0A+6bG7iTEpSRhwDJLQw0EMOqPiQSoMLHpAkA==","shasum":"c673df115a2bd0f515decc35058509710313fbd0","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.44.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCGKng8W15Iw+eKDthfV/RYdYmHMp21CkLNu1PwZ4v7gQIhAITjbmbKeAcWBMAj6ZyfLR33/nnvRW+Fvhpnh/+L7PSM"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkU8m4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo2Ng//VT1NLeIcM+QLDxtRu7jGnMZiD+ztBFqoSbSFQjRKDjzKyMQc\r\nriAXB4EmgAcTIO+5KApEEdL81OcNO5Dx4OGQdAWwpP8nQPVNchS//Zylesug\r\nATZCD9ERFhmr9kGpkjRLZPb2J/lCsxlMyih6ejMwgz8PXqUU8uY+hgfsFErM\r\nSDP3AKzMfr5hUkBxsg0UFbcbtb/p1Fcc2hlB4bGJj7nVeiFc6gHuf0PGX0x7\r\nyXYyVEeERyHwUgikW3BK+QYpFVB+MD4jhVcqDN6O7bn+snrEELlz2HQLfAKB\r\nFxIGu0eaC/vWgJ3+VqWetB6WD5sUfdJvb+Hub5FGiK6mInPIzEQDSCBgqOYX\r\nJdajqO+aT7FKFQIjAS1DZ2XheZvM2j5NKZ02txaF7GrVy7ZuiHhIhBfwp6fr\r\n8nnW4ViqTnWQ0r5Dwh8ZbQ9oF1/3Zx44i8FVsBJTv9VYadZdkqganSTz8GDO\r\nMUNPMZNuCsgqYcLoMf74Ym972xwrLfMM6y26qaQJ4HlLRL6RwuXFQ41Bw8Ar\r\n0Ja1xAdjOM+1z4IeIo7YPlgilaJwFuQ/BOJCV3SmARRs/mYww57E8uWb4AfK\r\njYmP5TPAdO0BUgqWlTNiP9Tr6cum0QEsx+/lhrNMs2aNjQSIJRTRkDmL/tYz\r\n/WsC1CyG/jxfDTU9pk+dbon4oJnx+xwys9c=\r\n=qZUa\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.44_1683212728266_0.8076964234028516"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.45":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.45","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.45+72580202","@latticexyz/schema-type":"2.0.0-alpha.1.45+72580202","@latticexyz/services":"2.0.0-alpha.1.45+72580202","@latticexyz/solecs":"2.0.0-alpha.1.45+72580202","@latticexyz/store":"2.0.0-alpha.1.45+72580202","@latticexyz/utils":"2.0.0-alpha.1.45+72580202","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"725802026ea0a79340354d38e0234511dd2c8076","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.45","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-mhhZmldXsAWS0NfGWL+69wfvBCoCMZP7ILeX+UT27sS9TNZYzUjI9cfhvE65jbIPGLL2O20kRWeBS/Q/Abi6+Q==","shasum":"fe73e49aba3853b13bfb9b49d3ed3acb94fcad0c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.45.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGq9H6tILTnrMZ47puYtPJMVgo8+XUcH9jPL+XetyCqaAiEA7w20hj2w9PQNgkGWZXdP9btX84Pcc6+ZgWJf3XYQ0yw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkU+iNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpD8Q/9GNzf6PT27Y9e5dK8dBsqqF+8IWxZk+Jo0T/eXqqLixqpH8z8\r\nsrKhHTHuZYOYST8wJIyWEG8NmksYkcjTUqiwr+lQJrUtpkCP6S/qYtB+gDcN\r\nXFVS6oSecF4L6hzBIUCCunFWsccO7ExftpPuJ++9K6Ftg///y/L6sGVFhl12\r\nWUHGQuE/zZtcJrNCofvDrU3uFNTAeMGTg1RDkQjOi4hygY3rqeaJq33Gfars\r\n806bQ5Y0ZC4fSo3Lga0zIfq91g+5yAI6ijEeyWQtceJGmM/vu4GzbOOJH5Wd\r\nCdjAOF/IoYnOOQnx47S8nGr5G6holv8Uh63g+wKpXltLqEoUu1vCCdVGXJ8l\r\n6ZGUHUYk1vVZ+6/cQJsJ/9VjLD895Asu3o9rtgRIePrUPz6vAYe92xNNHeOz\r\nZFpc1nKcqBFjrA1g2PKXO4N0CiaNbeJj5TwflT4zyT8sXBoa+nHW53FLYOkm\r\nA49NDSVFnIsnBP9I+OCJP4xZvyVoCwk34nsRS0iNkOkALLMBMfP//N3yxxmY\r\n0pdD4/se0emeBnjE0itZPsi1m81FixFr7vGz7OpbHrGr4ciVrcScoCuBcae3\r\nBP1Tmw2GrGX1+BbTwfkpI7muGwz0GG9aNt08KeJimq00+gGRZZjYlPWFGUap\r\nfhFAXfjVn6zUvbTze3RbcKGiVLmhGRlQxtw=\r\n=Q18s\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.45_1683220620828_0.710001499547676"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.46":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.46","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.46+ef6e6159","@latticexyz/schema-type":"2.0.0-alpha.1.46+ef6e6159","@latticexyz/services":"2.0.0-alpha.1.46+ef6e6159","@latticexyz/solecs":"2.0.0-alpha.1.46+ef6e6159","@latticexyz/store":"2.0.0-alpha.1.46+ef6e6159","@latticexyz/utils":"2.0.0-alpha.1.46+ef6e6159","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"ef6e615907cad5a74a4af8c8cfca3aa68975b4ea","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.46","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-pumS4/WP2rRJROzQhBOUHrTSFuKJ1858yu2OnlOc3JEf7KIiWpB0GvSGm/dLnJH5i6gK+GudW1jZmUNouEBb5A==","shasum":"67669de8eb575a0f2483870dcd90258d9d478e75","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.46.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIADbXktInt6GcAhVLF6SptV8qQWDa3JdLCvBmsWRbodjAiEAvQEO6Umq0rK0A8/aTygZHlF9NqwZ59hFBTI4taX7AUY="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkU/u9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrxAg/9GfwtUbjSq/zm22lqcROIK/Vd20tLGq4aj1GdSDJjugNl1qbw\r\nBUcvgL2ttzScqm0zKffvIOp3rfW2+rj2sBeDZZwvSXeeWG+6mDTGCA8Ue4WX\r\n8JxoAR/dGZz84j0OYle0JSVntgfZ4bOxhgbGXO20uQPugVe0eOeavFCZsm8Q\r\n7dWM2e/vfA8HOT7BNP410plmS4e1Kv1Orxbcyy6SsBliwq4ikrqOIK9dN95z\r\ndQJREcYWhjY8Y43VPw+b0a7EzICgkO1bKKZ/39llr8q2T9KSlZwC8Nx9rIoZ\r\ndf1NOh6THS99sw0Owx8OBnmjREGAqGhclB+4Fz8YP6Gz+swMhjAYLDU5T1LM\r\nq1YHKas3124hksQV1Qo/C0xTIKIGoQKKHQ1B9wSZKat9zcDPSNu5US5vVhF3\r\nV3aNR+HTOxpk6eoepZi0vqZAd23nau+98xzqB/d7uf5vlCkJ57MntPCXVq2L\r\nxpvoP6NqgGoz2q2JBMW1m/vkDTHxzzMi4Y9DoGnkiHJP2t1C/WgkaM1SLpE8\r\neK7ElgkhJcEu7MZClW2ahJGRpdk679EhVJZ6trb6lcPZn0knIZRNuAsY4N3q\r\nfitJJbctuJs1PyxhxRRhObSxz7GZM7qIpVUwoZk+NlOydNa/BczmRea25mS9\r\nM+xDZ6xeEDR0XsUt4av7VRP3aTCV/zD1I48=\r\n=b/h7\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.46_1683225533299_0.9086567420038241"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.47":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.47","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.47+525fd2e2","@latticexyz/schema-type":"2.0.0-alpha.1.47+525fd2e2","@latticexyz/services":"2.0.0-alpha.1.47+525fd2e2","@latticexyz/solecs":"2.0.0-alpha.1.47+525fd2e2","@latticexyz/store":"2.0.0-alpha.1.47+525fd2e2","@latticexyz/utils":"2.0.0-alpha.1.47+525fd2e2","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"525fd2e2b05183f2938f9da8aa44c45834978e79","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.47","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-PFZ0B9P6j758ImzFk19uwh+hoNJ7iQayDqttQQlfpHMpdHvmY5rhz3TEwTLGtS8COn08ULYgH4vHue8QZUPoKA==","shasum":"b0c63f36aba752ece389a88659d3541182da9f55","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.47.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCDeJmDAnBEfN/wPUGTYs/OQ5TuBqIdakSlwSvUR6gc/gIhANwPzacn6UAYhGA8b87rU8hQHPW0WHD/KYcq9jACcycw"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkVAz2ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpjGg/6AxCT6ejebfaMe3oe911fbqDuYIqjq6UxLnx+3dSnDg5N76I4\r\nOycri3woHxdVVtkGrasi7/Kiw/kHAtMmZ+8OtZzIOka4rl1dL8XE3pLmO+2I\r\npReposZBO/DB9L6B5zniDO0oUzoRdkJYsWlrFiiztdeOHtunHIXzD2K68Bhs\r\nswCw3pHjwsz5CD8VaOgm8vONRq5C1yxpzGOHDqpAG46O2X4NC2mqQ5LAlD23\r\nwsc1eR5r1xGukeyHOjINAVQ7FovWnM+FX0I8a6yPd0bYTtvMtSVKVkvv/Xjo\r\nNAfLIgNhcOzmx972W8PzhWZZ2fxIpTeAZ9cXP0vj9u7k+BhjfRsCN2k2aVF+\r\npkpGl+v9Z6hfVTe24G+x87On9bbFSRzGCwY4s6wJarmVFx4UDqre6RKjPvbw\r\n/SXl/1QkE6fUbwVNitydIjlM3Jv/CUFlSkLedii16ul31xRBA15OOpROVC4j\r\nHptgay6Wjit3HxeGMVi4gD50wFhhd+h85O31nQqgmpj6bHJPL2zTRbH0Mu20\r\n7jWusELuiTpu3yQOIVINqoXes9bBINig9GNZcGDnrm34LLUjS14VQVQuThlh\r\niUv5srwwvDXidd/LBamMg/rXljD1HdF+wg+acwewum/bphi1ec7A5fofou+g\r\nB9AjJM3PgrsxWnkX+6mxQTn5wwi19/q0rIM=\r\n=ycAR\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.47_1683229942292_0.3532665540631956"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.48":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.48","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.48+3869b4aa","@latticexyz/schema-type":"2.0.0-alpha.1.48+3869b4aa","@latticexyz/services":"2.0.0-alpha.1.48+3869b4aa","@latticexyz/solecs":"2.0.0-alpha.1.48+3869b4aa","@latticexyz/store":"2.0.0-alpha.1.48+3869b4aa","@latticexyz/utils":"2.0.0-alpha.1.48+3869b4aa","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"3869b4aa94dd961c3806bbdca67a0c683adfe3ee","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.48","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-T6dRjfdRCkuw5RwVdrkYOgA/FDT80Ib4UAhD923/KTapQ1cLLbix9ka5jr1+lLjK+jtn9Rnq64t29JnX+o0vug==","shasum":"3786ce2ac31aee7e1c60ea2039420bf8bcc372d3","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.48.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD+FLqIzJVs0gpGcnJZH/9wxfY/2OlXFVqE56bLFzKWIgIgBenulq4iCANmlub2HgfgGHkIRUivvpOJYw2wTI0qOy0="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.48_1683552683411_0.27080793522871827"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.49":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.49","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.49+b4e12cbb","@latticexyz/schema-type":"2.0.0-alpha.1.49+b4e12cbb","@latticexyz/services":"2.0.0-alpha.1.49+b4e12cbb","@latticexyz/solecs":"2.0.0-alpha.1.49+b4e12cbb","@latticexyz/store":"2.0.0-alpha.1.49+b4e12cbb","@latticexyz/utils":"2.0.0-alpha.1.49+b4e12cbb","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"b4e12cbb81079d91f5c5f51cc2aa37f5bc0e638e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.49","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-vBWjMB4YANFQCa+LgjwyPRrNCsWZJd0NShsL7lAsgPF4yCD9M+mz8MJZhxY17A4D1B8AVrUUCT8NRpLKALsp2Q==","shasum":"b6095d48ae8f9da614419ace2d04f5c7e0924b02","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.49.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCYtYkFX7zdJGRz7j9BymJXS2h9xORNTlUL5Lz7B1274QIhAKhGXZdgSNhLt32pywe7/ofVWbYaT41oaBHfZRvtru0e"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.49_1683553283715_0.2411941265269335"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.50":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.50","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.50+46d1a612","@latticexyz/schema-type":"2.0.0-alpha.1.50+46d1a612","@latticexyz/services":"2.0.0-alpha.1.50+46d1a612","@latticexyz/solecs":"2.0.0-alpha.1.50+46d1a612","@latticexyz/store":"2.0.0-alpha.1.50+46d1a612","@latticexyz/utils":"2.0.0-alpha.1.50+46d1a612","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"46d1a612271003dc39d96391139dc3a08cd8fcb8","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.50","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-4hvH+v+azdqAUnON7O+Z9uuYEKYSOWt64r2Tc8CpgZ8nLB2yK9XB1BbSbGLn9i9S9+PMC+6eEeo8ps5mwboKOQ==","shasum":"d285ef311abfcce1374afe7f20f14a0c7386081d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.50.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCfcM4MErLQpF7Uv4zrwL4tt4Ery72iMU1nIujuxZbEVgIgNv73sU5PHsESp19vTtSIg3SxMEwEMDAoUrzz3h3qWCg="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.50_1683554447767_0.3143046339554292"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.51":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.51","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.51+aedb0f26","@latticexyz/schema-type":"2.0.0-alpha.1.51+aedb0f26","@latticexyz/services":"2.0.0-alpha.1.51+aedb0f26","@latticexyz/solecs":"2.0.0-alpha.1.51+aedb0f26","@latticexyz/store":"2.0.0-alpha.1.51+aedb0f26","@latticexyz/utils":"2.0.0-alpha.1.51+aedb0f26","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"aedb0f26e8090506858a9450847afd32cfe01d4c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.51","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-9YV0/Sk6F3zOLwYuRN6+4Kz0Uef2D2jPLmLxYt2wL2yNwHNLdKPPDQ6TUCJOX6kRioZrGruIrqgEwHIZO6YO2A==","shasum":"de67cf7b3835e6150c995e156d7b16d740fde839","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.51.tgz","fileCount":70,"unpackedSize":503072,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCW6RzFNN/t+Gl2P1bzVd88oHj8Tw5f/qM76K8mdw7P8AIhAPNNwLmptnCkrNAZF4XXYXDqV+TP3ANIKvPUtxuvw4Io"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.51_1683557252908_0.4687398954989268"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.52":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.52","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.52+09d46420","@latticexyz/schema-type":"2.0.0-alpha.1.52+09d46420","@latticexyz/services":"2.0.0-alpha.1.52+09d46420","@latticexyz/solecs":"2.0.0-alpha.1.52+09d46420","@latticexyz/store":"2.0.0-alpha.1.52+09d46420","@latticexyz/utils":"2.0.0-alpha.1.52+09d46420","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"09d46420efd66fc7048014e561a48b348f7805c3","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.52","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-fcNqLdicd32uVUv615uHfrO/G0EIqzXUIrR4VXX/GLQZBKQdLMpAyypLSnvSHfpP1yDOMQq7d/I0E6j4FZIiqQ==","shasum":"88d4cef1808a6cf21f22cf58127e615b2e4ccdf9","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.52.tgz","fileCount":70,"unpackedSize":502844,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCoWU2vtgQX1iJPVEe6eE1SsrHRJtse/lfy0Vvph2R20wIhAJiJcuFlrsG26rBu+DSSl34GTl8nQnkwSj5e2Caz4/Dl"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.52_1683557679090_0.8426192612680188"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.53":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.53","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.53+09c9d72d","@latticexyz/schema-type":"2.0.0-alpha.1.53+09c9d72d","@latticexyz/services":"2.0.0-alpha.1.53+09c9d72d","@latticexyz/solecs":"2.0.0-alpha.1.53+09c9d72d","@latticexyz/store":"2.0.0-alpha.1.53+09c9d72d","@latticexyz/utils":"2.0.0-alpha.1.53+09c9d72d","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"09c9d72dcad040c49a6361d80e9f0330e3f43b71","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.53","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-JBXOX1SI/RoiGA9wM9d5aZ6pybpgQW+n7gmqtJHj5JTxGnR0cBNHDzTfAlvnUEKXscwhUF5ZiBt8TwXYSu7s8Q==","shasum":"eda8e81347d974fbd4c0cc21430b51ee8991cfbf","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.53.tgz","fileCount":70,"unpackedSize":504950,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCw19gsV9CJOYfZ2+M+6qyMmiwqrrqDonBPtaFH/BNKEAIgWYIyV2jkl3IPrtVP8xv9eP/A+ORKcBp58qcr1pXlJhI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.53_1683622469664_0.6912203565347261"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.54":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.54","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.54+bc992263","@latticexyz/schema-type":"2.0.0-alpha.1.54+bc992263","@latticexyz/services":"2.0.0-alpha.1.54+bc992263","@latticexyz/solecs":"2.0.0-alpha.1.54+bc992263","@latticexyz/store":"2.0.0-alpha.1.54+bc992263","@latticexyz/utils":"2.0.0-alpha.1.54+bc992263","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"bc992263b26a0df4086975cc365ce9b6556e6c8c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.54","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-fRlQv1+JNownB1r65V1OM814JUjgwMacn88py7tSGl82kPVPmIc7/VTTImfAYsobK2vh4I6dZzkaLZpvzmg8yg==","shasum":"3f977f495507fe844ffaf9ce689867623f0879b4","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.54.tgz","fileCount":70,"unpackedSize":504950,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDmlJmGzyoYMnWrR/3E0DTv0N9qKmyAN3/0n2Oc7SDFoAIgPKZlL/cmwT2aHYwP1sdCoo4kXFIKuFkhiFGYLL0Fj5A="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.54_1683640643715_0.6441561556055695"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.55":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.55","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.55+78944976","@latticexyz/schema-type":"2.0.0-alpha.1.55+78944976","@latticexyz/services":"2.0.0-alpha.1.55+78944976","@latticexyz/solecs":"2.0.0-alpha.1.55+78944976","@latticexyz/store":"2.0.0-alpha.1.55+78944976","@latticexyz/utils":"2.0.0-alpha.1.55+78944976","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"789449762b39dd4a6c1eb9041caa28171833c6f2","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.55","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-JZ9KIv02VrHUtc3hZmziPaUbk6grYtrTgPWFspi3GYmSfrd6zhVRecTT12sqd6A1scPnsgVNgJEOrNUaUKqS3w==","shasum":"4716151e27b46a4e6268f111780e251e1d0b43c5","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.55.tgz","fileCount":70,"unpackedSize":504950,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFak/GitfCZdJMPfaK5wnp2dg5grDgsLGJ+0PsI1YJyLAiA2M1fN2zo6cilK/dm8ttQW5q/IXLuOIxCPokrI0wJySg=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.55_1683640760812_0.5087777689460995"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.56":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.56","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.56+a22850ff","@latticexyz/schema-type":"2.0.0-alpha.1.56+a22850ff","@latticexyz/services":"2.0.0-alpha.1.56+a22850ff","@latticexyz/solecs":"2.0.0-alpha.1.56+a22850ff","@latticexyz/store":"2.0.0-alpha.1.56+a22850ff","@latticexyz/utils":"2.0.0-alpha.1.56+a22850ff","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"a22850ff378b71dc12cfeba14e7d6b59f63451b7","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.56","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-IjGqSTEnm0eJ4s+XjlrqvS+P27Ql8sD0ExH2hoXYfaIz/N78a1+iSC3QC//3XpsYsjv7J1KIsS/rHZXztG548A==","shasum":"50259dd4bc1d1acc108f89cdff63148bb3b12169","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.56.tgz","fileCount":70,"unpackedSize":504950,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAdRgYTQ7TEd0OARIE/uwuty0tU6ch/Va4P2gIyxJdfWAiEA3sE8L72KZWEq+o8O6THhjnBF0bC0s/ww0lf0tYV4ufU="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.56_1683640918828_0.68947883962555"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.57":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.57","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.57+d29b0bbc","@latticexyz/schema-type":"2.0.0-alpha.1.57+d29b0bbc","@latticexyz/services":"2.0.0-alpha.1.57+d29b0bbc","@latticexyz/solecs":"2.0.0-alpha.1.57+d29b0bbc","@latticexyz/store":"2.0.0-alpha.1.57+d29b0bbc","@latticexyz/utils":"2.0.0-alpha.1.57+d29b0bbc","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"d29b0bbc3a5404e0242a5d13eb3901ca61943826","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.57","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-ENkB+52P+FbZ8hyvTLDLx/qDvH2kLQAiq+7ByECAUe8Nm3YmsNFGuzQDNJUuyv9QQWIp+lwQZINAPdIP+9g0Tg==","shasum":"8b77fe125253da33fbf7187714eedb953a9d3cd4","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.57.tgz","fileCount":70,"unpackedSize":504950,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCfdtLvRqGqRXK05RqKvL9YrycEYLL5TYeEgcq57FRnIwIhAJEmRePJZlWbyXFPv0Iwno8eiClaexJZGWrbAoeo2bYK"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.57_1683640996268_0.36696173909092966"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.58":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.58","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.58+33362e7a","@latticexyz/schema-type":"2.0.0-alpha.1.58+33362e7a","@latticexyz/services":"2.0.0-alpha.1.58+33362e7a","@latticexyz/solecs":"2.0.0-alpha.1.58+33362e7a","@latticexyz/store":"2.0.0-alpha.1.58+33362e7a","@latticexyz/utils":"2.0.0-alpha.1.58+33362e7a","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"33362e7af7f93e2d7590e9d219e1fdff5b711b6d","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.58","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-xzaNyOM3V00zoPkWzLEBvYtTAdTqi0/tl4yW61CT9m6sP8AtyAaXH4KjIFiEhaAsnkIbKPR46c2jGvGifUkrrQ==","shasum":"36aa7ea90d44eeccb9795a243fab741e58b94477","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.58.tgz","fileCount":70,"unpackedSize":504950,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFCs2fsv2a+7lH8M1a4FiXPRJVUVZrFlQe+P8XpflNiTAiAbmFQfhKTurk1AkMO+wBUPN6u5upiJLPp+zeiOIohG7Q=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.58_1683641921020_0.39594155073801107"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.59":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.59","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.59+adbb72bc","@latticexyz/schema-type":"2.0.0-alpha.1.59+adbb72bc","@latticexyz/services":"2.0.0-alpha.1.59+adbb72bc","@latticexyz/solecs":"2.0.0-alpha.1.59+adbb72bc","@latticexyz/store":"2.0.0-alpha.1.59+adbb72bc","@latticexyz/utils":"2.0.0-alpha.1.59+adbb72bc","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"adbb72bcedcbe432578c463f6d34113f37b7c0ef","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.59","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-sXM78G7kS3bFJsXY13ZGpBe80Cqe/buhRrJXvgIe+nAuLBS4s44MF39s6Vb5IzUJf+blPCCGXQDrql6CCPQO2g==","shasum":"f67252117fc5e3ae165ed96741eda000c744ce0d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.59.tgz","fileCount":70,"unpackedSize":504950,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCScxU/oRJxGlAM96d4fVRK+maF5PCSPHta9zD07897dwIgUnQ0Gf0TOeZyrNf/3rthGXrfFLNNmDunrmBXYzY5ZK8="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.59_1683653159115_0.39938025266216837"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.60":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.60","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.60+fbd0a1c8","@latticexyz/schema-type":"2.0.0-alpha.1.60+fbd0a1c8","@latticexyz/services":"2.0.0-alpha.1.60+fbd0a1c8","@latticexyz/solecs":"2.0.0-alpha.1.60+fbd0a1c8","@latticexyz/store":"2.0.0-alpha.1.60+fbd0a1c8","@latticexyz/utils":"2.0.0-alpha.1.60+fbd0a1c8","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"fbd0a1c84af91ee23e19e9a16963242f0cdc8901","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.60","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-qTUZpK1I34mj38pfVe0lLv6thKdNIlgCFLpF14f5uKLptQi/FlS7LzojOKDy8p3V/rQCCXh8GjKRuYHxPFFN6w==","shasum":"25f4d6d611b620754870dcd93c985364c7ee651c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.60.tgz","fileCount":70,"unpackedSize":504950,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGXpkVYbKeRk1lnAv9YEAk0PRrWCejg6dcWhbCNFKL3AAiEArIAE02WKM6ufbzNf4zvnpaaSFq9zjlcqtn8nvQfzSBM="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.60_1683668254047_0.3383289496276305"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.61":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.61","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js"},"types":"src/index.ts","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"debug":"^4.3.4","lodash":"^4.17.21"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.61+31628925","@latticexyz/schema-type":"2.0.0-alpha.1.61+31628925","@latticexyz/services":"2.0.0-alpha.1.61+31628925","@latticexyz/solecs":"2.0.0-alpha.1.61+31628925","@latticexyz/store":"2.0.0-alpha.1.61+31628925","@latticexyz/utils":"2.0.0-alpha.1.61+31628925","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5","viem":"^0.2.0"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.2.0"},"engines":{"node":">=18"},"gitHead":"31628925fdfb188d8f3a922542e4ad60f0937a5c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.61","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-A2PdkMf8C3FQ2wVIgT3o0lLdOvpRdBo9kiqule661CjBMhUkkmls7dLsvxYntjMx4UekK25apbf64nhK+kVFOQ==","shasum":"300e6227478c380771396abae3a4e398cbac7883","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.61.tgz","fileCount":70,"unpackedSize":504950,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHr4GPhGJDb2hoFum6/hwV59xOtGnPQESXqjyuzwbpaBAiEAzK0JXcofY8CSMH/ZyOlnWnhoYQrm4hQppgrn+P+uje4="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.61_1683734479165_0.9662665159981982"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.62":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.62","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@latticexyz/common":"2.0.0-alpha.1.62+37cbf72c","debug":"^4.3.4","lodash":"^4.17.21","viem":"^0.3.18"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.62+37cbf72c","@latticexyz/schema-type":"2.0.0-alpha.1.62+37cbf72c","@latticexyz/services":"2.0.0-alpha.1.62+37cbf72c","@latticexyz/solecs":"2.0.0-alpha.1.62+37cbf72c","@latticexyz/store":"2.0.0-alpha.1.62+37cbf72c","@latticexyz/utils":"2.0.0-alpha.1.62+37cbf72c","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"engines":{"node":">=18"},"gitHead":"37cbf72c4025a26774120fdbe03286a2af5a7ca4","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.62","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-AHtEMETGADNzwNq5LzK1lbEr4bC9lmiqtzMDMnfL2CNmycDiQcoRJKfm+ZICI7hMcVkHyvStqSTOPhVcTxsBmQ==","shasum":"9e07ea7ef696b55360c4b20f29c935d820a78ecc","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.62.tgz","fileCount":74,"unpackedSize":520711,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD/ID90ZbLNEZqVwa3rj9REFbnsa7vHtMc1u4goZZj0rQIhAMGPi/oSgSZ9CHA5fL7smyNuX5D+LNGjVe7jOIFwB5TO"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.62_1683737157383_0.8442756665495015"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.63":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.63","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@latticexyz/common":"2.0.0-alpha.1.63+158de9e8","debug":"^4.3.4","lodash":"^4.17.21","viem":"^0.3.18"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.63+158de9e8","@latticexyz/schema-type":"2.0.0-alpha.1.63+158de9e8","@latticexyz/services":"2.0.0-alpha.1.63+158de9e8","@latticexyz/solecs":"2.0.0-alpha.1.63+158de9e8","@latticexyz/store":"2.0.0-alpha.1.63+158de9e8","@latticexyz/utils":"2.0.0-alpha.1.63+158de9e8","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"engines":{"node":">=18"},"gitHead":"158de9e83ff4212e34c79b166d8336377972922f","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.63","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-wkuw9ZYARhd/fTZJWrXn7N/eZIvEslA5sQYQtw6GoAw4vq5R8d7UmsjTpNnljlVr/VoRk0Wf3RtkbHbqLKZVUQ==","shasum":"f8997a48ab8e564e117dcda83b6ae708f3639fcb","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.63.tgz","fileCount":74,"unpackedSize":520711,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAn6O7NKljhhb8W4DQcRPXRrQkDw5GhZVJmqtghYlwKFAiAEbSf3qhK+yewlgpYrRUzFm/Y5EjUKtA4Wae8AmCt9YA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.63_1683738196095_0.4322061034979192"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.64":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.64","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@latticexyz/common":"2.0.0-alpha.1.64+5d7fca32","debug":"^4.3.4","lodash":"^4.17.21","viem":"^0.3.18"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.64+5d7fca32","@latticexyz/schema-type":"2.0.0-alpha.1.64+5d7fca32","@latticexyz/services":"2.0.0-alpha.1.64+5d7fca32","@latticexyz/solecs":"2.0.0-alpha.1.64+5d7fca32","@latticexyz/store":"2.0.0-alpha.1.64+5d7fca32","@latticexyz/utils":"2.0.0-alpha.1.64+5d7fca32","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"engines":{"node":">=18"},"gitHead":"5d7fca3267d4b38eac61cf75c2d286711b482b3e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.64","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-X2b0Opo7SLiPnh+ASABS4EPyFvP42jhl0DbV+NexRV5mTdbr8uKoRZa8Qjh1YY7HZRn1vBVborf7hbMP8eYs3A==","shasum":"8f28167377282c3f1a29befac87e02016cedc716","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.64.tgz","fileCount":74,"unpackedSize":520711,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIANjtSuP7pb+EBOh0phNWiHg0hOPPV8PpOFKM7BS4SLtAiEA33nBvy+rg5mPQf7pHV91iVseAuqWQP+U0WD3k+j8GKk="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.64_1683738960396_0.8200850991643736"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.65":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.65","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@latticexyz/common":"2.0.0-alpha.1.65+86cdd1c5","debug":"^4.3.4","lodash":"^4.17.21","viem":"^0.3.18"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.65+86cdd1c5","@latticexyz/schema-type":"2.0.0-alpha.1.65+86cdd1c5","@latticexyz/services":"2.0.0-alpha.1.65+86cdd1c5","@latticexyz/solecs":"2.0.0-alpha.1.65+86cdd1c5","@latticexyz/store":"2.0.0-alpha.1.65+86cdd1c5","@latticexyz/utils":"2.0.0-alpha.1.65+86cdd1c5","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"latest","@latticexyz/schema-type":"latest","@latticexyz/services":"latest","@latticexyz/solecs":"latest","@latticexyz/store":"latest","@latticexyz/utils":"latest","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"engines":{"node":">=18"},"gitHead":"86cdd1c5b4cd45ac6930c90182f15fc47c209ce5","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.65","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-E3msG9kGoXdTdYNXfRtr+oBqz2VWjNHnJFIN1+yo/FiSennUpCjRpsc3B0VHZ/A6WEvwYeg/FDMNx21M/CwvRQ==","shasum":"ef669c946d1bdb9e42d36ee34a5b0b3d7f3e207d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.65.tgz","fileCount":74,"unpackedSize":520711,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHbhvoClJwNAvRAfEFSGN0hYX3GmukorRPStESxQzuLjAiA4tCkEHbvtKnEwxZ/EyCRLjirKyYnAs5seGTtazOLmeQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.65_1683740922617_0.04982310327020545"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.66":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.66","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@latticexyz/common":"2.0.0-alpha.1.66+8fe95ecd","debug":"^4.3.4","lodash":"^4.17.21","viem":"^0.3.18"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.66+8fe95ecd","@latticexyz/schema-type":"2.0.0-alpha.1.66+8fe95ecd","@latticexyz/services":"2.0.0-alpha.1.66+8fe95ecd","@latticexyz/solecs":"2.0.0-alpha.1.66+8fe95ecd","@latticexyz/store":"2.0.0-alpha.1.66+8fe95ecd","@latticexyz/utils":"2.0.0-alpha.1.66+8fe95ecd","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"*","@latticexyz/schema-type":"*","@latticexyz/services":"*","@latticexyz/solecs":"*","@latticexyz/store":"*","@latticexyz/utils":"*","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"engines":{"node":">=18"},"gitHead":"8fe95ecd2fbd7e4db8588b839240ef383814ae6d","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.66","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-BT+M5L4YuQGEFK4l7/8O/yWw6X5V+BfzzCV5RRmbGDIDdRTKb7np+g0QiNwfUXnCuc9ya7PtMAbjgyWrzFjs0A==","shasum":"e48f8fdd68c52ce347f7893d6aee5911036936fb","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.66.tgz","fileCount":74,"unpackedSize":520681,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDPDRqdsstZoVRMiReIja9juEpMe9f7I4K0EqrLYKwA4wIhAL+ZxvkH33PGbCFN6USZblbr0nW9qllByGPWfvDksizQ"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.66_1683748216419_0.14093407814523173"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.67":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.67","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@latticexyz/common":"2.0.0-alpha.1.67+ba3fbd27","debug":"^4.3.4","lodash":"^4.17.21","viem":"^0.3.18"},"devDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"2.0.0-alpha.1.67+ba3fbd27","@latticexyz/schema-type":"2.0.0-alpha.1.67+ba3fbd27","@latticexyz/services":"2.0.0-alpha.1.67+ba3fbd27","@latticexyz/solecs":"2.0.0-alpha.1.67+ba3fbd27","@latticexyz/store":"2.0.0-alpha.1.67+ba3fbd27","@latticexyz/utils":"2.0.0-alpha.1.67+ba3fbd27","@protobuf-ts/grpcweb-transport":"^2.7.0","@types/debug":"^4.1.7","@types/google-protobuf":"^3.15.6","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","async-mutex":"^0.3.2","ethers":"^5.7.2","fake-indexeddb":"^4.0.0","google-protobuf":"^3.21.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rimraf":"^3.0.2","rxjs":"^7.5.5","threads":"^1.7.0","ts-jest":"^29.0.5","tslib":"^2.5.0","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6","typescript":"^4.9.5"},"peerDependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/recs":"*","@latticexyz/schema-type":"*","@latticexyz/services":"*","@latticexyz/solecs":"*","@latticexyz/store":"*","@latticexyz/utils":"*","@protobuf-ts/grpcweb-transport":"^2.7.0","async-mutex":"^0.3.2","ethers":"^5.7.2","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","observable-webworker":"^4.0.1","rxjs":"^7.5.5","threads":"^1.7.0"},"engines":{"node":">=18"},"gitHead":"ba3fbd27ce1678dfa3f4893682803bc9a234c91e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.67","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-OdoQbV0gveK/Bw93n7VZDBvczH/tw0W0fdQj0L9SrAFUtxlGgG1UuiPnH0qbxbQlWrSAVWx/7p0GpaWVQe/YZg==","shasum":"27949827c01e6ff3ac5d1170bd052ca985f8516b","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.67.tgz","fileCount":74,"unpackedSize":520681,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDcciCI2AXylz+oFegdb7KfmjmCQeXEbGfN5YCIKVhWNQIgDdCwUDj65ORbKX5la8MxxY/67/KEDtbHFITgcQ2MM24="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.67_1683750254309_0.6079823240271061"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.68":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.68","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.68+ae4b0807","@latticexyz/recs":"2.0.0-alpha.1.68+ae4b0807","@latticexyz/schema-type":"2.0.0-alpha.1.68+ae4b0807","@latticexyz/services":"2.0.0-alpha.1.68+ae4b0807","@latticexyz/solecs":"2.0.0-alpha.1.68+ae4b0807","@latticexyz/store":"2.0.0-alpha.1.68+ae4b0807","@latticexyz/utils":"2.0.0-alpha.1.68+ae4b0807","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"ae4b08077ed7a288f8d70875e8c8265c61f09294","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.68","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-NF5TKiG1cWtjheP61scL5A13m3HRw273DXi922fKjI0QQN3Yl797e0nqBc1+5kpF1i8x6nFFEkxkAaLa9T6/5w==","shasum":"39e5f2abbb770bd870a3bd33b1d836517fb4a821","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.68.tgz","fileCount":74,"unpackedSize":519867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAyaQLy83bbnYOktxWDYIDSnoCIG5fDrLR8nmfXizWsLAiEAhyEGamEOtsm8zyavz78gMNAeQWiDEHVZfNCF9Ti6jsA="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.68_1683794452244_0.44524442135417397"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.69":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.69","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.69+fd3e946e","@latticexyz/recs":"2.0.0-alpha.1.69+fd3e946e","@latticexyz/schema-type":"2.0.0-alpha.1.69+fd3e946e","@latticexyz/services":"2.0.0-alpha.1.69+fd3e946e","@latticexyz/solecs":"2.0.0-alpha.1.69+fd3e946e","@latticexyz/store":"2.0.0-alpha.1.69+fd3e946e","@latticexyz/utils":"2.0.0-alpha.1.69+fd3e946e","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"fd3e946e45239922732600f0d23357a832c88f1c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.69","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-CgDxmtEcBUe4DJpOb8IdrFB7Yq0Tq8X44qvfKJU0iYcIriWrX+kUHXDqAtQsPasjGaqZ1ziJ0aUiOOdQxKlctg==","shasum":"b3f39c9e9ee1bf1866790b88a83fe22cdd4f7edf","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.69.tgz","fileCount":74,"unpackedSize":519867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCHzsVp9jX8rxdN4oGbsCa+SYxHXFhbDorgN9u2QeJAekCIQDyCO2RBINjLT0s8djL9oFS2ZgXTRXkQCQjBTSp1/FPhw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.69_1683795190667_0.07750045563625862"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.70":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.70","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.70+5613eb1d","@latticexyz/recs":"2.0.0-alpha.1.70+5613eb1d","@latticexyz/schema-type":"2.0.0-alpha.1.70+5613eb1d","@latticexyz/services":"2.0.0-alpha.1.70+5613eb1d","@latticexyz/solecs":"2.0.0-alpha.1.70+5613eb1d","@latticexyz/store":"2.0.0-alpha.1.70+5613eb1d","@latticexyz/utils":"2.0.0-alpha.1.70+5613eb1d","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5613eb1de73848a0a8881a2456767a851624aa6c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.70","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-aWA+3R2r1zfkA47oZ0SgA3BpsftR3NrzuW8d+0QUSMisDnXygVdZS2An2CDSXU3m5SGcIJgJrdTQciPRsLYm+A==","shasum":"8479f88fcead9d555eef1534e8ab3a20787ad46a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.70.tgz","fileCount":74,"unpackedSize":519867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH+r7g1+1HaLCtfNd8hRUXKvgK0oS0lFIkKkjMxnMMPlAiEA+VLcD8YJ6yXPj7xl+Olh/Z7qkiBL6hrtAQMeUJNH6aM="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.70_1683796340116_0.816905370961801"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.71":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.71","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.71+bc9803bb","@latticexyz/recs":"2.0.0-alpha.1.71+bc9803bb","@latticexyz/schema-type":"2.0.0-alpha.1.71+bc9803bb","@latticexyz/services":"2.0.0-alpha.1.71+bc9803bb","@latticexyz/solecs":"2.0.0-alpha.1.71+bc9803bb","@latticexyz/store":"2.0.0-alpha.1.71+bc9803bb","@latticexyz/utils":"2.0.0-alpha.1.71+bc9803bb","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"bc9803bba61e06f952358b7ecfe402a376362a9e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.71","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-ZDmVUXG2e1eLRem/vki+pkjqZ7oVUoLYWy0Wdf3UCEMyivjaI61sQXwkY+0eF/pyWvgpE1eqv+HSdPppkoj7lQ==","shasum":"3e9e0dd35b7e907371aff985db1676903754c78e","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.71.tgz","fileCount":74,"unpackedSize":519867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHhq5cbT2RPYhxgpCZBch8VG5P5gz0bEKXUnXjp+5yRoAiEAkVPuIBrH2gR9Ase4Rj3oPb4uy7fAaTj4FGNOd0NdBKw="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.71_1683797787209_0.4431062575715856"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.72":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.72","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.72+52e596d6","@latticexyz/recs":"2.0.0-alpha.1.72+52e596d6","@latticexyz/schema-type":"2.0.0-alpha.1.72+52e596d6","@latticexyz/services":"2.0.0-alpha.1.72+52e596d6","@latticexyz/solecs":"2.0.0-alpha.1.72+52e596d6","@latticexyz/store":"2.0.0-alpha.1.72+52e596d6","@latticexyz/utils":"2.0.0-alpha.1.72+52e596d6","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"52e596d646ce6ff963aa1de2545653f03f192f0c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.72","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-RNIwIle/dmbjU12W/u+4r16xMkhYZaGneBH6viPg1P1t0KuQsqB76GKMYuDGelA6eI8z0QOXApviqHmPGxS1xg==","shasum":"e7546082127451e91b59be004a300061082394dd","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.72.tgz","fileCount":74,"unpackedSize":519867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICirimyrfj4EwNuuCVat6jlpPbpTUnDp0ib/Ui747Za0AiEAgd0vGnQ+bmLq5FxuMuXA+r4Oib94IaCq1Gp/4MUiDBY="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.72_1683800019492_0.5426992252376099"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.73":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.73","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.73+7c21c036","@latticexyz/recs":"2.0.0-alpha.1.73+7c21c036","@latticexyz/schema-type":"2.0.0-alpha.1.73+7c21c036","@latticexyz/services":"2.0.0-alpha.1.73+7c21c036","@latticexyz/solecs":"2.0.0-alpha.1.73+7c21c036","@latticexyz/store":"2.0.0-alpha.1.73+7c21c036","@latticexyz/utils":"2.0.0-alpha.1.73+7c21c036","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"7c21c03602fec35271a3554d0bde5b475509f198","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.73","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-+tvbCaVxqMfWnjrjCTmtrNzXmk8pUpTV8fM9bG1WoVpBqDy7o+H1hgKf8eYfmldrIPHU3K1TX34WvoaZpDbzrg==","shasum":"0b3b9b00315ef3e36cec90a72202e8989017f84b","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.73.tgz","fileCount":74,"unpackedSize":519867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCfOMTGdQyQADK4aG+5E/tKSiXqIasL8No38grduy5+ZwIhAIhEFH0pEKkV71Kifh3/NK7MEBeXjKhC1eN1j8oOEwAa"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.73_1683800079096_0.9575262589758102"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.74":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.74","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.74+727201d2","@latticexyz/recs":"2.0.0-alpha.1.74+727201d2","@latticexyz/schema-type":"2.0.0-alpha.1.74+727201d2","@latticexyz/services":"2.0.0-alpha.1.74+727201d2","@latticexyz/solecs":"2.0.0-alpha.1.74+727201d2","@latticexyz/store":"2.0.0-alpha.1.74+727201d2","@latticexyz/utils":"2.0.0-alpha.1.74+727201d2","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"727201d2168b1db29169f2005ee705fe93db05f2","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.74","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-9LARAE8ibOjz1MpcTjiDtaBpdcO4BhsujnTrqq9svaCaigyh3yLh6AJHR2lJk9oRfjicDZeGCyq3YDsg/3jx+g==","shasum":"e3f0c94aec0efac5937ccadf1a82d52841a4f49e","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.74.tgz","fileCount":74,"unpackedSize":519867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDe11nPtIsV1TJEmO8j1w3gChV+YnEQ8r98hX0vwHsyBgIhAIDzF0Y+XWeUUWA4gUuJpRq/Yn/kEuLckn3KrpWPkK5X"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.74_1683801174375_0.11988216009049535"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.75":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.75","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.75+5062be64","@latticexyz/recs":"2.0.0-alpha.1.75+5062be64","@latticexyz/schema-type":"2.0.0-alpha.1.75+5062be64","@latticexyz/services":"2.0.0-alpha.1.75+5062be64","@latticexyz/solecs":"2.0.0-alpha.1.75+5062be64","@latticexyz/store":"2.0.0-alpha.1.75+5062be64","@latticexyz/utils":"2.0.0-alpha.1.75+5062be64","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5062be64b66683b14ba3126686dcbd3456d035b8","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.75","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-JMLEbuI5fPeNk5gizJxCwFFJ9DalAPx7acy0Y5zDbhpXlmTzAIUO/DJHR3g0f5cIiCsmG2wWe/uHwhtMgBe/PA==","shasum":"ad5c743b83c4df1b24f9dd1513c23c58772319e7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.75.tgz","fileCount":74,"unpackedSize":519867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD+uaIMfjso3amoNnYnLZaocfMkTvKSWPUcfsRLaY3GHAIhAOhNoSEFvj2Q8do60mhYkcHlExIhQuAkF4kpr5SjZ9HE"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.75_1683801242801_0.12107835586647742"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.76":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.76","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.76+5a07f4a8","@latticexyz/recs":"2.0.0-alpha.1.76+5a07f4a8","@latticexyz/schema-type":"2.0.0-alpha.1.76+5a07f4a8","@latticexyz/services":"2.0.0-alpha.1.76+5a07f4a8","@latticexyz/solecs":"2.0.0-alpha.1.76+5a07f4a8","@latticexyz/store":"2.0.0-alpha.1.76+5a07f4a8","@latticexyz/utils":"2.0.0-alpha.1.76+5a07f4a8","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5a07f4a8542bb044ffe9e14d67bddf9c947f4ea8","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.76","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-gBSDwfyMDjtbOXCGP+DXsRgEeUR06CqOvbCmfuAJN+w4G8ISPDynVQ62kUSopGgwnYHrXABzs7LEj1Xf+Pm8IA==","shasum":"974d03bc09ad7f6443f5fdc6261f88b16c2b9892","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.76.tgz","fileCount":74,"unpackedSize":519867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCdSM29ZKodHGAUKRXJbRifYN+97XsnuXU8SQNkZo2RqgIgRzngSm3ZxxwIjZQDaB1oVeXr78jOoDn3YvxaTjwV9R8="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.76_1683801578372_0.5326340174193702"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.77":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.77","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","release":"npm publish --access=public","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.77+263ca799","@latticexyz/recs":"2.0.0-alpha.1.77+263ca799","@latticexyz/schema-type":"2.0.0-alpha.1.77+263ca799","@latticexyz/services":"2.0.0-alpha.1.77+263ca799","@latticexyz/solecs":"2.0.0-alpha.1.77+263ca799","@latticexyz/store":"2.0.0-alpha.1.77+263ca799","@latticexyz/utils":"2.0.0-alpha.1.77+263ca799","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"263ca799fb35c9ca5f03e2aee10fc51bf2030637","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.77","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-P/3fmfUuYihsiPcpPhKgoElBZbFiX5gFOWIcqxDi1IsSf5TzlBr5ElNiO/4O9t+7Y2RKRYzXkEKX4I3Y/axMyA==","shasum":"b76ea890027550c1982bd1d3791d4e618c51f048","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.77.tgz","fileCount":74,"unpackedSize":519867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB8OMhmHYLsm49H+XfVRRjb2R+tUtrYvXzS8h2YYSnUmAiEAnVUzgllmAP0n/3YLJCyRibfIVne69MOcx2OzOoQN16g="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.77_1683801899640_0.08406515935317427"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.78":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.78","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.78+3079e4de","@latticexyz/recs":"2.0.0-alpha.1.78+3079e4de","@latticexyz/schema-type":"2.0.0-alpha.1.78+3079e4de","@latticexyz/services":"2.0.0-alpha.1.78+3079e4de","@latticexyz/solecs":"2.0.0-alpha.1.78+3079e4de","@latticexyz/store":"2.0.0-alpha.1.78+3079e4de","@latticexyz/utils":"2.0.0-alpha.1.78+3079e4de","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"3079e4de73039f54accb227c3e2d3f538cdbceb5","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.78","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-7JpnwqeEOnaREQZs2Ecygm8J/OhvuGFZqGVzvWh5D6u0TzbxEzXso7bI9L1aI5emtkw5YEg+m3gTqqtjHDQgaw==","shasum":"4ce3827a0ef1e86c7a9616c08118356d9c3e253c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.78.tgz","fileCount":74,"unpackedSize":519821,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAOIoHERUbN0fw8jAhNfFYmq1EVgD3yGX5I4VW9C1b2KAiA2zGmMm1Ic5YSAxjc6Q5oEXVjfGlMdr2VNci1RVlbzXQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.78_1683802808303_0.8540556286183063"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.79":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.79","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.79+4a240b0d","@latticexyz/recs":"2.0.0-alpha.1.79+4a240b0d","@latticexyz/schema-type":"2.0.0-alpha.1.79+4a240b0d","@latticexyz/services":"2.0.0-alpha.1.79+4a240b0d","@latticexyz/solecs":"2.0.0-alpha.1.79+4a240b0d","@latticexyz/store":"2.0.0-alpha.1.79+4a240b0d","@latticexyz/utils":"2.0.0-alpha.1.79+4a240b0d","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"4a240b0d76ece1bb41c81f6046c90330b35a3c9b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.79","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-DTmVgByut36FPEoSZGV9MouH+s4OIQfTkhu6W6wkfZqvRRiCgyjFUMpWUgIH4XU3L1wl7+79+wJCJwhbp9YOPw==","shasum":"663197ac33e7e25a48e0e2b07003ffb60e379e60","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.79.tgz","fileCount":74,"unpackedSize":519821,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDghHBvj/Z9Yaa/76GRp76pZjJWhHmw07yibdz+cijoxQIgLUyUjXCdFpg/QfrU/baEtQO6DmvjDyNEL7uV1kkN6Qg="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.79_1683808364680_0.7335180304669542"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.80":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.80","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.80+943e962f","@latticexyz/recs":"2.0.0-alpha.1.80+943e962f","@latticexyz/schema-type":"2.0.0-alpha.1.80+943e962f","@latticexyz/services":"2.0.0-alpha.1.80+943e962f","@latticexyz/solecs":"2.0.0-alpha.1.80+943e962f","@latticexyz/store":"2.0.0-alpha.1.80+943e962f","@latticexyz/utils":"2.0.0-alpha.1.80+943e962f","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"943e962f0380d629612c4b843d4dd22b9996c41f","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.80","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-GV7QIB+c9qaGVZSRnlj77bjWBPV/mvIQuS/I+gPirjBlO2hJHZZAzHi8dveCgrYQJ5YYw54Ou22wV41i8sxz6A==","shasum":"e4f28142073cca77552fb8df3b90f8b24a2166ba","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.80.tgz","fileCount":74,"unpackedSize":519821,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCJehgaEWEvKM1DpcbQh6ZFZtXOd98VjjUFfDs0kPR6+gIgGm/LKWDOBSH+HXZDnPSfpXlntu6ds/FknlWrn1w37QI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.80_1683813947568_0.6373573208573495"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.81":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.81","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.81+91c7571c","@latticexyz/recs":"2.0.0-alpha.1.81+91c7571c","@latticexyz/schema-type":"2.0.0-alpha.1.81+91c7571c","@latticexyz/services":"2.0.0-alpha.1.81+91c7571c","@latticexyz/solecs":"2.0.0-alpha.1.81+91c7571c","@latticexyz/store":"2.0.0-alpha.1.81+91c7571c","@latticexyz/utils":"2.0.0-alpha.1.81+91c7571c","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"91c7571cac24c7c3668115992cca35f1fcc3f213","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.81","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-sUpJCaobCJQK1ZJEOJXLSKD0P+kG9P+7d3iY4uaF+KM7/l1/ZLBMNO4z0V1DSgJXFMeMGMuCEpifDqnT+BCRrQ==","shasum":"5608e9ac13d9eab95b34f9a86535284e359c6f5f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.81.tgz","fileCount":74,"unpackedSize":519821,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH4XsL4pRmZ6BrUJkfxOBHKeOj9Y7+01wb2/mSOF5T6cAiB5O3Y4NTiwDzBnsvZQmHIvI/ffiWwjp9aWXQEEYrJrZQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.81_1683817254008_0.9813315458337575"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.82":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.82","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.82+c1fa59f5","@latticexyz/recs":"2.0.0-alpha.1.82+c1fa59f5","@latticexyz/schema-type":"2.0.0-alpha.1.82+c1fa59f5","@latticexyz/services":"2.0.0-alpha.1.82+c1fa59f5","@latticexyz/solecs":"2.0.0-alpha.1.82+c1fa59f5","@latticexyz/store":"2.0.0-alpha.1.82+c1fa59f5","@latticexyz/utils":"2.0.0-alpha.1.82+c1fa59f5","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"c1fa59f507a0ea18c118b948b8b22b44a1f52d8d","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.82","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-be/ECElWrsLdSYXoDIJIPJQ/Rks/UCpLm7pzC4CMz9AsearopaSPYx1ccK25e/9VZ2ZntU0HIuNQLXdSN1PGGQ==","shasum":"899d3f8523a3fb4c390518b7bd417cf95e59713b","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.82.tgz","fileCount":74,"unpackedSize":519821,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDaiQRoBjGvT7M4oio5hQHxSrweMqR5fkhlHJvoyqWkpwIgD1TdoH5MX/E9rK04q+EA1oLRYnnOqLg6X0871aBp/ic="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.82_1683820933015_0.1130473583386915"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.83":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.83","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.83+6c110dc8","@latticexyz/recs":"2.0.0-alpha.1.83+6c110dc8","@latticexyz/schema-type":"2.0.0-alpha.1.83+6c110dc8","@latticexyz/services":"2.0.0-alpha.1.83+6c110dc8","@latticexyz/solecs":"2.0.0-alpha.1.83+6c110dc8","@latticexyz/store":"2.0.0-alpha.1.83+6c110dc8","@latticexyz/utils":"2.0.0-alpha.1.83+6c110dc8","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"6c110dc8b1f55142b1ce5dae144ce10e25eb5308","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.83","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-48FHBfOHYd4zzlunfSRDP8EkGpSx72GE3+ZdN+JROtIGUmL3vMWhW+rd1ghKe8C5AoJmjFR3+gYsy34iFhFDcw==","shasum":"d9af2faa35e101107f6229d233cdc5169406183d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.83.tgz","fileCount":74,"unpackedSize":519821,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDS2LWKpMfSOfBqiywRuQLseKo674swA8pfw22pEzGQ/QIgSFNGgbgU3E36Djk0i6axL3HeCng0DyVTQ/ytTE1DuRs="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.83_1683847721899_0.8410667921405319"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.84":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.84","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.84+dc92ae75","@latticexyz/recs":"2.0.0-alpha.1.84+dc92ae75","@latticexyz/schema-type":"2.0.0-alpha.1.84+dc92ae75","@latticexyz/services":"2.0.0-alpha.1.84+dc92ae75","@latticexyz/solecs":"2.0.0-alpha.1.84+dc92ae75","@latticexyz/store":"2.0.0-alpha.1.84+dc92ae75","@latticexyz/utils":"2.0.0-alpha.1.84+dc92ae75","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"dc92ae75619127f32eb0cd8d4ddaeda1a477a89d","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.84","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-U6e9GyUa0M+RQbQngEXM/3UPr5LnuXSW7AtAcp8vuzlLhvGqkKfB8+KOLLzwcLGxmVHWiL5F95celoAusZtrRQ==","shasum":"a876470bfcd8c030a3c8329d7b8263e0563135e4","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.84.tgz","fileCount":74,"unpackedSize":519821,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCVIylkXNC9KQy/BNgR6j4z2Y/a0x3AAjDXh5tVs63SqwIgPPvFHf8NI4YP+7xGwxyHlGP2AhimTTCPaFuEzavBKrg="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.84_1683861224637_0.7553427370429919"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.85":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.85","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.85+04810bab","@latticexyz/recs":"2.0.0-alpha.1.85+04810bab","@latticexyz/schema-type":"2.0.0-alpha.1.85+04810bab","@latticexyz/services":"2.0.0-alpha.1.85+04810bab","@latticexyz/solecs":"2.0.0-alpha.1.85+04810bab","@latticexyz/store":"2.0.0-alpha.1.85+04810bab","@latticexyz/utils":"2.0.0-alpha.1.85+04810bab","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"04810babd9ee0d45f6db7b4b9608a4fa4548810e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.85","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-PaGfyxkZ9pZDLiVAvQgbzBc1gKSbmfK8RAKRqyfGe5Pr54FzxOyBxHw6KGogo5g/ep0R1HrcfGKp0tNuERRIiA==","shasum":"8cd8b52707151e9520f71dbabb1acfff08d1fafb","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.85.tgz","fileCount":74,"unpackedSize":516701,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB2wYtvkV03vnQzuaw1pZZapye8FNy7f932mDc+u2nEUAiBsShHhyEDRxDB8t6ejWHSPylm15iM2yhGrg5bpt58Ksw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.85_1683886635877_0.7602139032279134"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.86":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.86","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.86+a9070931","@latticexyz/recs":"2.0.0-alpha.1.86+a9070931","@latticexyz/schema-type":"2.0.0-alpha.1.86+a9070931","@latticexyz/services":"2.0.0-alpha.1.86+a9070931","@latticexyz/solecs":"2.0.0-alpha.1.86+a9070931","@latticexyz/store":"2.0.0-alpha.1.86+a9070931","@latticexyz/utils":"2.0.0-alpha.1.86+a9070931","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"a907093105ca6b6166b28f8d94d50ad7dde8365f","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.86","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-NDhDVDLLKX2HNTAJePtyL6P8SRgGPBd1M5Jy6oytMPBxrAYR02ghdwFaQR4cKzor+zjj7lUb/wpngwunhnJwbw==","shasum":"3e7bfa02c0a79324e03bca153ab6cc611f07be46","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.86.tgz","fileCount":74,"unpackedSize":516749,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDFJLJS7e5Uci/fwIH48HAbdyQEdvXze7OQOn/p48tWmwIhAJhuH1SNW7MWK9GsFrQvCjv2E77LHLnnPR6KnZJxMuCQ"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.86_1683887375346_0.31509520090726273"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.87":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.87","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.87+a4627ee6","@latticexyz/recs":"2.0.0-alpha.1.87+a4627ee6","@latticexyz/schema-type":"2.0.0-alpha.1.87+a4627ee6","@latticexyz/services":"2.0.0-alpha.1.87+a4627ee6","@latticexyz/solecs":"2.0.0-alpha.1.87+a4627ee6","@latticexyz/store":"2.0.0-alpha.1.87+a4627ee6","@latticexyz/utils":"2.0.0-alpha.1.87+a4627ee6","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"a4627ee6a2527373eefea6ba3cd2300fbd2af6f9","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.87","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-chNrSSwEBkEZvhY+1w/18mS9+58Et/o1RSOKjNBS5iEcx02BLp6mLheEWND94zEd06ZuQGKR+23tjvGWQCwAAA==","shasum":"9a3c2744741c7e276062202a2fed9d106afe5e5a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.87.tgz","fileCount":74,"unpackedSize":516749,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGHq5fOylbrUEutIZS0pa4P/VFenF2rUi9L7Qi7nnEuKAiEA3Mj/ZtsLbK86hf+AuHS6dkp04+99Uud+HUv657xQe2M="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.87_1683887412654_0.6450605589738143"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.88":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.88","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.88+9d2c1bcc","@latticexyz/recs":"2.0.0-alpha.1.88+9d2c1bcc","@latticexyz/schema-type":"2.0.0-alpha.1.88+9d2c1bcc","@latticexyz/services":"2.0.0-alpha.1.88+9d2c1bcc","@latticexyz/solecs":"2.0.0-alpha.1.88+9d2c1bcc","@latticexyz/store":"2.0.0-alpha.1.88+9d2c1bcc","@latticexyz/utils":"2.0.0-alpha.1.88+9d2c1bcc","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"9d2c1bcc90cee9476aa8e857d092aa3e391bde68","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.88","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-JmbEd0ZGMo6Yfc0Q2wE0KcBlY4XnNpnAkta8yeanWYnGWTJ6u1Dn75CFXqLOaidoVfIq1JM3p5qMoAlFJ5WBfw==","shasum":"85ec34a97affbc717f919465d83c071104c3bd7f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.88.tgz","fileCount":74,"unpackedSize":516749,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHdbsJLaXD7wnoRYab8eioASWFDMKtkr9FJRSwPK0LJ9AiEAwrVY6l7NdTvmNlVPI/4HfV9BmdxEfJInDwABkY5yHjw="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.88_1683901328370_0.1376339974062495"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.89":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.89","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.89+2d9bacf4","@latticexyz/recs":"2.0.0-alpha.1.89+2d9bacf4","@latticexyz/schema-type":"2.0.0-alpha.1.89+2d9bacf4","@latticexyz/services":"2.0.0-alpha.1.89+2d9bacf4","@latticexyz/solecs":"2.0.0-alpha.1.89+2d9bacf4","@latticexyz/store":"2.0.0-alpha.1.89+2d9bacf4","@latticexyz/utils":"2.0.0-alpha.1.89+2d9bacf4","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"2d9bacf467d948a8dde5b76fff248af3c711db2b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.89","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-KvFOPXJazU1ggHotSyGpgpWBYy27pKBgVCa/01dQd6IAkDcs0MW2v+sEZy8LBPHVL1tn3KJubg+FL7969LRHJQ==","shasum":"5746c20cae412370d79c951d78b08da3097adc72","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.89.tgz","fileCount":74,"unpackedSize":516749,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGDe4byUBkrliqcLZQRen5neJlvznnUEkQm9eC/LDQIxAiEAzuQgouZU4sevJX8MLqmisdfX1FjxBa0O/yVbVRnUiZc="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.89_1683904659059_0.9280002650336909"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.90":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.90","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.90+9493f30c","@latticexyz/recs":"2.0.0-alpha.1.90+9493f30c","@latticexyz/schema-type":"2.0.0-alpha.1.90+9493f30c","@latticexyz/services":"2.0.0-alpha.1.90+9493f30c","@latticexyz/solecs":"2.0.0-alpha.1.90+9493f30c","@latticexyz/store":"2.0.0-alpha.1.90+9493f30c","@latticexyz/utils":"2.0.0-alpha.1.90+9493f30c","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"9493f30c82b442fc0f3ca834543289be602a9c9f","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.90","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-Tf82nUV/ocuEQXRD+fNltvR3EZ0vnpsx8846DNgOQOs6p5+mnR+Y1qHM/g8Y6HKQssnGoWVcAsdf2lFTL5xQZw==","shasum":"f93e4d32890c400376843c8faef0718be2cb3c6f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.90.tgz","fileCount":74,"unpackedSize":517997,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCiEEd1rp0Gt8cRJYOHeqzd+/O3raQjqIn1bo+/NamUdwIhANmZnotT+LlQmStU9PmAC5GLULHGlRTkaUWIYZR6j5Kv"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.90_1683904951193_0.08026569514265325"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.91":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.91","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.91+1daed5a8","@latticexyz/recs":"2.0.0-alpha.1.91+1daed5a8","@latticexyz/schema-type":"2.0.0-alpha.1.91+1daed5a8","@latticexyz/services":"2.0.0-alpha.1.91+1daed5a8","@latticexyz/solecs":"2.0.0-alpha.1.91+1daed5a8","@latticexyz/store":"2.0.0-alpha.1.91+1daed5a8","@latticexyz/utils":"2.0.0-alpha.1.91+1daed5a8","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"1daed5a8e4121a14decbe8d3136e77aae8764312","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.91","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-liwi2Pkrawq5vQpnk6MrCN7DyVdG4Ya5IPrOIXZkAbqrTIm6SqkOECym7Os2m7LQacR/GtauNz9b/OT/wLWfog==","shasum":"79e2b36459e3c4722c90a196786ce31895752cfd","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.91.tgz","fileCount":74,"unpackedSize":517997,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHF6vqqo0wGhjWXHkv9xBo3GM2Wj45iNYpv0qpolHaHQAiEAi3VAdtDVobDtFPVVwu0xcS2job2/vKYg9fn04wh0310="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.91_1683905945357_0.5901630794368768"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.92":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.92","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.92+d4e62959","@latticexyz/recs":"2.0.0-alpha.1.92+d4e62959","@latticexyz/schema-type":"2.0.0-alpha.1.92+d4e62959","@latticexyz/services":"2.0.0-alpha.1.92+d4e62959","@latticexyz/solecs":"2.0.0-alpha.1.92+d4e62959","@latticexyz/store":"2.0.0-alpha.1.92+d4e62959","@latticexyz/utils":"2.0.0-alpha.1.92+d4e62959","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"d4e62959cecda21d6d1dedb6cdf35aa5f7e50445","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.92","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-vV67UoyVZJf7y6tS/7kDsO+rwi/MZYUusagYOKwaJKMy5f77OgzZGrYOF4mAxRoICckWGHx43/73SRxz/dn87w==","shasum":"e219cbd325576b0f23d9ead621000d70169dc862","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.92.tgz","fileCount":74,"unpackedSize":517997,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDZr+6TDR+vDuxReayqr8r0rgRyrWp/6PWDGDyLTjMUdAIhAK6KitzVU72XnEhrhh/MhrCho1P9hsuRwWhoQ8JxBdlu"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.92_1683929455995_0.1599291267295646"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.93":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.93","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.93+8c0b25f4","@latticexyz/recs":"2.0.0-alpha.1.93+8c0b25f4","@latticexyz/schema-type":"2.0.0-alpha.1.93+8c0b25f4","@latticexyz/services":"2.0.0-alpha.1.93+8c0b25f4","@latticexyz/solecs":"2.0.0-alpha.1.93+8c0b25f4","@latticexyz/store":"2.0.0-alpha.1.93+8c0b25f4","@latticexyz/utils":"2.0.0-alpha.1.93+8c0b25f4","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"8c0b25f48d70d62e2cb605c93a762f4b4ddd37ab","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.93","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-o5Zu1AAEl9u2oP4DZGFpaoqJJWlRlv0V9CfWsxmnJTMsfu5mGxLcajkm8fdyRquCYXjkLemWmUVKgZ5wiXX37w==","shasum":"174d9aba4aeaaac75c59ae7626d65b73b9ebcb26","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.93.tgz","fileCount":74,"unpackedSize":517997,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDyss8zdrwOsAGgrdhr5meiWtsIcdMSnqVI0KRnFy7L6gIgczwudP9f0AOpf7IaWDXl72PmvuQ5ctA2pf5ZoWD/eY0="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.93_1684026108508_0.4431702280645291"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.94":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.94","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.94+e6e3cc23","@latticexyz/recs":"2.0.0-alpha.1.94+e6e3cc23","@latticexyz/schema-type":"2.0.0-alpha.1.94+e6e3cc23","@latticexyz/services":"2.0.0-alpha.1.94+e6e3cc23","@latticexyz/solecs":"2.0.0-alpha.1.94+e6e3cc23","@latticexyz/store":"2.0.0-alpha.1.94+e6e3cc23","@latticexyz/utils":"2.0.0-alpha.1.94+e6e3cc23","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"e6e3cc236bdd9fb4f5c4a9dba8ebdd92a2916fb7","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.94","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-HOXRRhr9Vw+L6VFHe/QZ/pK/0u/0ZXB2LFfmDLYXOcR0HBshm+1V9H3mc7V3Ponb5UB7a5MbT7QBmp0cSOZvlQ==","shasum":"22a6f039415ebfc3d64b42df4a7052a9b4438185","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.94.tgz","fileCount":74,"unpackedSize":517997,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBxupQuLi6V3V+awqTxNpJvE7PpqjQRnTFwy2lRGtPkyAiEAn9EUeCLfAGYXsa73ksrYrKx6pqK98DKN8ggqCT2hkQI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.94_1684139138641_0.1936532208784072"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.95":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.95","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.95+9347a5fb","@latticexyz/recs":"2.0.0-alpha.1.95+9347a5fb","@latticexyz/schema-type":"2.0.0-alpha.1.95+9347a5fb","@latticexyz/services":"2.0.0-alpha.1.95+9347a5fb","@latticexyz/solecs":"2.0.0-alpha.1.95+9347a5fb","@latticexyz/store":"2.0.0-alpha.1.95+9347a5fb","@latticexyz/utils":"2.0.0-alpha.1.95+9347a5fb","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"9347a5fbed1c690b4b6717f83d2f7dfe811d98a7","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.95","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-d5p3EiRXDhOgQgy1QbkLGMPlgGfQHtjDaGX8kgQV3N1N9h0/P0ZidL88E2/c7Yv5ov4ihLaIX0T/yVS+MSX+JQ==","shasum":"5f87fa13fb969d80364efcd9b19eb132de231098","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.95.tgz","fileCount":74,"unpackedSize":517997,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHX5/OV39lEfDlHK5WQykZbj2QDa0kTGocz6Cj2DRKRUAiEAkgOgppJp/QHSZaBHdTTyLKvvCHYvwvHl8/nzWSribCA="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.95_1684139491828_0.31717203784447356"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.96":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.96","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.96+ebcae98c","@latticexyz/recs":"2.0.0-alpha.1.96+ebcae98c","@latticexyz/schema-type":"2.0.0-alpha.1.96+ebcae98c","@latticexyz/services":"2.0.0-alpha.1.96+ebcae98c","@latticexyz/solecs":"2.0.0-alpha.1.96+ebcae98c","@latticexyz/store":"2.0.0-alpha.1.96+ebcae98c","@latticexyz/utils":"2.0.0-alpha.1.96+ebcae98c","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"ebcae98c367221cbe3264af99596d8184c62d557","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.96","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-e7rR6vOsgnK5VQ0IVN84wZQtrg3fi0DoDeHLreYoT4LlOPVBGPo2JCd8S4qWkEIzxCvONWOrEzrdrLnUiZ6a/Q==","shasum":"58c98510b19f07c237f6252cd7ccd73930348a9e","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.96.tgz","fileCount":74,"unpackedSize":517997,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC1AoShNz96Tn2WJKR/XUM1Wl0M/7MaPsuoVQw/Gx6kZQIgQuqZS2vFBx5cIZ4PF+WKQX1glnSaSgcvvZRnE8YgO+Y="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.96_1684139549255_0.3123885599754965"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.97":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.97","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.97+bd928fc0","@latticexyz/recs":"2.0.0-alpha.1.97+bd928fc0","@latticexyz/schema-type":"2.0.0-alpha.1.97+bd928fc0","@latticexyz/services":"2.0.0-alpha.1.97+bd928fc0","@latticexyz/solecs":"2.0.0-alpha.1.97+bd928fc0","@latticexyz/store":"2.0.0-alpha.1.97+bd928fc0","@latticexyz/utils":"2.0.0-alpha.1.97+bd928fc0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"bd928fc0f51e4ef299ec75b791fdf49c9eab7bca","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.97","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-/jObtcbyAn1954EJjuqOxUvvi7m/ZosniwQ9FJGHrzeOmzGoDQkkbryUNlD8SInO3ec/fvmhOmipVnBuYS8fyg==","shasum":"8ebcf063aeb4644be9ce50e259d03197a6c6fbcd","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.97.tgz","fileCount":74,"unpackedSize":517997,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDJLOqQwyr7YU+xAc9mIgiNxTFXQukx2yrvzCTedk1/JQIhANi3bP44bJBuB65PLiVqjR48sAbYmKN3Yyyy6q7YtGmD"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.97_1684139717388_0.2025175751526911"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.98":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.98","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.98+ed5a7091","@latticexyz/recs":"2.0.0-alpha.1.98+ed5a7091","@latticexyz/schema-type":"2.0.0-alpha.1.98+ed5a7091","@latticexyz/services":"2.0.0-alpha.1.98+ed5a7091","@latticexyz/solecs":"2.0.0-alpha.1.98+ed5a7091","@latticexyz/store":"2.0.0-alpha.1.98+ed5a7091","@latticexyz/utils":"2.0.0-alpha.1.98+ed5a7091","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"ed5a70913f662dfdaa6ea7daf42f0cec3442a69d","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.98","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-06pGuTqlYoMEMkqm/WJlVqwDlbv4c1zmFIXcRge9bKTMvWdnKfOYi8VfNF9MXTxtt3Rt6ui5dXHmnEl8Zx/TPA==","shasum":"73998f1ca9c260a1fe2c607dc0696fb218e420bd","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.98.tgz","fileCount":74,"unpackedSize":517997,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDiqwf/B/uvusc7G039fyRWt5rkd9eFTolyZTB5EAFVjQIgITrIDgyceutZY2E7cFbUPe3L0UGeBgnkrpddHJY6NK0="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.98_1684139723283_0.3574752102712542"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.100":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.100","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.100+e321316f","@latticexyz/recs":"2.0.0-alpha.1.100+e321316f","@latticexyz/schema-type":"2.0.0-alpha.1.100+e321316f","@latticexyz/services":"2.0.0-alpha.1.100+e321316f","@latticexyz/solecs":"2.0.0-alpha.1.100+e321316f","@latticexyz/store":"2.0.0-alpha.1.100+e321316f","@latticexyz/utils":"2.0.0-alpha.1.100+e321316f","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"e321316f9a2e51f7b376b4481266be20d50d5573","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.100","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-DMMkrODbTRTw2cyGNQin9CouLx0pB3F1nUreOWiHF8EQ37YyrkQyfKNbQTzMMKENNXYg146kt17tO5ETOqczJw==","shasum":"dcdf1fbb17d2123ff8606cde6c796a474cca40d0","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.100.tgz","fileCount":74,"unpackedSize":518005,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHatRo6h2yqUQIGRKyd7byihzcL2iDni8nxgFKs7PGIPAiBILLApURSptlede1QmkMazRf+7u7/t+zVFRko9sKF3oA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.100_1684161375384_0.5558240052105003"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.101":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.101","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.101+5b9ec0ba","@latticexyz/recs":"2.0.0-alpha.1.101+5b9ec0ba","@latticexyz/schema-type":"2.0.0-alpha.1.101+5b9ec0ba","@latticexyz/services":"2.0.0-alpha.1.101+5b9ec0ba","@latticexyz/solecs":"2.0.0-alpha.1.101+5b9ec0ba","@latticexyz/store":"2.0.0-alpha.1.101+5b9ec0ba","@latticexyz/utils":"2.0.0-alpha.1.101+5b9ec0ba","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5b9ec0ba89621dd5c2c3a2e47755b602e158b7f5","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.101","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-7yHRxr6Mhrogb0Rz4EDQfj+Q92rPpspjx5GgK1FOa7d73amo6TdKqBha6+2Kjhnd+SJJkagAWjKmH/jvQ0wpdA==","shasum":"2f5680a5298b0e2d07dd08bad15f28eda281819d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.101.tgz","fileCount":74,"unpackedSize":518005,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFejxiHWLcqvn4Lv5xHH2WHemRWXc0bBBK5rSrelI3NjAiBTC8CqTUS4h59eSLNJGCecSqXAlMqEXI6oqgO7ACGLvw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.101_1684163383944_0.270476123562174"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.102":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.102","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.102+2d24c65e","@latticexyz/recs":"2.0.0-alpha.1.102+2d24c65e","@latticexyz/schema-type":"2.0.0-alpha.1.102+2d24c65e","@latticexyz/services":"2.0.0-alpha.1.102+2d24c65e","@latticexyz/solecs":"2.0.0-alpha.1.102+2d24c65e","@latticexyz/store":"2.0.0-alpha.1.102+2d24c65e","@latticexyz/utils":"2.0.0-alpha.1.102+2d24c65e","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"2d24c65eb4a0693e7b40f8b234527b6a57f5acb0","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.102","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-VbcsSsduZG7fMYuRgCPyu6G9hfz6ec/m/x2eUYhQYIkJ04J3TNyM21c0MTfV4/rBX/sHy8hCpYp4teKb3utCpw==","shasum":"9ba6436a8e32b556a5ba68a419ec89cb4fed4807","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.102.tgz","fileCount":74,"unpackedSize":518005,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFOWSEPRG+FW7/9tB6ifPVJWXhkBtu1Y21DRF23rXFNKAiASRrnat5FqLR8/xSdZjTCKUNXGvhA7MGZI4OgKRJG7JQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.102_1684168517411_0.18017388156488923"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.103":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.103","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.103+872fc732","@latticexyz/recs":"2.0.0-alpha.1.103+872fc732","@latticexyz/schema-type":"2.0.0-alpha.1.103+872fc732","@latticexyz/services":"2.0.0-alpha.1.103+872fc732","@latticexyz/solecs":"2.0.0-alpha.1.103+872fc732","@latticexyz/store":"2.0.0-alpha.1.103+872fc732","@latticexyz/utils":"2.0.0-alpha.1.103+872fc732","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"872fc73287574cf51c188552e1ce4b654f52f43a","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.103","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-2+y33rIdRQLW+/GaIUp9x2ndszEmrmdwJdKQarqaguoDMiFGD/xpcKhikILjGZimPjs3WWU20gdfzdo0WQkzdQ==","shasum":"4c9f7de13b9cee417b2d7c1e2b214069ba02e756","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.103.tgz","fileCount":74,"unpackedSize":468985,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCeG//mk1x8ZXF65ZmL6BENnvPLAMQ7WAukb81ntelAbwIhAK6WN5OD5QIolRmuWuVdDqnMZse4nG9XcVQMFDFoqiay"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.103_1684177345537_0.5486762580412152"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.104":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.104","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.104+eccf1cff","@latticexyz/recs":"2.0.0-alpha.1.104+eccf1cff","@latticexyz/schema-type":"2.0.0-alpha.1.104+eccf1cff","@latticexyz/services":"2.0.0-alpha.1.104+eccf1cff","@latticexyz/solecs":"2.0.0-alpha.1.104+eccf1cff","@latticexyz/store":"2.0.0-alpha.1.104+eccf1cff","@latticexyz/utils":"2.0.0-alpha.1.104+eccf1cff","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"eccf1cffd68bc6865207ce1db48960a402e7d95e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.104","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-MG7MEk7HIVTzu6bTUEiPwrcBv6g+xhOpGE1Y7QFHHR+0LY/oZspknV4Z3bgpacvfhV2lJP6Y9p0LXs4bkZ/Nyw==","shasum":"926ea88abadfa8a78f5b9c17b3f627f9da4ec86d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.104.tgz","fileCount":74,"unpackedSize":468985,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCQdy5hp8S9NZQ7l5twNRTGRA6fEEehXJ5xszImNOlfAAIhAIcEpvQzEwGgCGvSmUa40riGl4YRAEddwaqSJgJnO6yl"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.104_1684184068131_0.2068865243125777"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.105":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.105","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.105+843c663b","@latticexyz/recs":"2.0.0-alpha.1.105+843c663b","@latticexyz/schema-type":"2.0.0-alpha.1.105+843c663b","@latticexyz/services":"2.0.0-alpha.1.105+843c663b","@latticexyz/solecs":"2.0.0-alpha.1.105+843c663b","@latticexyz/store":"2.0.0-alpha.1.105+843c663b","@latticexyz/utils":"2.0.0-alpha.1.105+843c663b","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"843c663bb8f69e5aad5e84089fbe77e3f0f726b3","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.105","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-O8x26tqjTfx+A0k3MZK6vslU7V+SxWuo2rSXrN1w3EFoVaJfI1CSjhZsQvUV1GBjyg0E/qFSeJC1of5sINIHwA==","shasum":"83a0f14ee691ab5170e2f0be53092eda95f2041d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.105.tgz","fileCount":74,"unpackedSize":468985,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBOtauOMqnCLrIhvWbPqVdZqrC4kAKifz1LcVcPOTpsjAiEA9uvFPbC7/N+fBPjVKhvyrKOJZe07lOvk0/UV38OLu6M="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.105_1684186027963_0.7168608224842945"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.106":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.106","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.106+9e7c2477","@latticexyz/recs":"2.0.0-alpha.1.106+9e7c2477","@latticexyz/schema-type":"2.0.0-alpha.1.106+9e7c2477","@latticexyz/services":"2.0.0-alpha.1.106+9e7c2477","@latticexyz/solecs":"2.0.0-alpha.1.106+9e7c2477","@latticexyz/store":"2.0.0-alpha.1.106+9e7c2477","@latticexyz/utils":"2.0.0-alpha.1.106+9e7c2477","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"9e7c2477a951c790de10bfb6ac19eac056894784","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.106","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-Jdim9xV9XH1/8jARFAi8yd/+dizXrDl4QVgR9UT5dKsmAtsDCMs5FUq0RKgn1/8gBQ8+SKuyFz/mmjQJXbmCYg==","shasum":"692770481babb31604c71b1d585385d6ce6bb109","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.106.tgz","fileCount":74,"unpackedSize":468985,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGOlHeJQR/lf8MUIYno+RZVWxsVewwuJF6sMDmI1CTgyAiEA+7U3EQwBqdoRhV+sUd/GU9DTuFOY7Lb6Vf9adxw2qMs="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.106_1684229234902_0.18268228477417936"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.107":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.107","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.107+4dcb641c","@latticexyz/recs":"2.0.0-alpha.1.107+4dcb641c","@latticexyz/schema-type":"2.0.0-alpha.1.107+4dcb641c","@latticexyz/services":"2.0.0-alpha.1.107+4dcb641c","@latticexyz/solecs":"2.0.0-alpha.1.107+4dcb641c","@latticexyz/store":"2.0.0-alpha.1.107+4dcb641c","@latticexyz/utils":"2.0.0-alpha.1.107+4dcb641c","@latticexyz/world":"2.0.0-alpha.1.107+4dcb641c","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"4dcb641cc264190275972d6dd2cef6d134efb7d2","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.107","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-aYz1NfTn/afgT9m2tPYqQxHkjn53NA3Mgfp2CA2Jqg37IfGLmnVTsZqJo7cB/YKU8jB0E0TfFrqrAADVjTihHw==","shasum":"d3c3f775656f176b2014bac841368a7fed41053d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.107.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBa1OKwCkwmIUh16B3vsq3A/ZNFqrcgFYCpTEqit74nvAiEAs61c8AqiuqK0MNuF+vT7Rm7XmocmuBbGQhhgs+Aapb4="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.107_1684235433383_0.8526465006276389"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.108":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.108","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.108+48ce4195","@latticexyz/recs":"2.0.0-alpha.1.108+48ce4195","@latticexyz/schema-type":"2.0.0-alpha.1.108+48ce4195","@latticexyz/services":"2.0.0-alpha.1.108+48ce4195","@latticexyz/solecs":"2.0.0-alpha.1.108+48ce4195","@latticexyz/store":"2.0.0-alpha.1.108+48ce4195","@latticexyz/utils":"2.0.0-alpha.1.108+48ce4195","@latticexyz/world":"2.0.0-alpha.1.108+48ce4195","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"48ce419583dca8d33a20caf522dd19a06753c6a0","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.108","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-4u5uIPUUVsa6AspsFcvvth0gMAFRSy/y6oe0vSSLdwjhKqqps6pCBSMt60morfIlV63cw80oeAcvXkC7IMP2Cg==","shasum":"ecd4256ebab3a623dc8a7328b83ecf0b2a40f0ab","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.108.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDE41eI0aPK59irWusxrGeueAHa4Pkd4j2JL4pUlbfHXgIgCOmFRLraLMLgfrrZ3g31E9FewwK1WsKQtNi2sLg7q7g="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.108_1684241674327_0.18802420736161252"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.109":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.109","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.109+748105d2","@latticexyz/recs":"2.0.0-alpha.1.109+748105d2","@latticexyz/schema-type":"2.0.0-alpha.1.109+748105d2","@latticexyz/services":"2.0.0-alpha.1.109+748105d2","@latticexyz/solecs":"2.0.0-alpha.1.109+748105d2","@latticexyz/store":"2.0.0-alpha.1.109+748105d2","@latticexyz/utils":"2.0.0-alpha.1.109+748105d2","@latticexyz/world":"2.0.0-alpha.1.109+748105d2","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"748105d283de21a5c6de741480e4336a8add6ca6","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.109","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-2ojUSLWQKUmHIysTY/h48GZa9gM/1jH9Mof+BS3naYgYy6ZCz7TiZS8+rjdzVbqfJAlb8ehwxhj59qkbbMNWLg==","shasum":"299fc3d62ce50bdec4ff6b280159cfbbf13329d6","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.109.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFXgdMKEATFJaK0EgdUnlWHU3uOu1b5xRGyoDlc1IIivAiAs0jTeDlo6qk9LjXkZ6iEGEeyXq9DRkceHa36k5HQvyQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.109_1684244999110_0.29447030473062474"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.110":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.110","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.110+2ba2442c","@latticexyz/recs":"2.0.0-alpha.1.110+2ba2442c","@latticexyz/schema-type":"2.0.0-alpha.1.110+2ba2442c","@latticexyz/services":"2.0.0-alpha.1.110+2ba2442c","@latticexyz/solecs":"2.0.0-alpha.1.110+2ba2442c","@latticexyz/store":"2.0.0-alpha.1.110+2ba2442c","@latticexyz/utils":"2.0.0-alpha.1.110+2ba2442c","@latticexyz/world":"2.0.0-alpha.1.110+2ba2442c","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"2ba2442c574c26d5a42d5a6b4794492bb8b2f791","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.110","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-fcgAG6QHfzfMCibWCo0sWRSwp9h8ef82KKIdhUaxABrq72X+MyQumzmiVX3ZzUbcue7DIlnXGRoj9umiBUz+XQ==","shasum":"56534e811e5f18e41e17c58fbeb421a7e8e43e46","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.110.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHJLIaIn4KHjWnY7HaOYkIbovEZKvUyIhpTscBohLnwoAiA1oMWINuJGoqBv5vry5pVcgX7E1EwHisBtJJGGfw0goA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.110_1684245994811_0.4665561485234535"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.111":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.111","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.111+509d9158","@latticexyz/recs":"2.0.0-alpha.1.111+509d9158","@latticexyz/schema-type":"2.0.0-alpha.1.111+509d9158","@latticexyz/services":"2.0.0-alpha.1.111+509d9158","@latticexyz/solecs":"2.0.0-alpha.1.111+509d9158","@latticexyz/store":"2.0.0-alpha.1.111+509d9158","@latticexyz/utils":"2.0.0-alpha.1.111+509d9158","@latticexyz/world":"2.0.0-alpha.1.111+509d9158","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"509d9158752a2cb13309aa6a692dd588991ccb42","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.111","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-Uax92Hv6VwXPNQhVze0WBl2o/BjrUks/4wSJ1Uvaf1LVf2vwu22958GOBb/1lUIjuBqfThYrwp3ybx+Hz5a75w==","shasum":"e0f0e9a7d6fc8ebcd0ca2acec01f11585bc6b713","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.111.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCjmniZVo2THEL8K0z/LmntIiU1FzrDQtGmKQNTRGkWtgIhAOguaaYpwDBFW7/8Uz2jPYcJ0CZ/C9VAdGettDQ8zh4z"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.111_1684247865812_0.6372235349800162"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.112":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.112","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.112+23030e57","@latticexyz/recs":"2.0.0-alpha.1.112+23030e57","@latticexyz/schema-type":"2.0.0-alpha.1.112+23030e57","@latticexyz/services":"2.0.0-alpha.1.112+23030e57","@latticexyz/solecs":"2.0.0-alpha.1.112+23030e57","@latticexyz/store":"2.0.0-alpha.1.112+23030e57","@latticexyz/utils":"2.0.0-alpha.1.112+23030e57","@latticexyz/world":"2.0.0-alpha.1.112+23030e57","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"23030e5798738bd67f8c91029449a8a6c2de0485","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.112","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-Zv0tnZg9nKVEth3YfVaJjMAU9U9504leBnrdWCwfG8rblX6HwMJfJy282u70vNOxMrJDRHDaIQfoZexvoHfpyA==","shasum":"a95422f37b0c32996139eda8d018e777d11322da","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.112.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHr+Hgt+32UWv98kGvME3yrX2pi2XaWY1GKdJJsgx6uWAiEA1QOyzvMyX5E4r/d3TlkMNoCI+C6YPgGD+zj3h2ZHejI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.112_1684248141511_0.33524595627511045"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.113":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.113","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.113+461363f6","@latticexyz/recs":"2.0.0-alpha.1.113+461363f6","@latticexyz/schema-type":"2.0.0-alpha.1.113+461363f6","@latticexyz/services":"2.0.0-alpha.1.113+461363f6","@latticexyz/solecs":"2.0.0-alpha.1.113+461363f6","@latticexyz/store":"2.0.0-alpha.1.113+461363f6","@latticexyz/utils":"2.0.0-alpha.1.113+461363f6","@latticexyz/world":"2.0.0-alpha.1.113+461363f6","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"461363f61b8230fe911cc89a5a37c85cb8518f6b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.113","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-RcVEA8RMtHVps0LKM1oy/zavszfFCyJ35RwCZ+96aCjX2U/s0pPqHy1lKUtUeWSn8uShJR3szpYObUM634cSSg==","shasum":"80fff57ef4610487d344a8d69e88f0dc1b7d9c94","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.113.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDWeT9df83TpH8bAYxqX+/qlGQCLgbOLR33FoKGTMoWCQIhAKjfXjO4NMLgQdcTZ/BhqTjhfU1PAfYc/XfLjjNy7kgv"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.113_1684248272794_0.6463311409299093"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.114":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.114","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.114+91b37a44","@latticexyz/recs":"2.0.0-alpha.1.114+91b37a44","@latticexyz/schema-type":"2.0.0-alpha.1.114+91b37a44","@latticexyz/services":"2.0.0-alpha.1.114+91b37a44","@latticexyz/solecs":"2.0.0-alpha.1.114+91b37a44","@latticexyz/store":"2.0.0-alpha.1.114+91b37a44","@latticexyz/utils":"2.0.0-alpha.1.114+91b37a44","@latticexyz/world":"2.0.0-alpha.1.114+91b37a44","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"91b37a4414fb9730be1886bfbdf4352c37b70d1a","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.114","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-WKoTSUjnSENJj63FDc3OYfYD5j6lDVe0GOHNHGzPEjMHacw/3KrQsXxsHkyHl/YnBJ0G3bR8KpF9S33l0YGR6w==","shasum":"f63c615b4d732363db99a2c427f293c9df1c3825","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.114.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCC/NK1HbqoYFHsFbUvs+aMpHIAE0M26E/FbsxhJFv5EAIgdrF4/AhzLthZHYYwRPm18qRVWkAnJLwO6/P5mFccUqA="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.114_1684252872864_0.8892108000422212"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.115":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.115","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.115+3dd17edb","@latticexyz/recs":"2.0.0-alpha.1.115+3dd17edb","@latticexyz/schema-type":"2.0.0-alpha.1.115+3dd17edb","@latticexyz/services":"2.0.0-alpha.1.115+3dd17edb","@latticexyz/solecs":"2.0.0-alpha.1.115+3dd17edb","@latticexyz/store":"2.0.0-alpha.1.115+3dd17edb","@latticexyz/utils":"2.0.0-alpha.1.115+3dd17edb","@latticexyz/world":"2.0.0-alpha.1.115+3dd17edb","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"3dd17edb1d6d0fe1b41b004cc83261875c89508f","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.115","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-sckfUfbbOR8YUvv2mrmqE9q36NkMDVvbdxQnSWeMpTnxDbr3oKRuALjYVh7kFX9lJKVw30YrBNMiWVj7ZIR9Fg==","shasum":"1516d1fadb0fdcb30de536553b0dbd4c015de296","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.115.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC+wUm9jhUfp4++LjinrOt71UsBEff2unoF47KudbQxnwIgeWTEjf3GRgaNi5aFtXMB7hgoI0DUwQKL4Ux7qCVYe+Y="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.115_1684265227147_0.8861716834658453"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.116":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.116","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.116+475e632d","@latticexyz/recs":"2.0.0-alpha.1.116+475e632d","@latticexyz/schema-type":"2.0.0-alpha.1.116+475e632d","@latticexyz/services":"2.0.0-alpha.1.116+475e632d","@latticexyz/solecs":"2.0.0-alpha.1.116+475e632d","@latticexyz/store":"2.0.0-alpha.1.116+475e632d","@latticexyz/utils":"2.0.0-alpha.1.116+475e632d","@latticexyz/world":"2.0.0-alpha.1.116+475e632d","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"475e632d674f901100481536c96633317b318952","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.116","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-/iTpDPIcpU+GPrH3PTVvkIOzIaMI1XtYETkf6PPyklbCv+edK39piTPA+W4uHHnZQ/EgiQOsLKVX1sG4Z5E14w==","shasum":"bd2aab39dfe311a8060035bc15a3de69151d8b00","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.116.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDkD5EIt9k6/HkH7VS/7Dxr8VDCOQju+IVECOj4WK0jBQIgLu+wpimYX7kgv9qvTlhwEWaQV4GZLVmHlwcqm4xL6TM="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.116_1684269410221_0.9175414403496942"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.117":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.117","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.117+6db2181d","@latticexyz/recs":"2.0.0-alpha.1.117+6db2181d","@latticexyz/schema-type":"2.0.0-alpha.1.117+6db2181d","@latticexyz/services":"2.0.0-alpha.1.117+6db2181d","@latticexyz/solecs":"2.0.0-alpha.1.117+6db2181d","@latticexyz/store":"2.0.0-alpha.1.117+6db2181d","@latticexyz/utils":"2.0.0-alpha.1.117+6db2181d","@latticexyz/world":"2.0.0-alpha.1.117+6db2181d","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"6db2181d3335f95e0bb22c61f82dc5b6c5bbe7f3","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.117","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-JhaSfbLq31D8LpsHUtC2pVsexT2WOq/RRJDO90ooO2ZEwV4zrdT6RppJIvxzSEKz8zwU3iFm/+A3quqtTGSYfQ==","shasum":"11ff2d7272b0f98cd99303ae815791e6649dc8ae","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.117.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDpz/72q3vxZsJD2dA59PlxiFWOmOR+uJ4I3/mTZp71RAIhAKhwbc2EebWU7I/Qq7Op/oSTp+D41mF8a6vCAVKPrbGt"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.117_1684274828271_0.6200197709563411"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.118":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.118","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.118+b6ed145e","@latticexyz/recs":"2.0.0-alpha.1.118+b6ed145e","@latticexyz/schema-type":"2.0.0-alpha.1.118+b6ed145e","@latticexyz/services":"2.0.0-alpha.1.118+b6ed145e","@latticexyz/solecs":"2.0.0-alpha.1.118+b6ed145e","@latticexyz/store":"2.0.0-alpha.1.118+b6ed145e","@latticexyz/utils":"2.0.0-alpha.1.118+b6ed145e","@latticexyz/world":"2.0.0-alpha.1.118+b6ed145e","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"b6ed145eae9faf70322b9ae38d947bff5e988a72","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.118","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-QuQU250HEBTLe/2kFxdazZ3tsOnVX99nLJ9dwJKa+G9VBnpAhsJa7GTaArN59BKdXqHEi341+audLscbjnQczw==","shasum":"8a6090fcd74a3e01cfbb7a20b50c49c1066367d2","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.118.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDC1S/LGM0X0n1geyBuXzRedzFzrkVvdmkJ4po1u2+KMQIhAKQKtDh2nYy27mHAPkpGOVCyQWflXUY97u7RkQiKLckx"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.118_1684276477773_0.33878366535050053"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.120":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.120","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.120+a16a0d2c","@latticexyz/recs":"2.0.0-alpha.1.120+a16a0d2c","@latticexyz/schema-type":"2.0.0-alpha.1.120+a16a0d2c","@latticexyz/services":"2.0.0-alpha.1.120+a16a0d2c","@latticexyz/solecs":"2.0.0-alpha.1.120+a16a0d2c","@latticexyz/store":"2.0.0-alpha.1.120+a16a0d2c","@latticexyz/utils":"2.0.0-alpha.1.120+a16a0d2c","@latticexyz/world":"2.0.0-alpha.1.120+a16a0d2c","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"a16a0d2c67e035160d62d817f4abd46b292e0232","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.120","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-SDqasORI1pZ17RgiYFYlq+46dTLjjHwoAzyintvb6YNIiGIk5aL28X+Pc7QH4kGB1lPLRyVhxd/BwJjSYv7RoQ==","shasum":"9e65920db33255811293d6092a88262cd1d0a1c5","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.120.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDEDRMk9MZGU8wiaeqM/Psh/gN8YKBpgAXLJ6CBCC6TfgIhALwcH0YHsssQRD9QTmn/UVccVmEMtTQo94f2m7OwxB8d"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.120_1684280454114_0.9180061137578999"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.119":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.119","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.119+e84dc42a","@latticexyz/recs":"2.0.0-alpha.1.119+e84dc42a","@latticexyz/schema-type":"2.0.0-alpha.1.119+e84dc42a","@latticexyz/services":"2.0.0-alpha.1.119+e84dc42a","@latticexyz/solecs":"2.0.0-alpha.1.119+e84dc42a","@latticexyz/store":"2.0.0-alpha.1.119+e84dc42a","@latticexyz/utils":"2.0.0-alpha.1.119+e84dc42a","@latticexyz/world":"2.0.0-alpha.1.119+e84dc42a","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"e84dc42a7e649a58d3c4ab257c74bf1477f14600","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.119","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-hrndDQ7D408GjOVxZ1fUX4NcXg7U2s27GJ990XfqnSFUNFDzuXeVWt/REKJhIqNxABPLGvC27TjzklHzADNAUw==","shasum":"7dca363208edb4e42045f4f931e1a52fe4bc0699","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.119.tgz","fileCount":78,"unpackedSize":483990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDCv2xuHoDIgVd62ViWSpWz6KL65GxK9JgG7AkelHRXGAiBwArPtrYr658OZCfuAmecp/0lyWFXLyb7mFP+FXTd+QA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.119_1684280458986_0.24729712874978316"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.121":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.121","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.121+6426a941","@latticexyz/recs":"2.0.0-alpha.1.121+6426a941","@latticexyz/schema-type":"2.0.0-alpha.1.121+6426a941","@latticexyz/services":"2.0.0-alpha.1.121+6426a941","@latticexyz/solecs":"2.0.0-alpha.1.121+6426a941","@latticexyz/store":"2.0.0-alpha.1.121+6426a941","@latticexyz/utils":"2.0.0-alpha.1.121+6426a941","@latticexyz/world":"2.0.0-alpha.1.121+6426a941","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"6426a9414d1abf412db16f87fcd75d9eb0663a27","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.121","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-kj1e0NyHm3tvhHUfzHtMZmr6eZ1L+RGRRZohP1rx9Hs4jr/64INw/vIlGXVFAQxMFTZLQ4tg65OK5J83jlgkaQ==","shasum":"c1d1b0ff12bd00397040ba40ff73232acb69654d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.121.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDrOoD8hgC0MLDWK8VElr6ywxILkr5CyQEofJ+NCZxCTQIgRXHs5p8G444ZAytd3tTbR9VVCEhx1QiCM7Jae5OvDKI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.121_1684282241140_0.6053525512674163"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.122":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.122","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.122+186528cd","@latticexyz/recs":"2.0.0-alpha.1.122+186528cd","@latticexyz/schema-type":"2.0.0-alpha.1.122+186528cd","@latticexyz/services":"2.0.0-alpha.1.122+186528cd","@latticexyz/solecs":"2.0.0-alpha.1.122+186528cd","@latticexyz/store":"2.0.0-alpha.1.122+186528cd","@latticexyz/utils":"2.0.0-alpha.1.122+186528cd","@latticexyz/world":"2.0.0-alpha.1.122+186528cd","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"186528cdb0a44ea19996ac67f0a342a36a940127","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.122","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-ZbICK0DGnvSXBDBjy/FpnjYcMhJE/n8iNkknxuk5d8dH5ZNEJEHvgp2yHXEj9Vi+hgkrTiYDPtWZOgHOKfs5lA==","shasum":"91b7f9cdf536ea74648b814fb2923e94d662f2b8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.122.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGaDH+B8RJlS77pNM2cT4MZbUbgyPXvAfF13cVPHbSkAAiEAs5N/uEYb29Gnw7T6w9LVVqvd4SXJNRahRk3OwngMX4I="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.122_1684282401686_0.3645173477808057"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.125":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.125","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.125+1b4563ef","@latticexyz/recs":"2.0.0-alpha.1.125+1b4563ef","@latticexyz/schema-type":"2.0.0-alpha.1.125+1b4563ef","@latticexyz/services":"2.0.0-alpha.1.125+1b4563ef","@latticexyz/solecs":"2.0.0-alpha.1.125+1b4563ef","@latticexyz/store":"2.0.0-alpha.1.125+1b4563ef","@latticexyz/utils":"2.0.0-alpha.1.125+1b4563ef","@latticexyz/world":"2.0.0-alpha.1.125+1b4563ef","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"1b4563ef3c7a54cd773899994d2fde6496be0c82","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.125","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-rTw/O8dResT1WVhPApy6WJF9kx01nL1xZCMojvpT5+5KA78KKhEd4YV2KVTSYLJesE4xuKm/VNtMrTIshg9lSg==","shasum":"894103e281d0f7d0f32228d091003451e3a2c551","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.125.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDWuY0H91P7kgsKSJ3ZzGXOuCV9l+/uDz1juxpz4BGcSQIgZ3D7goMyPdNkheLcUETRZuGTAIQ/5TKx3bBp92OROKM="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.125_1684309854848_0.9420116654202433"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.126":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.126","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.126+7bd4cb4e","@latticexyz/recs":"2.0.0-alpha.1.126+7bd4cb4e","@latticexyz/schema-type":"2.0.0-alpha.1.126+7bd4cb4e","@latticexyz/services":"2.0.0-alpha.1.126+7bd4cb4e","@latticexyz/solecs":"2.0.0-alpha.1.126+7bd4cb4e","@latticexyz/store":"2.0.0-alpha.1.126+7bd4cb4e","@latticexyz/utils":"2.0.0-alpha.1.126+7bd4cb4e","@latticexyz/world":"2.0.0-alpha.1.126+7bd4cb4e","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"7bd4cb4eebad3a88bdc108c15adf88f014a32c72","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.126","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-kiu4jtbSPRH1DV4U2QEu97tOVmY3jBjoos1yAwkSvdAqd6uS25FsYntQe/Yl5PcV8lhpK0SVzy92lW9k8sWSjg==","shasum":"7b89291caa88f7583678d6f0d67a6d807b90ae25","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.126.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICcaHv0i3AKMUr0q4vCSffOLtWK62YEcvZSouRIwdkHvAiEA/nicmMVvhT1/XCfuSk1biQFDEB9DFgJUXYBA4Aqvm7I="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.126_1684319929668_0.6470525285972695"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.127":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.127","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.127+eb1c4c6d","@latticexyz/recs":"2.0.0-alpha.1.127+eb1c4c6d","@latticexyz/schema-type":"2.0.0-alpha.1.127+eb1c4c6d","@latticexyz/services":"2.0.0-alpha.1.127+eb1c4c6d","@latticexyz/solecs":"2.0.0-alpha.1.127+eb1c4c6d","@latticexyz/store":"2.0.0-alpha.1.127+eb1c4c6d","@latticexyz/utils":"2.0.0-alpha.1.127+eb1c4c6d","@latticexyz/world":"2.0.0-alpha.1.127+eb1c4c6d","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"eb1c4c6dafb7b0021477f59b98353ef01a41fa4f","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.127","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-lbNzWxrLFaMi6zMfUlEwSbsYoKPATdLVdrbpGbrF13AmUnj91bvaeuk2siv3395LuxmCboR0wB78KaR0MN2YIQ==","shasum":"96250b3c6ac62252f3e8d3533490cf1e52305c03","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.127.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHsKAqQ2KUftFvHpJMakn4Z8ewdKalix4bd7oZyhNV9fAiBAlh6Wmd9SHx5Eqbkt1voSHkUNetZU7FhQl82LFg5AHw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.127_1684319978671_0.9858295585309664"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.128":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.128","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.128+d3d1e7fc","@latticexyz/recs":"2.0.0-alpha.1.128+d3d1e7fc","@latticexyz/schema-type":"2.0.0-alpha.1.128+d3d1e7fc","@latticexyz/services":"2.0.0-alpha.1.128+d3d1e7fc","@latticexyz/solecs":"2.0.0-alpha.1.128+d3d1e7fc","@latticexyz/store":"2.0.0-alpha.1.128+d3d1e7fc","@latticexyz/utils":"2.0.0-alpha.1.128+d3d1e7fc","@latticexyz/world":"2.0.0-alpha.1.128+d3d1e7fc","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"d3d1e7fc5632d56a50ea7b68a75fee0947cb836a","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.128","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-UyUSpRo5J96tY6OmfRTbswi6UdlojK7KVahnqRR9lBGoYf044L/RLTV7h8ruwVB967GM0kdanHCFIUvaF/c80w==","shasum":"7286dd83c23137732e517d4ab304186daebb1dcf","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.128.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHzhaAbCKXOi4bnU1A+ScUVKCe4zZ/FpOyCNxAws4dV7AiAN7RgW6Ow5diF4IlT+YOBYSWSN9OAP1ywp/TGCFQ8MFw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.128_1684320179159_0.009538565529850995"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.129":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.129","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.129+0779a75b","@latticexyz/recs":"2.0.0-alpha.1.129+0779a75b","@latticexyz/schema-type":"2.0.0-alpha.1.129+0779a75b","@latticexyz/services":"2.0.0-alpha.1.129+0779a75b","@latticexyz/solecs":"2.0.0-alpha.1.129+0779a75b","@latticexyz/store":"2.0.0-alpha.1.129+0779a75b","@latticexyz/utils":"2.0.0-alpha.1.129+0779a75b","@latticexyz/world":"2.0.0-alpha.1.129+0779a75b","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"0779a75bc69f7a8d00adf2aebdcd9c7f3d6ac82c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.129","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-/P7fVZgHJ11uMRFTlF+XBgvfRjG3vM+Wf4HMnlL5oWbt9xWccTHMcuISzbdOUuw25hn0Gkspv5t9XV3WHvpayg==","shasum":"ca20481d05abf0ce533acfae0037dc0a985c4bc6","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.129.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDtaHncT5imDApzDXAhI9EhZgil6N3Yz1Z2KXkLmZ0kjgIgV1afDkr24397iBKHur1zsoY8V8z1g5JZ9YOvU9u6RxQ="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.129_1684320795004_0.9951086372045015"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.130":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.130","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.130+0cf99951","@latticexyz/recs":"2.0.0-alpha.1.130+0cf99951","@latticexyz/schema-type":"2.0.0-alpha.1.130+0cf99951","@latticexyz/services":"2.0.0-alpha.1.130+0cf99951","@latticexyz/solecs":"2.0.0-alpha.1.130+0cf99951","@latticexyz/store":"2.0.0-alpha.1.130+0cf99951","@latticexyz/utils":"2.0.0-alpha.1.130+0cf99951","@latticexyz/world":"2.0.0-alpha.1.130+0cf99951","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"0cf99951a8a1093f94afb82b59091ed9c3b4ca11","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.130","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-zzsF+ELCuUMbfQyyHr2j+EEGFDOU+EzqpUT5cZ0hNCfw1bq60TdGt2ujvTPDv7cnNRTEAuASLfNHB1C2wo6pmQ==","shasum":"36ca29511731d84f5506c3f4102ea67ede468e4a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.130.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIANNHEG4UBCXNY9GVaBUUW8nWJdPKq73Nf0Z+qePGjRKAiEAzXI3jAP6ZTyiBMGIQspuldO7U00QVzZ1s1cR9V+C+Xo="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.130_1684333127383_0.127273926665604"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.131":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.131","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.131+ba10d78b","@latticexyz/recs":"2.0.0-alpha.1.131+ba10d78b","@latticexyz/schema-type":"2.0.0-alpha.1.131+ba10d78b","@latticexyz/services":"2.0.0-alpha.1.131+ba10d78b","@latticexyz/solecs":"2.0.0-alpha.1.131+ba10d78b","@latticexyz/store":"2.0.0-alpha.1.131+ba10d78b","@latticexyz/utils":"2.0.0-alpha.1.131+ba10d78b","@latticexyz/world":"2.0.0-alpha.1.131+ba10d78b","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"ba10d78b5446041678c9ff280087523fb41107b9","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.131","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-Ht75LzC4JVZEOFPjIPQAYzI943dtrnRp2i9zAitJVt5rl5cGEyN6QL06XvgLg1Wr5dN2ocMHNC/Dj5qBM2BPjA==","shasum":"6d46d6d6bb58c207066cd68fc6199ed159d77ff2","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.131.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCLWbj+Uf3JW7XAjkXjI8st2x9LZbznBmNvu0Bp0GZN5QIgJFA4Gl8ekIHx/jGZOlQzxPMfxt59cOmXApKafgW0DFE="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.131_1684336438225_0.31105835443524965"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.132":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.132","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.132+47ab35d7","@latticexyz/recs":"2.0.0-alpha.1.132+47ab35d7","@latticexyz/schema-type":"2.0.0-alpha.1.132+47ab35d7","@latticexyz/services":"2.0.0-alpha.1.132+47ab35d7","@latticexyz/solecs":"2.0.0-alpha.1.132+47ab35d7","@latticexyz/store":"2.0.0-alpha.1.132+47ab35d7","@latticexyz/utils":"2.0.0-alpha.1.132+47ab35d7","@latticexyz/world":"2.0.0-alpha.1.132+47ab35d7","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"47ab35d746b174be806d633699e7ef7570052ce4","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.132","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-AdsqyavW3shHn8Ge/vk24N7YGz6kMSrcWengYTaCj7+wLtApnSdIkXDs17ig8THp+X2vB31titbWaIDjwoLcJA==","shasum":"36107556f9222968cce33640a0dcead3581abac4","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.132.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDOA50CVaA9RxUgDvi9/Ef6OKCO+yp3gU56AKic057bwgIhAOzioz0srXKdpMciVFmfV4TAZ/EThu/o4IiXBydoI/yq"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.132_1684340658847_0.3526416666968053"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.133":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.133","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.133+81be21a7","@latticexyz/recs":"2.0.0-alpha.1.133+81be21a7","@latticexyz/schema-type":"2.0.0-alpha.1.133+81be21a7","@latticexyz/services":"2.0.0-alpha.1.133+81be21a7","@latticexyz/solecs":"2.0.0-alpha.1.133+81be21a7","@latticexyz/store":"2.0.0-alpha.1.133+81be21a7","@latticexyz/utils":"2.0.0-alpha.1.133+81be21a7","@latticexyz/world":"2.0.0-alpha.1.133+81be21a7","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"81be21a79233efb7bf80bf089f5dc53a6cd9cebd","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.133","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-A3TSAJtMCT6/r4UZpHDwmm/6M8X2FQqWtSTxPUNxZglbeCOprB2rmyp4FoUN4dPG6iisox4cOKlYFTKkmobhZA==","shasum":"0ff8620b5851d5a5c6d59971e540930f75281aed","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.133.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDn54WuezNmG5qpmrD/DZDOpLokIiqUT2I3uL/RoemELgIge6JY1ye3WuDrU25d/0LSGEkzsA7KRtwD0YovEoqV9Zo="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.133_1684342574114_0.16468539613268396"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.134":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.134","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.134+7e7877f1","@latticexyz/recs":"2.0.0-alpha.1.134+7e7877f1","@latticexyz/schema-type":"2.0.0-alpha.1.134+7e7877f1","@latticexyz/services":"2.0.0-alpha.1.134+7e7877f1","@latticexyz/solecs":"2.0.0-alpha.1.134+7e7877f1","@latticexyz/store":"2.0.0-alpha.1.134+7e7877f1","@latticexyz/utils":"2.0.0-alpha.1.134+7e7877f1","@latticexyz/world":"2.0.0-alpha.1.134+7e7877f1","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"7e7877f101446acfb41e10b5c6d3807776a4c542","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.134","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-t9atbIharjUFJelOOwNU/nkHjZZ667KctT0ulIAvPWvnIEI6dlyTtuv96uNNmVTHRDMmaUgvRHIXCe/Q88yaZQ==","shasum":"18fce2b80321dc3ffc0c02055b56aac25367c3b6","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.134.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCP1bTG6ozkBfxmoZn4mpquc5sVaqOnCv277aWV8hE0MgIgGL3Xa7IL5bvCGvmRMMpG6ATopwS8/nIiRo5aT78Jh/8="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.134_1684342976654_0.5490804755277225"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.135":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.135","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.135+c06f531b","@latticexyz/recs":"2.0.0-alpha.1.135+c06f531b","@latticexyz/schema-type":"2.0.0-alpha.1.135+c06f531b","@latticexyz/services":"2.0.0-alpha.1.135+c06f531b","@latticexyz/solecs":"2.0.0-alpha.1.135+c06f531b","@latticexyz/store":"2.0.0-alpha.1.135+c06f531b","@latticexyz/utils":"2.0.0-alpha.1.135+c06f531b","@latticexyz/world":"2.0.0-alpha.1.135+c06f531b","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"c06f531b03eceb034c8fd4a0ac46bdc181ffa2d1","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.135","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-ZW8NePLUoM2aTNYDx+AwAwS/fzUUsrtC/+7GiXILKQvOcWi0+4seHf4vT4oCbHV6ywv7o++3bDsB+oFtKE2Vcg==","shasum":"00bd98e6c97b015672c07801524595e23181e776","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.135.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDk3UpshSo2+BRbdFKQdr4JbLGy92KplopbnRsCVbQ8fwIgBIdqTM+QA7dONo67NiOOY83I4q4JdPuFkcYR3Q0Ld/U="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.135_1684344660916_0.7799707526024782"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.136":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.136","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.136+14707f8a","@latticexyz/recs":"2.0.0-alpha.1.136+14707f8a","@latticexyz/schema-type":"2.0.0-alpha.1.136+14707f8a","@latticexyz/services":"2.0.0-alpha.1.136+14707f8a","@latticexyz/solecs":"2.0.0-alpha.1.136+14707f8a","@latticexyz/store":"2.0.0-alpha.1.136+14707f8a","@latticexyz/utils":"2.0.0-alpha.1.136+14707f8a","@latticexyz/world":"2.0.0-alpha.1.136+14707f8a","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"14707f8a19a71557cb43dd58d9df8909d4969000","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.136","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-Y+RQRrPwKsddmMTVJOgJ4/Lx3y9Q4pRI7cCz80ePqe31j5WUfiHQ0hLWei49aq/u8ErrotnLMrNjwEyHetRLWA==","shasum":"a1efead1ac5a0fabf4afba220ebc9dfd48150da1","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.136.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDIif2qoB5B6gRIFqTfA0Ei2hTsa9kLT+Lt2HLofWSojAIgc6JCh+AHreXHbKfpyokBNavm3yEm5JT2wDi/g4Fx5Wk="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.136_1684346428437_0.463292996586675"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.137":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.137","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.137+b3dea005","@latticexyz/recs":"2.0.0-alpha.1.137+b3dea005","@latticexyz/schema-type":"2.0.0-alpha.1.137+b3dea005","@latticexyz/services":"2.0.0-alpha.1.137+b3dea005","@latticexyz/solecs":"2.0.0-alpha.1.137+b3dea005","@latticexyz/store":"2.0.0-alpha.1.137+b3dea005","@latticexyz/utils":"2.0.0-alpha.1.137+b3dea005","@latticexyz/world":"2.0.0-alpha.1.137+b3dea005","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"b3dea005b19c7d5d248d4013e5992a73f3e0b29b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.137","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-OSnSmJbgKJtZH+hxhHtdPYP4oV1pKZKjyZOhxa7q41o59NysgSZr6Q1YdPdpmrE5e0TLDfiYBtaOzYdjiGVuog==","shasum":"03eafaa7f2db6548872cf353fed0a09d03e11d8c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.137.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHU99axthRudcADbyRuUOfYMe2FZbUf500GKYQKGM20/AiAPGrbcBKYR8MJcHdYo1+3Me5StY+o3ZUhxlfaj4i+5XA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.137_1684347062377_0.8114125337039881"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.138":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.138","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.138+e2081f63","@latticexyz/recs":"2.0.0-alpha.1.138+e2081f63","@latticexyz/schema-type":"2.0.0-alpha.1.138+e2081f63","@latticexyz/services":"2.0.0-alpha.1.138+e2081f63","@latticexyz/solecs":"2.0.0-alpha.1.138+e2081f63","@latticexyz/store":"2.0.0-alpha.1.138+e2081f63","@latticexyz/utils":"2.0.0-alpha.1.138+e2081f63","@latticexyz/world":"2.0.0-alpha.1.138+e2081f63","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"e2081f637269380148fcc586b326fecac269a7e7","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.138","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-xJacvnBdGOkaYG3E45QaGFozYfKMr3sVzBLrHc1fcgKZNiZqwu7kxwliRsgIcgr1zUG/s7ZNlFLWkTEdCm1lyA==","shasum":"636293a89db12059f17d2f31f2cfcda0b7cfe8fd","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.138.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDYcA7BdiCFIJnklLzXGoaAY16DKcLgbsPwv+Acdscf9AIgX3QSoiRtoT1QgARpw4x/JqP6lBXCvEncohJYX4yKxpo="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.138_1684352421288_0.3185749842625547"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.139":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.139","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.139+5caa5094","@latticexyz/recs":"2.0.0-alpha.1.139+5caa5094","@latticexyz/schema-type":"2.0.0-alpha.1.139+5caa5094","@latticexyz/services":"2.0.0-alpha.1.139+5caa5094","@latticexyz/solecs":"2.0.0-alpha.1.139+5caa5094","@latticexyz/store":"2.0.0-alpha.1.139+5caa5094","@latticexyz/utils":"2.0.0-alpha.1.139+5caa5094","@latticexyz/world":"2.0.0-alpha.1.139+5caa5094","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5caa50945a4081982f4506c50eb68c7e9ee48381","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.139","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-/gYfeccEoO62A54U/GOF5diqey7/jlCLHafnNjYHUP0g7nwpmWO5gVqtNR1WNTDa5eUUjK62DuN1hzL0xY+ZBw==","shasum":"e3791380a6d75aad3600c745cca3ad1459472073","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.139.tgz","fileCount":78,"unpackedSize":484872,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB64nOQuqongQBKUzqnwl8VoyZ00oZbX7P78TNJJyjlkAiEA6nsDEbRrGIXzhzpSLwsylYynGuV7M4QsVdhfodgrNLc="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.139_1684359486848_0.5824880760999653"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.140":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.140","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.140+b80aaf67","@latticexyz/recs":"2.0.0-alpha.1.140+b80aaf67","@latticexyz/schema-type":"2.0.0-alpha.1.140+b80aaf67","@latticexyz/services":"2.0.0-alpha.1.140+b80aaf67","@latticexyz/solecs":"2.0.0-alpha.1.140+b80aaf67","@latticexyz/store":"2.0.0-alpha.1.140+b80aaf67","@latticexyz/utils":"2.0.0-alpha.1.140+b80aaf67","@latticexyz/world":"2.0.0-alpha.1.140+b80aaf67","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"b80aaf67946212775e277e1bf342f135ee86c346","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.140","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-+cyGF3fW/+oS4gN5yALzWpIuzwg+AzUQCEHvQPjeBy3IQDPUeQzdNNp6LtmZ5thlaYx+wRkt/SJ6+9PII0nbdQ==","shasum":"8683508aa57d57df2e2cc7ae69c0461fc3cce8e9","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.140.tgz","fileCount":78,"unpackedSize":485143,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDnYq6gpq2qbsDDHRmNGLJ4umvaMheX6eyM2sh2GNKxxwIhAN62Fy0z7ldK3X8x23RuFqlgZGR6NlOJZbQnpW23Ir0P"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.140_1684362913043_0.9884438878017696"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.141":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.141","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.141+5841367c","@latticexyz/recs":"2.0.0-alpha.1.141+5841367c","@latticexyz/schema-type":"2.0.0-alpha.1.141+5841367c","@latticexyz/services":"2.0.0-alpha.1.141+5841367c","@latticexyz/solecs":"2.0.0-alpha.1.141+5841367c","@latticexyz/store":"2.0.0-alpha.1.141+5841367c","@latticexyz/utils":"2.0.0-alpha.1.141+5841367c","@latticexyz/world":"2.0.0-alpha.1.141+5841367c","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5841367c2e42861e7bae73a59d2384a7e41d92ae","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.141","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-4DdXF/o9vf4GkeArRUgEq9UJQLNimzqYxP+EB/kNYtNnje40aROW+Sjd+NUahQseRvdeaSTU5C4EBi1KcE5YVw==","shasum":"87f8f982a2f47efebe531a68453dd4bfa4b521a2","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.141.tgz","fileCount":78,"unpackedSize":485143,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHtxwdHAABbSv/faEWpt8dhkzoViOjUdj/AHbrMNcW+HAiAk5oOhI7KmKMS47r/JddSls0R2jhl+jlGrF8tRK/t5mA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.141_1684363029662_0.6133734663038863"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.142":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.142","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.142+113ce559","@latticexyz/recs":"2.0.0-alpha.1.142+113ce559","@latticexyz/schema-type":"2.0.0-alpha.1.142+113ce559","@latticexyz/services":"2.0.0-alpha.1.142+113ce559","@latticexyz/solecs":"2.0.0-alpha.1.142+113ce559","@latticexyz/store":"2.0.0-alpha.1.142+113ce559","@latticexyz/utils":"2.0.0-alpha.1.142+113ce559","@latticexyz/world":"2.0.0-alpha.1.142+113ce559","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"113ce559335cbc78f5669f8fb99b19a519275a00","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.142","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-D4aCsnLqQMf4xeUW4EpybShHEMbr6gEWebrZVoi/Pr0UXS4MGIhWLTuPoVQTMUkB6IyXaQnXozhFNV/hqYRFHA==","shasum":"519709faf4d00c4d55bd597fe8df67a839d12b04","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.142.tgz","fileCount":78,"unpackedSize":485143,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD+Q5TvUk3oahYIBTSu7IdpXu/NFC1iYBXz+wEanxFXQgIhAMteRwjxZWEMyUJnJEKPL8vm/TKDs75CGWlqNuIc8sb6"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.142_1684363859586_0.7687325949438641"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.143":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.143","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.143+5c1112ef","@latticexyz/recs":"2.0.0-alpha.1.143+5c1112ef","@latticexyz/schema-type":"2.0.0-alpha.1.143+5c1112ef","@latticexyz/services":"2.0.0-alpha.1.143+5c1112ef","@latticexyz/solecs":"2.0.0-alpha.1.143+5c1112ef","@latticexyz/store":"2.0.0-alpha.1.143+5c1112ef","@latticexyz/utils":"2.0.0-alpha.1.143+5c1112ef","@latticexyz/world":"2.0.0-alpha.1.143+5c1112ef","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5c1112efa7a4177070f1b8f0bb446543b9b32a63","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.143","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-tYrCygj33ItQmtQnP97b6nZ8bs2okxUxlC4e9DW3IsyZtWIbLP6k3dppM7H3PakmRIb7Vmwzb8E1QdFIhTPLWg==","shasum":"3e38b96f2f59d108d1621316bf9c8f1eecb3eb54","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.143.tgz","fileCount":78,"unpackedSize":485143,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCD2ST1zwwgd2t65jA64fcWRQR85j6S0QA++XXqyy7TSAIhAKlhvLV9xTo81lbHwAytfOF5HjObxftI/tdveych95Jo"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.143_1684372157689_0.22665373379478737"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.144":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.144","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.144+2fc44a6d","@latticexyz/recs":"2.0.0-alpha.1.144+2fc44a6d","@latticexyz/schema-type":"2.0.0-alpha.1.144+2fc44a6d","@latticexyz/services":"2.0.0-alpha.1.144+2fc44a6d","@latticexyz/solecs":"2.0.0-alpha.1.144+2fc44a6d","@latticexyz/store":"2.0.0-alpha.1.144+2fc44a6d","@latticexyz/utils":"2.0.0-alpha.1.144+2fc44a6d","@latticexyz/world":"2.0.0-alpha.1.144+2fc44a6d","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"2fc44a6d9e9de3358e36d4e019cf501e0b08ce11","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.144","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-N25oWqjoX7k7GErKYna/Clx9ODU61E2ORacsCyUfRkObppqABfYnhSUiWcK3sXMxn82GoiYyQY9hmUp6SEFOgg==","shasum":"fbb5ce854644af80eaaa142973d7751c560f138c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.144.tgz","fileCount":78,"unpackedSize":485143,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDC0PG+/dlT8yzYsq9Xm/1HIl3mGfAWW7H0sv2hiI5C2gIgE5Uix/7Rccn+mvWBdpTG4Pt3g8T3cT28LLuXb9UrwVg="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.144_1684372234868_0.42793191735803493"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.145":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.145","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.145+50e599cb","@latticexyz/recs":"2.0.0-alpha.1.145+50e599cb","@latticexyz/schema-type":"2.0.0-alpha.1.145+50e599cb","@latticexyz/services":"2.0.0-alpha.1.145+50e599cb","@latticexyz/solecs":"2.0.0-alpha.1.145+50e599cb","@latticexyz/store":"2.0.0-alpha.1.145+50e599cb","@latticexyz/utils":"2.0.0-alpha.1.145+50e599cb","@latticexyz/world":"2.0.0-alpha.1.145+50e599cb","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"50e599cb65887337b90943ad973d7ffcb2bccef1","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.145","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-8vgc5eBGdEtKURtjxoTbIo9FVDDAxmYzXX/vFhmbz+FQxr7B0IArfLoCEWIR4l1j3q/c5fMgJOuTH46Bn2lUrA==","shasum":"02371b5b35e22cdc68365fc6e03ce66b39af96c1","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.145.tgz","fileCount":78,"unpackedSize":485143,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDDlS3GFdinkXmkt4bp1twpspkFA0RuFlN7rYC5h4lOUAIhAJjKrhiBL1PmdZsksCDkQWmcuhoXN3GO+lQQHbycXTSl"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.145_1684372530637_0.8233231911855441"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.146":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.146","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.146+6b552aac","@latticexyz/recs":"2.0.0-alpha.1.146+6b552aac","@latticexyz/schema-type":"2.0.0-alpha.1.146+6b552aac","@latticexyz/services":"2.0.0-alpha.1.146+6b552aac","@latticexyz/solecs":"2.0.0-alpha.1.146+6b552aac","@latticexyz/store":"2.0.0-alpha.1.146+6b552aac","@latticexyz/utils":"2.0.0-alpha.1.146+6b552aac","@latticexyz/world":"2.0.0-alpha.1.146+6b552aac","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"6b552aac42eca128297c0d44b4bc20baead4aad5","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.146","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-mZlou9xzGKdm2kzl25RbmxjfaE/lcPdg9ZBWt0vymLU++u0zOJ1OLVpRaQW5Gdt5pOIax2+7q1xi0TQnRW4KUQ==","shasum":"3711ef01565f8bb4a6c7fb2ef2531e1da816e1af","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.146.tgz","fileCount":78,"unpackedSize":485143,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDpLAKfyzUDAPQR+kdbuOMR3E6SbxuF3eN4serZ35q6WgIhAIqplkInOalX8I751w95qfoWkEpT40BWL+okUF4iwRa6"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.146_1684372551569_0.9530569393031141"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.147":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.147","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.147+e4a5bc93","@latticexyz/recs":"2.0.0-alpha.1.147+e4a5bc93","@latticexyz/schema-type":"2.0.0-alpha.1.147+e4a5bc93","@latticexyz/services":"2.0.0-alpha.1.147+e4a5bc93","@latticexyz/solecs":"2.0.0-alpha.1.147+e4a5bc93","@latticexyz/store":"2.0.0-alpha.1.147+e4a5bc93","@latticexyz/utils":"2.0.0-alpha.1.147+e4a5bc93","@latticexyz/world":"2.0.0-alpha.1.147+e4a5bc93","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"e4a5bc93e9808852a1bb183b9d1dbde191c36653","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.147","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-8/moWZuepMTSImHxCohZAc+PSy5d5mkOd3r/RaHYgRK5oCN5v9AvqVE5Zc0OYwbjWe/4DpcS/CgyFjZjSZyaZw==","shasum":"3f86d5fdd5164e3f313fdba27956147feb3648de","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.147.tgz","fileCount":78,"unpackedSize":485143,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDpMQaFdAIMSvCAK3hgjblMbvJtpX4qCYToiD0YwH627wIgXs/t9+HhlI4lSB2a2M0IG6UUhvyRDQdG70waySq9Lk0="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.147_1684372703062_0.37344392189301945"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.148":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.148","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.148+85e38ba8","@latticexyz/recs":"2.0.0-alpha.1.148+85e38ba8","@latticexyz/schema-type":"2.0.0-alpha.1.148+85e38ba8","@latticexyz/services":"2.0.0-alpha.1.148+85e38ba8","@latticexyz/solecs":"2.0.0-alpha.1.148+85e38ba8","@latticexyz/store":"2.0.0-alpha.1.148+85e38ba8","@latticexyz/utils":"2.0.0-alpha.1.148+85e38ba8","@latticexyz/world":"2.0.0-alpha.1.148+85e38ba8","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"85e38ba818ca0d99c7b75650e8ff1939f8325af8","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.148","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-jof08DSXkzBK0T2LfWVcJL3aRIJ9IQssjwCBzMfnEr/KTQxnBIFVoVytCtG8GaPaPDMES0Vgc37YVetupS411g==","shasum":"67a3b48e882377d51c9c9e652c50b674d389e489","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.148.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHdjspuOUp74wI7zx9b4RnmnOpTVRHbs8RIxEhjhYztDAiBfy0qVyKopctkPKIs36u9ksvc+OJU7POIFFTFG0qzu3w=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.148_1684378680789_0.5180544372931655"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.149":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.149","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.149+024f6037","@latticexyz/recs":"2.0.0-alpha.1.149+024f6037","@latticexyz/schema-type":"2.0.0-alpha.1.149+024f6037","@latticexyz/services":"2.0.0-alpha.1.149+024f6037","@latticexyz/solecs":"2.0.0-alpha.1.149+024f6037","@latticexyz/store":"2.0.0-alpha.1.149+024f6037","@latticexyz/utils":"2.0.0-alpha.1.149+024f6037","@latticexyz/world":"2.0.0-alpha.1.149+024f6037","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"024f6037ad661a4100300674d6227e7da3e5548e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.149","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-bHINw1gfVnSE6VaVFyxAKbXLGYqyYsLPFMpkj/cCxRzbSgg04YVV5JloYYjwhXkPzzj4/A1oey3KJoY8bECnyQ==","shasum":"6490f10d91ba2254c233dd205511d308c7dc4721","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.149.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICVtoYUEiXtd2tQzziZCOSwbbJ8HuDzdcx+bucjm5rU8AiBepp6yPGMaVovBpeQCpF9RslgE4clLeWfwZzPAJMixUg=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.149_1684414472325_0.9232896397273582"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.150":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.150","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.150+91490577","@latticexyz/recs":"2.0.0-alpha.1.150+91490577","@latticexyz/schema-type":"2.0.0-alpha.1.150+91490577","@latticexyz/services":"2.0.0-alpha.1.150+91490577","@latticexyz/solecs":"2.0.0-alpha.1.150+91490577","@latticexyz/store":"2.0.0-alpha.1.150+91490577","@latticexyz/utils":"2.0.0-alpha.1.150+91490577","@latticexyz/world":"2.0.0-alpha.1.150+91490577","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"91490577e4541d572328d503c1417b442f05daa9","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.150","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-a24bracy5Yg4mKgWUFHOL9IQIBH1tteO6cIMEWRGaK1Lm4wr/oINwbvSmzOoOnMO+7aWMxHVcERIAFFYTchU6A==","shasum":"a1f721fae012ece323a5edc30252fd68b877ff79","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.150.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDtq9QryPftWokTsq7+lmKRQ/pPEyLUAD9Cfr+5kuveNwIhAIPlyeyz0XpaM3G1dFI2dM8Xw1o88ttfcH7ZzTTQmfbo"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.150_1684418324059_0.8504195405978228"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.151":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.151","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.151+daaee0a8","@latticexyz/recs":"2.0.0-alpha.1.151+daaee0a8","@latticexyz/schema-type":"2.0.0-alpha.1.151+daaee0a8","@latticexyz/services":"2.0.0-alpha.1.151+daaee0a8","@latticexyz/solecs":"2.0.0-alpha.1.151+daaee0a8","@latticexyz/store":"2.0.0-alpha.1.151+daaee0a8","@latticexyz/utils":"2.0.0-alpha.1.151+daaee0a8","@latticexyz/world":"2.0.0-alpha.1.151+daaee0a8","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"daaee0a81b32bd3cbbe822546be3ab3de6023807","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.151","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-JIexGdH7b9DmIx3CBrTaN6or7ZvJkNGWiLccTG23ltEYx1p+BNy3SPAD0AizOkhlNpNUyz3QQ6iOGxDNRseKSw==","shasum":"cb0966def4e8114d54da784e97bb640fe481b85c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.151.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICuKHRg58K+CThgV8P4TzEG3M5zJlxQEkjW/0vJ4+94nAiEAyXL511wzUKXfvjJK9Rdw/IxENaJdEcfUamzFFauCQVQ="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.151_1684420774818_0.5189233644624118"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.152":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.152","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.152+26ea0ce8","@latticexyz/recs":"2.0.0-alpha.1.152+26ea0ce8","@latticexyz/schema-type":"2.0.0-alpha.1.152+26ea0ce8","@latticexyz/services":"2.0.0-alpha.1.152+26ea0ce8","@latticexyz/solecs":"2.0.0-alpha.1.152+26ea0ce8","@latticexyz/store":"2.0.0-alpha.1.152+26ea0ce8","@latticexyz/utils":"2.0.0-alpha.1.152+26ea0ce8","@latticexyz/world":"2.0.0-alpha.1.152+26ea0ce8","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"26ea0ce81eb313224e73b194ad65bf66cd67ef54","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.152","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-6EPSG49Y1TKIjqc8NRLSS0dDpXKovWIkJmW+n2HZNBOQ3T2ZOT4j9OXJRiTvjckxT/i50Rf/11Y3+ZAyJJVtNA==","shasum":"4f000888e9ae862f6f49b875769a6d53131e0022","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.152.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDIcaN61iczJYpmP4R7pQKXQu96ppLruDyb1Q3fonL9hQIhAOlCShZ1sBS2m24xlrUNIC+EmlwG//r08LrOjw0XWObD"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.152_1684422851311_0.38000712174664075"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.153":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.153","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.153+17446d7b","@latticexyz/recs":"2.0.0-alpha.1.153+17446d7b","@latticexyz/schema-type":"2.0.0-alpha.1.153+17446d7b","@latticexyz/services":"2.0.0-alpha.1.153+17446d7b","@latticexyz/solecs":"2.0.0-alpha.1.153+17446d7b","@latticexyz/store":"2.0.0-alpha.1.153+17446d7b","@latticexyz/utils":"2.0.0-alpha.1.153+17446d7b","@latticexyz/world":"2.0.0-alpha.1.153+17446d7b","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"17446d7b0ebac4ce4c9982cdb0e9fd4c43bf54b7","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.153","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-sPm6vZAixFW+gWsEUErGiN2jhssg3MU1wRpmotqqXIEkge/2ujyS0/m9vB2GkfRLylW8CQmPdMft5tg36Yd2+A==","shasum":"4ff08971bac81a2fe7298854d520f34392f49dac","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.153.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDWR2btrsmNdJfexc8mP1CAiVyXwDNyRfJYUPlYx9p3YwIgCucIMAyyKjbGEdGWa2B0UM9yER+I3tAfHM/eGyvtiK8="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.153_1684424462992_0.0682762123511691"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.154":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.154","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.154+3311faf8","@latticexyz/recs":"2.0.0-alpha.1.154+3311faf8","@latticexyz/schema-type":"2.0.0-alpha.1.154+3311faf8","@latticexyz/services":"2.0.0-alpha.1.154+3311faf8","@latticexyz/solecs":"2.0.0-alpha.1.154+3311faf8","@latticexyz/store":"2.0.0-alpha.1.154+3311faf8","@latticexyz/utils":"2.0.0-alpha.1.154+3311faf8","@latticexyz/world":"2.0.0-alpha.1.154+3311faf8","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"3311faf84b6ae6c0307a1ba446d5abd024aa6847","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.154","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-XiIDIHH3pt6Hf5miAKtvWXpDRd9RillqZcnyoo/ZqHZ+ELNaTaWz6wHZaFzrUpU1rBKvyGr8xffume8R9LA8kw==","shasum":"a5f674b85094e610448436145da23a02027f095a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.154.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDYHHwc9OPk7qmTJLuQcfT1/TatorEvkzLioj1R7MdbtAiEA5idl44Gb2O4oPmSmr2pc7286q6EUdjERrCUO/0jrZrc="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.154_1684425321949_0.4737615483772224"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.155":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.155","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.155+d3823203","@latticexyz/recs":"2.0.0-alpha.1.155+d3823203","@latticexyz/schema-type":"2.0.0-alpha.1.155+d3823203","@latticexyz/services":"2.0.0-alpha.1.155+d3823203","@latticexyz/solecs":"2.0.0-alpha.1.155+d3823203","@latticexyz/store":"2.0.0-alpha.1.155+d3823203","@latticexyz/utils":"2.0.0-alpha.1.155+d3823203","@latticexyz/world":"2.0.0-alpha.1.155+d3823203","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"d38232032b86d3dbccc00ffc23f6eee4e93c7732","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.155","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-tQBe6w4tsi8or928vhHq/DiDSlIhEGv/nVLrh2fPzuR9V1+Qa292U+P0Y2nuHvOwvzU3V7WCijqMGV9syqnRwA==","shasum":"798a1410b4adc38b184328b81769ee21015130b7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.155.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGzc3uh7uuwm5jiOaaZPWKpQJ90bwfqfTe711JWg9j2uAiBAdIZ80sh4BHM/us1TmGCxpbugCPDj8Gk/foflbSCAPg=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.155_1684427818223_0.009302136343259049"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.156":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.156","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.156+b196a143","@latticexyz/recs":"2.0.0-alpha.1.156+b196a143","@latticexyz/schema-type":"2.0.0-alpha.1.156+b196a143","@latticexyz/services":"2.0.0-alpha.1.156+b196a143","@latticexyz/solecs":"2.0.0-alpha.1.156+b196a143","@latticexyz/store":"2.0.0-alpha.1.156+b196a143","@latticexyz/utils":"2.0.0-alpha.1.156+b196a143","@latticexyz/world":"2.0.0-alpha.1.156+b196a143","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"b196a143a93a5cb2c1268aad490de989e7099298","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.156","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-0W33MJY673mYf/IwLczULa85at8SX8kWsOpeGjqyz+30pY1g0CIYUqkEYjpScFK8UovVW/914NXQfqwPI3Aacg==","shasum":"c4604f663e1cc441fafeb92b4f31850b7e2999f1","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.156.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHYb5C3WYz8Jl+JYAsnQoLyDQ+iUppa87EUceReYdFjrAiEAxjLaS57/vHuTERasjd/V4R3cKJHuPNeNS1JSB22oWUI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.156_1684429843251_0.7409198871801781"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.157":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.157","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.157+54e39586","@latticexyz/recs":"2.0.0-alpha.1.157+54e39586","@latticexyz/schema-type":"2.0.0-alpha.1.157+54e39586","@latticexyz/services":"2.0.0-alpha.1.157+54e39586","@latticexyz/solecs":"2.0.0-alpha.1.157+54e39586","@latticexyz/store":"2.0.0-alpha.1.157+54e39586","@latticexyz/utils":"2.0.0-alpha.1.157+54e39586","@latticexyz/world":"2.0.0-alpha.1.157+54e39586","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"54e395866574f993463f5fffbf295a1314254b93","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.157","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-DFUejKbWiRwCIPTyGwrWYWFaPqFqUkqsD6oirqOXZT3QIsf+5EK9aEm+9wAxpqBnL2hfsix0ibhA1olIy/1Wjg==","shasum":"4a293b2314aa290f0fc622f0b00d648786f73ded","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.157.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD+E02A/fnetrgSoDZoYT62Eh/YQTZTpZaH7MHXAASUjgIgRNZbPHKNrRCfG8QMH8w/3itE9dsYSbfc+fl+L6puZt8="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.157_1684430570703_0.20377490249962693"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.158":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.158","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.158+7f706c4c","@latticexyz/recs":"2.0.0-alpha.1.158+7f706c4c","@latticexyz/schema-type":"2.0.0-alpha.1.158+7f706c4c","@latticexyz/services":"2.0.0-alpha.1.158+7f706c4c","@latticexyz/solecs":"2.0.0-alpha.1.158+7f706c4c","@latticexyz/store":"2.0.0-alpha.1.158+7f706c4c","@latticexyz/utils":"2.0.0-alpha.1.158+7f706c4c","@latticexyz/world":"2.0.0-alpha.1.158+7f706c4c","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"7f706c4ccdb624557c3b16ba21c1c258924e13ac","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.158","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-3AE+9/StU3/V0SLh3ygyzMjwPYKgxFtGNKELSYfgKF1Y5eYcXd2Tmdn58XCyZdurmEUkoG9zaSvFxJmtR2yRFw==","shasum":"29d23b0d318a68dd0abfb95e66bd506803377dc0","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.158.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC1ccw6E6uiHkDkdk11H0SYHCYEn7QvFKXImIAf7mblvgIgFxniwT08tgjGcYBY5mrWxb6VFFjqVqJe1AOZ2r+44Lg="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.158_1684431041275_0.6666644362157395"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.159":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.159","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.159+59588ab6","@latticexyz/recs":"2.0.0-alpha.1.159+59588ab6","@latticexyz/schema-type":"2.0.0-alpha.1.159+59588ab6","@latticexyz/services":"2.0.0-alpha.1.159+59588ab6","@latticexyz/solecs":"2.0.0-alpha.1.159+59588ab6","@latticexyz/store":"2.0.0-alpha.1.159+59588ab6","@latticexyz/utils":"2.0.0-alpha.1.159+59588ab6","@latticexyz/world":"2.0.0-alpha.1.159+59588ab6","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"59588ab6ff1d68f69cc8dcc4126f9c64deee723c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.159","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-ht8q9QrDzCUHxKhQLdBppctY5XUbyCSSG4yz1kQhUk9AmUQ9mMFqbSc7Y1SWoxJ5e2RjxrDyv0qlKaT66Jtkow==","shasum":"5b898897c2e7cd295dd5658cfddee8328ef00050","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.159.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCOVLZNfcpICXVLCdidghut8sjiwjxCMkU30WrwAWH8awIgBEB5v5U1VVO8uFgi5YXYbKGb/2TcidKnUiRA4auEzm8="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.159_1684432491938_0.05413250711191031"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.160":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.160","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.160+cadd06f2","@latticexyz/recs":"2.0.0-alpha.1.160+cadd06f2","@latticexyz/schema-type":"2.0.0-alpha.1.160+cadd06f2","@latticexyz/services":"2.0.0-alpha.1.160+cadd06f2","@latticexyz/solecs":"2.0.0-alpha.1.160+cadd06f2","@latticexyz/store":"2.0.0-alpha.1.160+cadd06f2","@latticexyz/utils":"2.0.0-alpha.1.160+cadd06f2","@latticexyz/world":"2.0.0-alpha.1.160+cadd06f2","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"cadd06f2aaf1a742e663df0ec94d86e63cb0d413","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.160","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-3QOn/q0XkZBsjjs0TCDbshv0ekIsvxmpcaO1HOz55alDixXnXz//2wm3Ccb+cD1dLmVXpX/pXMEEkICBS7YFQg==","shasum":"554b279fe6cf858d239773a220b96815b4ef4535","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.160.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGnAnDjlpAlwyxvtus3EzJMenPaZVmwc9UrSX4iNufUPAiAN/z2VCk/8RxX+GXZvZWV6zl/PqFx+1vehg/xJ0jOGKw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.160_1684434299262_0.029555094092274414"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.161":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.161","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.161+cd7b89c4","@latticexyz/recs":"2.0.0-alpha.1.161+cd7b89c4","@latticexyz/schema-type":"2.0.0-alpha.1.161+cd7b89c4","@latticexyz/services":"2.0.0-alpha.1.161+cd7b89c4","@latticexyz/solecs":"2.0.0-alpha.1.161+cd7b89c4","@latticexyz/store":"2.0.0-alpha.1.161+cd7b89c4","@latticexyz/utils":"2.0.0-alpha.1.161+cd7b89c4","@latticexyz/world":"2.0.0-alpha.1.161+cd7b89c4","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"cd7b89c4c0804a6c68f81a4ff2d310b2828d2b49","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.161","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-3D3MoBWUSz2ZHMkDZcmfQwrZhnUwtgbGhpuwS8ve18upEYO477YklxS5Y2j8GkHSskDxclNDY5NxhEjOpv86/Q==","shasum":"496e4de418a88ec783973a20e62df81b850f386c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.161.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCTA3VTnbLwrqIdir8vqUsuDJ/jE9Xo+GkbEFHHbE4lLgIhAPw2Fnc6BHg2pvNS2VJBroYSGnTPmbLzwEdD6xlL60dI"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.161_1684435837388_0.2683376449818644"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.162":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.162","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.162+cc722dd0","@latticexyz/recs":"2.0.0-alpha.1.162+cc722dd0","@latticexyz/schema-type":"2.0.0-alpha.1.162+cc722dd0","@latticexyz/services":"2.0.0-alpha.1.162+cc722dd0","@latticexyz/solecs":"2.0.0-alpha.1.162+cc722dd0","@latticexyz/store":"2.0.0-alpha.1.162+cc722dd0","@latticexyz/utils":"2.0.0-alpha.1.162+cc722dd0","@latticexyz/world":"2.0.0-alpha.1.162+cc722dd0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"cc722dd0c435fea5ca725b749675ec3a76d77080","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.162","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-9Dxzf/5II6987ynHA9T3ad7O/VnZe+2OrYWYRVP0jl2DdWMQiFfVmwv+r7r/JUJxLE6yLaT7VxIZUHJSPAFd0g==","shasum":"8add2844abaead906f62a01c9138b3bf2d429e05","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.162.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG58ralOHeTygrHVA8F4IhoIKLqdwhGbzMx/ThnQ5vhbAiAg5gbntZe9ImlRJE14+mFKE6PNgDGYh2Q9N6l4FVR0hQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.162_1684435887037_0.35556564093924514"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.163":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.163","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.163+eace7da2","@latticexyz/recs":"2.0.0-alpha.1.163+eace7da2","@latticexyz/schema-type":"2.0.0-alpha.1.163+eace7da2","@latticexyz/services":"2.0.0-alpha.1.163+eace7da2","@latticexyz/solecs":"2.0.0-alpha.1.163+eace7da2","@latticexyz/store":"2.0.0-alpha.1.163+eace7da2","@latticexyz/utils":"2.0.0-alpha.1.163+eace7da2","@latticexyz/world":"2.0.0-alpha.1.163+eace7da2","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"eace7da2a480c45411e621fdb4ed3f5bdd44cfab","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.163","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-LovHI6RgMXuwmik/Puf0hVmaopwCxJvfz1CMwU241HHRI7bYfQU0NUh8DU9AK6hjP0qUdzTauG0vSj0Er+0d+A==","shasum":"0ffaac8046460fcff61ba907b9d7015104a836c9","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.163.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCM2lidV48zMME6Gn+6p2pVtGEOBluSeKsF8VKQ55sl4AIhAJIEEkm+Wujh64YMzhm3Fd8QEhJ3P1RGSqBK+NuJLNsY"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.163_1684437325234_0.1913936165665644"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.164":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.164","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.164+6d93e41f","@latticexyz/recs":"2.0.0-alpha.1.164+6d93e41f","@latticexyz/schema-type":"2.0.0-alpha.1.164+6d93e41f","@latticexyz/services":"2.0.0-alpha.1.164+6d93e41f","@latticexyz/solecs":"2.0.0-alpha.1.164+6d93e41f","@latticexyz/store":"2.0.0-alpha.1.164+6d93e41f","@latticexyz/utils":"2.0.0-alpha.1.164+6d93e41f","@latticexyz/world":"2.0.0-alpha.1.164+6d93e41f","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"6d93e41f4e69cef98c4d460a5488faab96d261a1","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.164","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-Cv339c4JW+xFttnpvi5RFZCBR6VbSDx5xELq8etHKMzVr5xZOpsv3ubXYzeZ4b5wEfz0JX8qy9566Skw+Pvp4A==","shasum":"c4734c38ecd487d6bb7ac0f99a9b904c847375d7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.164.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCxRruHvtnaXrXQbpdM2Aj2YgUN3TnqGHi6K5VORHPdCwIhAMA5Bk/XZFTf8BcLNPi7QbYv9INgFMl5IvwvrAAFhAZp"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.164_1684441733767_0.4790388594659123"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.165":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.165","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.165+21066424","@latticexyz/recs":"2.0.0-alpha.1.165+21066424","@latticexyz/schema-type":"2.0.0-alpha.1.165+21066424","@latticexyz/services":"2.0.0-alpha.1.165+21066424","@latticexyz/solecs":"2.0.0-alpha.1.165+21066424","@latticexyz/store":"2.0.0-alpha.1.165+21066424","@latticexyz/utils":"2.0.0-alpha.1.165+21066424","@latticexyz/world":"2.0.0-alpha.1.165+21066424","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"21066424e66cdb0e690581746e87a3dd8c0f44c3","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.165","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-U/ah812QU9lw56+TT0cgiiNCRjkLq/csYaBm0Vf/7IH4hFtIRKMjwcpolO8m6DubYdwry+79lRsZrjE6WihSiw==","shasum":"644004b9bf3ae2ad4564306b470e9c724c920862","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.165.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH7WUI3lnu9Om12c34emYUaF+CdFDkNjAVCuiCuIrb4jAiAC3KnL8KiGdJriSFz9ddr88jsoMH9glSNs2HfvYLRmfw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.165_1684445015746_0.3772774458267114"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.166":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.166","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.166+731bb323","@latticexyz/recs":"2.0.0-alpha.1.166+731bb323","@latticexyz/schema-type":"2.0.0-alpha.1.166+731bb323","@latticexyz/services":"2.0.0-alpha.1.166+731bb323","@latticexyz/solecs":"2.0.0-alpha.1.166+731bb323","@latticexyz/store":"2.0.0-alpha.1.166+731bb323","@latticexyz/utils":"2.0.0-alpha.1.166+731bb323","@latticexyz/world":"2.0.0-alpha.1.166+731bb323","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"731bb3231406716e5cfc6e933bb559f8f31969f2","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.166","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-AvlxQTKL7UK9SSe5ZP2S/hTOvB2vBjZjqgQXHDCjH6owWsaH2IBn7B9+1XVel/YYp2M/cxQrgKqDblvzoVE/Qw==","shasum":"558d5f6ae2c9d3ee0b668a76654a4eadcc97aed0","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.166.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA58ZaKIDhrNKhWfzYnN4n4fqEJTDPXGCnBzU+z6wo8sAiBz19kcF0EKrQXdu2betZoukjnJun2BOgtLRqINwIqS5w=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.166_1684448125770_0.5139501717913344"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.167":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.167","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.167+f0d444a3","@latticexyz/recs":"2.0.0-alpha.1.167+f0d444a3","@latticexyz/schema-type":"2.0.0-alpha.1.167+f0d444a3","@latticexyz/services":"2.0.0-alpha.1.167+f0d444a3","@latticexyz/solecs":"2.0.0-alpha.1.167+f0d444a3","@latticexyz/store":"2.0.0-alpha.1.167+f0d444a3","@latticexyz/utils":"2.0.0-alpha.1.167+f0d444a3","@latticexyz/world":"2.0.0-alpha.1.167+f0d444a3","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"f0d444a37dc6dd6d1d700f5a72b5144cef56d431","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.167","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-vXfGb5rmKhg64NSVGL+Eq3RiLDg13qZ7o/RSfKCUeW4960rP/IBNZB1UqKujnfbYUC0ew7jcBEH9yc1cpy1X/g==","shasum":"ecab0d693e71ec6814c66742e519bcd76ca370e0","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.167.tgz","fileCount":79,"unpackedSize":487546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDLRlsBUHok+NKArC4+eBoMlmL1I5pq1zim08YfsjsIYQIgCIFlwv0SvIR4D6u3Z2excyeXuhNuwqra9IwHYT+6Q3A="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.167_1684451741787_0.970289345031623"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.168":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.168","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.168+ceefb3c5","@latticexyz/recs":"2.0.0-alpha.1.168+ceefb3c5","@latticexyz/schema-type":"2.0.0-alpha.1.168+ceefb3c5","@latticexyz/services":"2.0.0-alpha.1.168+ceefb3c5","@latticexyz/solecs":"2.0.0-alpha.1.168+ceefb3c5","@latticexyz/store":"2.0.0-alpha.1.168+ceefb3c5","@latticexyz/utils":"2.0.0-alpha.1.168+ceefb3c5","@latticexyz/world":"2.0.0-alpha.1.168+ceefb3c5","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"ceefb3c51c0f96e7a1fe89d3dfaa4260a8bd7c3b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.168","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-RXS8w1iSJKyrX8EtWfIN3bRqrB9PTHBDjhAU1+0UGKxA8Dd5xRvpUTrsgqShJQFrAklmEdstz/MiJeDjZfQ3bQ==","shasum":"af18209d7401cb36168bf0b649746a2c63cbc2e0","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.168.tgz","fileCount":79,"unpackedSize":487986,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID5sCFBtxgQdtddlo/j1HTxSDrniPaPjLvool4aUmDG/AiAGcqp/K+cz+kOqxcpMrY+Sdpw93mbFW8wM2yQMWRHLPA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.168_1684451840682_0.004456511175459754"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.169":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.169","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.169+9e98a81c","@latticexyz/recs":"2.0.0-alpha.1.169+9e98a81c","@latticexyz/schema-type":"2.0.0-alpha.1.169+9e98a81c","@latticexyz/services":"2.0.0-alpha.1.169+9e98a81c","@latticexyz/solecs":"2.0.0-alpha.1.169+9e98a81c","@latticexyz/store":"2.0.0-alpha.1.169+9e98a81c","@latticexyz/utils":"2.0.0-alpha.1.169+9e98a81c","@latticexyz/world":"2.0.0-alpha.1.169+9e98a81c","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"9e98a81c5d6650a785c663c9a25e34a6d9b196d8","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.169","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-7JtMotZgocPnhfT5xB2ownHW+qGE1IRYUJpo8GLu1qH8flHoOsE4fZ/gzGm92z4jGqIS9ClodRDtIw8+7rrOlQ==","shasum":"15e6afa84c29ac8e61366693da25fdafc5e60798","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.169.tgz","fileCount":79,"unpackedSize":487986,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBRM5at53Nzavxy/gz1uazuiLSk9W7/Td1j4uHAiflo5AiAoMnwiyGNDj6FtaYLS6603Rbwclax7EYGFqLLlf8rAOQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.169_1684452403908_0.23155626177998356"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.170":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.170","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.170+76be5d21","@latticexyz/recs":"2.0.0-alpha.1.170+76be5d21","@latticexyz/schema-type":"2.0.0-alpha.1.170+76be5d21","@latticexyz/services":"2.0.0-alpha.1.170+76be5d21","@latticexyz/solecs":"2.0.0-alpha.1.170+76be5d21","@latticexyz/store":"2.0.0-alpha.1.170+76be5d21","@latticexyz/utils":"2.0.0-alpha.1.170+76be5d21","@latticexyz/world":"2.0.0-alpha.1.170+76be5d21","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"76be5d2193ac6c6d9ffead8afe1e3b2e2a156dae","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.170","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-3mk8g9cJ7yva+EjH461H8SQzKTPtgH4Qv1356Ob0cAV1ODeSdz+TXws4NREmR36Inv3vAFCgaxtCFzrLFymeag==","shasum":"387e5cb07a70ade54ada2626d1ca779a1ec97aa6","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.170.tgz","fileCount":79,"unpackedSize":487986,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCe0968AP4VajvRXAaWm+Bu17Wgh4O20rlO/HfXNhGMpQIgL5aANjYPkT9SMt5iPl1Oe+DK7u4YxsZHNNR1dssO9G0="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.170_1684474051217_0.08975756045964878"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.171":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.171","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.171+837f5f49","@latticexyz/recs":"2.0.0-alpha.1.171+837f5f49","@latticexyz/schema-type":"2.0.0-alpha.1.171+837f5f49","@latticexyz/services":"2.0.0-alpha.1.171+837f5f49","@latticexyz/solecs":"2.0.0-alpha.1.171+837f5f49","@latticexyz/store":"2.0.0-alpha.1.171+837f5f49","@latticexyz/utils":"2.0.0-alpha.1.171+837f5f49","@latticexyz/world":"2.0.0-alpha.1.171+837f5f49","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"837f5f491cc602c2efea379cd9dcf5c1b017e24d","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.171","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-fkv0xBFZljgNOy2woeJM7+xnTpw6Qfno07jqDf0cLmdihoNoYXThtGBUcudxRopbrUIhulCm6wPpyKw0IA/PMQ==","shasum":"322199b27afd88953bff3d3059cf00527ffc6517","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.171.tgz","fileCount":79,"unpackedSize":487986,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDWZSPFux+r03L9YvJAaQN/HKf9dDnAxVlw26lScbabGgIgVm5t1nTkQLtexsKOOw1UUnpCwDy+yBzIfo98MZOG+yQ="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.171_1684507818646_0.1150096496535582"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.172":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.172","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.172+7ebb18f7","@latticexyz/recs":"2.0.0-alpha.1.172+7ebb18f7","@latticexyz/schema-type":"2.0.0-alpha.1.172+7ebb18f7","@latticexyz/services":"2.0.0-alpha.1.172+7ebb18f7","@latticexyz/solecs":"2.0.0-alpha.1.172+7ebb18f7","@latticexyz/store":"2.0.0-alpha.1.172+7ebb18f7","@latticexyz/utils":"2.0.0-alpha.1.172+7ebb18f7","@latticexyz/world":"2.0.0-alpha.1.172+7ebb18f7","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"7ebb18f7b1d9e0168ea2fb7e4f9e96cb9f359d85","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.172","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-DuAOeHBpPwEp6p6SY5CLfYjyA0D5Qe1wme6xe3cjtbLmGrfHpBG+iYsAKKXLtDspHi57TrPkh4HZvL9nXwYXVA==","shasum":"e132480eeb7450af45664f23528c25c305e08f60","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.172.tgz","fileCount":79,"unpackedSize":488634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBPNIFiSn0E83L7yqjNQ1nyCpkJjfHrtg8IzBft2KN6+AiBgEkBFjQlHonzWUlMYWBWTk/RA1gX9xAb9jVFnAaSiGA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.172_1684507907788_0.6451157273897001"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.173":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.173","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.173+ffc66e77","@latticexyz/recs":"2.0.0-alpha.1.173+ffc66e77","@latticexyz/schema-type":"2.0.0-alpha.1.173+ffc66e77","@latticexyz/services":"2.0.0-alpha.1.173+ffc66e77","@latticexyz/solecs":"2.0.0-alpha.1.173+ffc66e77","@latticexyz/store":"2.0.0-alpha.1.173+ffc66e77","@latticexyz/utils":"2.0.0-alpha.1.173+ffc66e77","@latticexyz/world":"2.0.0-alpha.1.173+ffc66e77","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"ffc66e776b6587c38af4dd1119b599c049b2406b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.173","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-ie2hcZuveqVr5cXzixu0GgX7GP3M4NLtOyaqeCtjezvILzmS8/h6SMUOHhupYCvsdaPIO1iMxRmxwEi+SNKwVw==","shasum":"798f6150026ed6c62fcf7cb541d4ddf0c37ddaec","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.173.tgz","fileCount":79,"unpackedSize":488634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFoPb7DdzlsSOVwU/mpw7rIi0YJQb/jlr07mui5HIJ8KAiEAmNzDBBXZMU1KFI75EB1y6g0qnsoLYs2OubZUSzVEd4o="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.173_1684510663861_0.44260683811211887"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.174":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.174","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.174+7d4c188f","@latticexyz/recs":"2.0.0-alpha.1.174+7d4c188f","@latticexyz/schema-type":"2.0.0-alpha.1.174+7d4c188f","@latticexyz/services":"2.0.0-alpha.1.174+7d4c188f","@latticexyz/solecs":"2.0.0-alpha.1.174+7d4c188f","@latticexyz/store":"2.0.0-alpha.1.174+7d4c188f","@latticexyz/utils":"2.0.0-alpha.1.174+7d4c188f","@latticexyz/world":"2.0.0-alpha.1.174+7d4c188f","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"7d4c188fdfeba00c39c5303108a72aaea6bfe053","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.174","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-JaFoVPAQHyC61aPGG9vHH/vVth8E3NgM+gtoLKSy1QCakcpcuXXnfriKbNSdGzd4Hp72215AmFvm8HaVIPi5hw==","shasum":"fddf7d38e9bc0ff5610c0d45b9d3cb372cd03987","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.174.tgz","fileCount":79,"unpackedSize":488634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDQFCCba04KRkIR5SePcthj97NXj/UIe/aW7enaH4RqHAiEA9BoMTFGS6hpNZ/HTAzwLHlIsHyeDghR5ecio+939ooI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.174_1684520310947_0.0694271762180887"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.175":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.175","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.175+641d0d35","@latticexyz/recs":"2.0.0-alpha.1.175+641d0d35","@latticexyz/schema-type":"2.0.0-alpha.1.175+641d0d35","@latticexyz/services":"2.0.0-alpha.1.175+641d0d35","@latticexyz/solecs":"2.0.0-alpha.1.175+641d0d35","@latticexyz/store":"2.0.0-alpha.1.175+641d0d35","@latticexyz/utils":"2.0.0-alpha.1.175+641d0d35","@latticexyz/world":"2.0.0-alpha.1.175+641d0d35","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"641d0d35912622c99fcbb347b0c0af15efc0ad11","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.175","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-i7GzRZpQzP0wm54d6r2lE6zNx2KtFLmKsCkkEtxAY/5mrF+fbU1LxEVRvEq4aYUUFnTEMUIe8VEg9LuR+s9XHQ==","shasum":"120e3f6b4f3b7c83c569b0418a6f5078cd97edcf","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.175.tgz","fileCount":79,"unpackedSize":488634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCZW2QPzbqAqJe53gChMJa4fJgpStxHOCCtXAs2iuvBxgIgEE8WRQ6Ib3wSFtlPL2aUA9H2rmp/C+gy/AgMPASeozY="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.175_1684524084315_0.540728873057549"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.176":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.176","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.176+b2c06c9f","@latticexyz/recs":"2.0.0-alpha.1.176+b2c06c9f","@latticexyz/schema-type":"2.0.0-alpha.1.176+b2c06c9f","@latticexyz/services":"2.0.0-alpha.1.176+b2c06c9f","@latticexyz/solecs":"2.0.0-alpha.1.176+b2c06c9f","@latticexyz/store":"2.0.0-alpha.1.176+b2c06c9f","@latticexyz/utils":"2.0.0-alpha.1.176+b2c06c9f","@latticexyz/world":"2.0.0-alpha.1.176+b2c06c9f","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"b2c06c9f213094c5b10dd550f84575131f42cd73","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.176","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-3+czXpwRSPibaOG8vtvNxBmeDWSz6kJhNbFOnUDA/ra06KhXujHD+uBSiOzjH9brKRZ18pRweGk60M2xLydPnw==","shasum":"a8aa40852299bc47e000af9c081ebae24078fe2e","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.176.tgz","fileCount":79,"unpackedSize":488634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH6+1a6Tz9iQCNxVANm5yzw0AV5BLvNpqy/KgcvPiXHTAiEAkhjLmT8/oKennWk7z7w7mpqKWZuCVnzqKS5bZ8TPIrg="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.176_1684544499034_0.2839625408054587"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.177":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.177","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.177+5ec509dd","@latticexyz/recs":"2.0.0-alpha.1.177+5ec509dd","@latticexyz/schema-type":"2.0.0-alpha.1.177+5ec509dd","@latticexyz/services":"2.0.0-alpha.1.177+5ec509dd","@latticexyz/solecs":"2.0.0-alpha.1.177+5ec509dd","@latticexyz/store":"2.0.0-alpha.1.177+5ec509dd","@latticexyz/utils":"2.0.0-alpha.1.177+5ec509dd","@latticexyz/world":"2.0.0-alpha.1.177+5ec509dd","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5ec509dd824f3fb588e0396996ee97ca36dfa13d","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.177","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-95EvigJuN8hKVlehcs0Y0cQTYbdTk5Eg2U89B61uKtcfhNVInLNQ26XR8KT6M5XUV5Pqv8nkJURAs0adgoytWA==","shasum":"3949e2daa4450c1dddd9fb4e372fe007ead5ed6f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.177.tgz","fileCount":79,"unpackedSize":488634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIADV1kzWTeFmOALNqhEOvqofuZhr9zK23Tkz+d6vUdA8AiA5Qo0BbI3gkd/1LDd/p/Ek8orKYDFVjyq3Hn31xyNKuw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.177_1684567451557_0.3827070145419684"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.178":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.178","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.178+df25b713","@latticexyz/recs":"2.0.0-alpha.1.178+df25b713","@latticexyz/schema-type":"2.0.0-alpha.1.178+df25b713","@latticexyz/services":"2.0.0-alpha.1.178+df25b713","@latticexyz/solecs":"2.0.0-alpha.1.178+df25b713","@latticexyz/store":"2.0.0-alpha.1.178+df25b713","@latticexyz/utils":"2.0.0-alpha.1.178+df25b713","@latticexyz/world":"2.0.0-alpha.1.178+df25b713","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"df25b71318809fa18daeb32d02a77f1aa9ed3a9b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.178","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-KAiXf1x6/thksWld7Fn9mSPErFf4FH7xf09FSC2Euz5sOLSlx9dBlBPW6MvHqMyYJDdG+ObrVyQu2ulTxDNp1Q==","shasum":"46e910b414a71b86b5b15ca8f2fec46623638184","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.178.tgz","fileCount":79,"unpackedSize":488634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB7QbMGcQlKv2kqVi1ce/fnxXRTFAK1tadR4elVo70fpAiBBVEoqN22KY2prqOlOQFldFy+ehrFd+UIjuvlHbqp+aQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.178_1684595194926_0.8019794525992463"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.179":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.179","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.179+1898fd55","@latticexyz/recs":"2.0.0-alpha.1.179+1898fd55","@latticexyz/schema-type":"2.0.0-alpha.1.179+1898fd55","@latticexyz/services":"2.0.0-alpha.1.179+1898fd55","@latticexyz/solecs":"2.0.0-alpha.1.179+1898fd55","@latticexyz/store":"2.0.0-alpha.1.179+1898fd55","@latticexyz/utils":"2.0.0-alpha.1.179+1898fd55","@latticexyz/world":"2.0.0-alpha.1.179+1898fd55","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"1898fd5593cc38c3b30e1f47ca450dcab372fcc9","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.179","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-vj7q8g9pFLFL+JUeW7a5fo6GTfneCNTBFjgxc4nBLl0BRGVxtlKX0lg4LmmXtfOoKDQRID5xdOdFcheyxbsm1Q==","shasum":"1ad3a6e9edc6043e72e8ab887f8f588738e6f259","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.179.tgz","fileCount":79,"unpackedSize":488634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC7olWz4oUf31TU7kJjZMQIeOdkbayIzxIJ7muof56djgIhAK1sb4FQAmCuADHEmCy8VUasMN3mULRlPFFj+2Pmcc1F"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.179_1684597403725_0.596394196919265"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.180":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.180","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.180+a300e25d","@latticexyz/recs":"2.0.0-alpha.1.180+a300e25d","@latticexyz/schema-type":"2.0.0-alpha.1.180+a300e25d","@latticexyz/services":"2.0.0-alpha.1.180+a300e25d","@latticexyz/solecs":"2.0.0-alpha.1.180+a300e25d","@latticexyz/store":"2.0.0-alpha.1.180+a300e25d","@latticexyz/utils":"2.0.0-alpha.1.180+a300e25d","@latticexyz/world":"2.0.0-alpha.1.180+a300e25d","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"a300e25d45be5d18959b8be93edf6c3f19580ab1","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.180","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-zaoiX7JTsSgTaN9NP6B77QmNl3D7xiKVA5T2diWhiYYt1twClqh8VTsCJYCd6xfpEyDrFX1SMuGlgsCr2R9UuA==","shasum":"0f117cd2399e892cfb3f506ccece14dd001ae002","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.180.tgz","fileCount":79,"unpackedSize":488634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGSzmPXo66QHUsjLuvCFcPLQFr5fgO+W0TcjvrnlnZIBAiEA4EGnQJEjAJ//vFTgeAK1fM4MNlZMih3uz/9eno6ylgI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.180_1684608161508_0.11962998601517105"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.181":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.181","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.181+e80def85","@latticexyz/recs":"2.0.0-alpha.1.181+e80def85","@latticexyz/schema-type":"2.0.0-alpha.1.181+e80def85","@latticexyz/services":"2.0.0-alpha.1.181+e80def85","@latticexyz/solecs":"2.0.0-alpha.1.181+e80def85","@latticexyz/store":"2.0.0-alpha.1.181+e80def85","@latticexyz/utils":"2.0.0-alpha.1.181+e80def85","@latticexyz/world":"2.0.0-alpha.1.181+e80def85","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"e80def85d358f41990c2da63fec35c1fb2da1a64","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.181","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-YVRIBvQrllcyzuELexUi7h7yNtjNjCv+IrejMRP1A84Vu/qwu8YYpqxLoji1+lPdnYPRV5/ngRJ23gUeh3XbqQ==","shasum":"a0bfcffa27b7033345979833b288da09f5edaad9","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.181.tgz","fileCount":79,"unpackedSize":488634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGeXiZ2TrMOJSD+eqb4Bc+KGoR3Q+QYN9QWIJ8N/LbiIAiAJcAFS5kNDDoagAoJJ3lOnf4tVWMYq84kZjecmj/JRRQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.181_1684612925635_0.2081556113328582"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.182":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.182","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.182+7cc83c7d","@latticexyz/recs":"2.0.0-alpha.1.182+7cc83c7d","@latticexyz/schema-type":"2.0.0-alpha.1.182+7cc83c7d","@latticexyz/services":"2.0.0-alpha.1.182+7cc83c7d","@latticexyz/solecs":"2.0.0-alpha.1.182+7cc83c7d","@latticexyz/store":"2.0.0-alpha.1.182+7cc83c7d","@latticexyz/utils":"2.0.0-alpha.1.182+7cc83c7d","@latticexyz/world":"2.0.0-alpha.1.182+7cc83c7d","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"7cc83c7d8434a759c88552f91d36ef248e08227f","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.182","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-wy5noFbJwCGR+AoR994MQM/kZh0iBdgodpUF/hzxDYY9FhV4Nw4T0BVYUYcPKdnofo5TmbYqHbqQczteLW9yYg==","shasum":"973c7afa9e3700ca76d8e3c969f3fcb0792e88c5","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.182.tgz","fileCount":79,"unpackedSize":488634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGupXvBOOQvXSdCsbkGWUFigRU9H0Em5JsTlZ4Ch766aAiAh5wORfbAL5NHCz8tPvR008R/7r9PvmDcYdQW+1r87gw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.182_1684620468677_0.16316809731164716"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.183":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.183","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.183+07a99974","@latticexyz/recs":"2.0.0-alpha.1.183+07a99974","@latticexyz/schema-type":"2.0.0-alpha.1.183+07a99974","@latticexyz/services":"2.0.0-alpha.1.183+07a99974","@latticexyz/solecs":"2.0.0-alpha.1.183+07a99974","@latticexyz/store":"2.0.0-alpha.1.183+07a99974","@latticexyz/utils":"2.0.0-alpha.1.183+07a99974","@latticexyz/world":"2.0.0-alpha.1.183+07a99974","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"07a9997463ce040b187cbebd55d09ed9504f648a","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.183","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-HfzhA0q9P58X/8p/D1xq1Ul5s7oeGfa/c9qFgdFMmZaEP4eeWT7zaseZ60t970ZrGrhWqLPENkny9tclHU/8gg==","shasum":"f97e88d571b0cfe4d12c4baf7f0977ce336012c3","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.183.tgz","fileCount":79,"unpackedSize":488634,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICEesCVZ7KoncRL7mXpuTF9r2yBxC6SM7tSClQ7ZhyHsAiEAiLx29SywwflbJwGEGxY7egk2K7nX0VGE1RuIOfjaJ64="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.183_1684623752643_0.2085449226108067"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.184":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.184","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.184+cac999de","@latticexyz/recs":"2.0.0-alpha.1.184+cac999de","@latticexyz/schema-type":"2.0.0-alpha.1.184+cac999de","@latticexyz/services":"2.0.0-alpha.1.184+cac999de","@latticexyz/solecs":"2.0.0-alpha.1.184+cac999de","@latticexyz/store":"2.0.0-alpha.1.184+cac999de","@latticexyz/utils":"2.0.0-alpha.1.184+cac999de","@latticexyz/world":"2.0.0-alpha.1.184+cac999de","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"cac999def73fe6b826ac5ed2f5e7022078456f1e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.184","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-j+BS60M4ODC1FV5rHzJKm5CemAmq0IBFnbwOU697XYyhMY7m1I72IlDDlbVwHTncjlE+orOzapMtX+8KC0zkTQ==","shasum":"6494fb0651ac564a01f415dc88c767ea61f80361","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.184.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFzc2Kz86tyswPNUMoxxtBTx+1Ud4BdODy+N3KhJ1YnUAiAa3Ao7AO+G0sVTP5H4K9gbqgoKnOxH9Lw0Ph7zkA77Rw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.184_1684774401640_0.6609754674255841"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.185":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.185","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.185+2c8af753","@latticexyz/recs":"2.0.0-alpha.1.185+2c8af753","@latticexyz/schema-type":"2.0.0-alpha.1.185+2c8af753","@latticexyz/services":"2.0.0-alpha.1.185+2c8af753","@latticexyz/solecs":"2.0.0-alpha.1.185+2c8af753","@latticexyz/store":"2.0.0-alpha.1.185+2c8af753","@latticexyz/utils":"2.0.0-alpha.1.185+2c8af753","@latticexyz/world":"2.0.0-alpha.1.185+2c8af753","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"2c8af7537de9874ca9b70df89238ca294928fcc8","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.185","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-4oCnSMaMQlY/m1TQOPckj5FweepT/JCHEFnM9jJSsot4VYPKrm0znZUJOWPXSsiYOyFeYZEy3NDDfeqLYV9sXg==","shasum":"ff238bc90d39c58be7d024b23dcc1c6ce8d3b952","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.185.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE5gfTxKDmsNK9/abCzfw2qRdtyYgx+zgd0jl5pU8Z0KAiB6Mzppi9ZyYDaziEWLPxOnBqEWXpSZr4xFIPnqqru/Fw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.185_1684775705147_0.9906629999913885"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.186":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.186","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.186+4d24c965","@latticexyz/recs":"2.0.0-alpha.1.186+4d24c965","@latticexyz/schema-type":"2.0.0-alpha.1.186+4d24c965","@latticexyz/services":"2.0.0-alpha.1.186+4d24c965","@latticexyz/solecs":"2.0.0-alpha.1.186+4d24c965","@latticexyz/store":"2.0.0-alpha.1.186+4d24c965","@latticexyz/utils":"2.0.0-alpha.1.186+4d24c965","@latticexyz/world":"2.0.0-alpha.1.186+4d24c965","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"4d24c96518daa894b6b64289570b70764296ce9e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.186","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-iZaR0OkAruswvSbtqBhUPxtv3+K3Umf1gyD0fw11aWQnm0v3AjZee7pr98b+r2yJTLJYLqUZAPxKMwJCOaMhiw==","shasum":"c195afde998bab47f01e51ea3751e9656782d80c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.186.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEBE1tNJyyD4dsGl2Q/9mGKXukIYcWrSjVLs0r33vIW9AiBAcZpW2cOv3CDCI30O8SOxgpxIV02vfmD3Bz0vhrY0SA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.186_1684776453361_0.687889504515302"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.187":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.187","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.187+c6b8210c","@latticexyz/recs":"2.0.0-alpha.1.187+c6b8210c","@latticexyz/schema-type":"2.0.0-alpha.1.187+c6b8210c","@latticexyz/services":"2.0.0-alpha.1.187+c6b8210c","@latticexyz/solecs":"2.0.0-alpha.1.187+c6b8210c","@latticexyz/store":"2.0.0-alpha.1.187+c6b8210c","@latticexyz/utils":"2.0.0-alpha.1.187+c6b8210c","@latticexyz/world":"2.0.0-alpha.1.187+c6b8210c","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"c6b8210c643291cc73b43e12104966ebb4dd4b2a","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.187","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-9MUuWVGRvkiFxpgXVJQNVXIz/swkcrGaiedZ/YnrHoyF0TAntH9Gf5CFHT+IlYtMI+ouhchPUC3qfA2t2Ch2FA==","shasum":"c07c73aa709fa5851f34076b77e966982c2f881a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.187.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGPWqHiwJl5ytfj78OVxuUgsQMKDEZm6dJP04JRckX8DAiBGn8aWgQfxM5opkJMtZUhB2AM5OuDrsGaWtk7ftODmmw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.187_1684776613631_0.3704829456587875"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.188":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.188","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.188+c2c5e7c7","@latticexyz/recs":"2.0.0-alpha.1.188+c2c5e7c7","@latticexyz/schema-type":"2.0.0-alpha.1.188+c2c5e7c7","@latticexyz/services":"2.0.0-alpha.1.188+c2c5e7c7","@latticexyz/solecs":"2.0.0-alpha.1.188+c2c5e7c7","@latticexyz/store":"2.0.0-alpha.1.188+c2c5e7c7","@latticexyz/utils":"2.0.0-alpha.1.188+c2c5e7c7","@latticexyz/world":"2.0.0-alpha.1.188+c2c5e7c7","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"c2c5e7c7a67056ecdd8e7825a895685a97ce1e9c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.188","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-iItRnF7Mcyg5S8mMRmCSeIZnwGpAsgOYqztq681Bfot+y1D5fKKrOMIUexdIlgev9hJwONZiEtytyZZ0749vqA==","shasum":"80b24171ee1e25bcbd1689fed8d664bd8923ce70","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.188.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC0QGOxjBEOtHGGtM1yAOX/Eo7h6X/2K5UvZebM+qa93AiEA+5KxYlYsNZgG+GjEIQCyjedKJtE3WmUEEJdyYK4e5d0="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.188_1684777733862_0.763826325274644"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.189":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.189","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.189+aaae8222","@latticexyz/recs":"2.0.0-alpha.1.189+aaae8222","@latticexyz/schema-type":"2.0.0-alpha.1.189+aaae8222","@latticexyz/services":"2.0.0-alpha.1.189+aaae8222","@latticexyz/solecs":"2.0.0-alpha.1.189+aaae8222","@latticexyz/store":"2.0.0-alpha.1.189+aaae8222","@latticexyz/utils":"2.0.0-alpha.1.189+aaae8222","@latticexyz/world":"2.0.0-alpha.1.189+aaae8222","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"aaae8222174055f226c3f89d399a1d3fd4ed999d","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.189","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-UFvCIMz4dAOijeXuIeEfetCHuFZFOlQ1jZXtxnxeC69nAP+aTP/8vyqmgvmLvr5NoR9jc5yxGK1R4DzzPu+u8A==","shasum":"f1d6ece24a605d5efe9650e249742098d7a79cea","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.189.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICPtv7FE7W+tazXtH7zX2i1JBMfLpDVoKit+1caRuplaAiBpn0e7mh5MEaysZeoAEMOVtQK7PoQ+xK8dOYnhHM/FBA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.189_1684777997908_0.37927970120194177"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.190":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.190","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.190+b43a3a7f","@latticexyz/recs":"2.0.0-alpha.1.190+b43a3a7f","@latticexyz/schema-type":"2.0.0-alpha.1.190+b43a3a7f","@latticexyz/services":"2.0.0-alpha.1.190+b43a3a7f","@latticexyz/solecs":"2.0.0-alpha.1.190+b43a3a7f","@latticexyz/store":"2.0.0-alpha.1.190+b43a3a7f","@latticexyz/utils":"2.0.0-alpha.1.190+b43a3a7f","@latticexyz/world":"2.0.0-alpha.1.190+b43a3a7f","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"b43a3a7fd0f87947b2e4cfdbbe850d2649d8c7a0","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.190","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-oGPaqE+ih1WgvCbgxA0HNIDI+pS2EnNRsNWcQG3xniHBwWHpofiNiL6Qu8cQwBCpyJe9uLl3lY4X6qiVPYGRRg==","shasum":"6781337e5ad59eede1e36fb008b2bebaf9ccd798","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.190.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCks4iWwx6KWtsXeJEnTkr4ly0GSTptXAZOWUHTBJ/XlwIhAPiq/s1KwcueTVqWKGLs/wqneIKHrPMUFEZ8aVJsluR7"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.190_1684783496185_0.969711278855965"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.191":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.191","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.191+0a055f00","@latticexyz/recs":"2.0.0-alpha.1.191+0a055f00","@latticexyz/schema-type":"2.0.0-alpha.1.191+0a055f00","@latticexyz/services":"2.0.0-alpha.1.191+0a055f00","@latticexyz/solecs":"2.0.0-alpha.1.191+0a055f00","@latticexyz/store":"2.0.0-alpha.1.191+0a055f00","@latticexyz/utils":"2.0.0-alpha.1.191+0a055f00","@latticexyz/world":"2.0.0-alpha.1.191+0a055f00","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"0a055f005aa955f54abeb0502a40a8b391b1db1d","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.191","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-FIkzafSiiuCpw7eDVljRrUNgRpfEAfZ+NCgmB8hhFcaFLUtZ3LGo4O6i0m6V2aWahO8SdS5f1V8Gx4ReOJm/XA==","shasum":"ac997c5b8718aeadc038b0536e98149d2a2b85c1","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.191.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDMandD2mIcegrEQkIOUvAzLShM+cFl8kV3Y0k0Sp0trAIhAJ9MwMqUrfR7fun6Q26kdKFXM7McDt/ZuJa0JcnNpmuO"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.191_1684792507493_0.15499556224390498"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.192":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.192","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.192+966b379d","@latticexyz/recs":"2.0.0-alpha.1.192+966b379d","@latticexyz/schema-type":"2.0.0-alpha.1.192+966b379d","@latticexyz/services":"2.0.0-alpha.1.192+966b379d","@latticexyz/solecs":"2.0.0-alpha.1.192+966b379d","@latticexyz/store":"2.0.0-alpha.1.192+966b379d","@latticexyz/utils":"2.0.0-alpha.1.192+966b379d","@latticexyz/world":"2.0.0-alpha.1.192+966b379d","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"966b379d6331ff7d9f176d098a0b51f022d442d7","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.192","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-ZIlRvzJuuwE4KeG9/hmDAncl9yu0OFngIHOs1bApxT0s8Um8Zqxt1UKYpdH5b41tpLlErrNnX+RQidyzVat/3g==","shasum":"4b21dc9a80982086430eb63d7c217bc4160d5e75","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.192.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA/OXgZD5f9+SX+WcfNWcfPvd+mnMLE1A9h2f5VezvnzAiAKBqOJ6xicDnFluS4Cdpc9vLVFHwOxs3OAS/5gg0EB/Q=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.192_1684831730670_0.44131871385824994"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.193":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.193","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.193+a18fb753","@latticexyz/recs":"2.0.0-alpha.1.193+a18fb753","@latticexyz/schema-type":"2.0.0-alpha.1.193+a18fb753","@latticexyz/services":"2.0.0-alpha.1.193+a18fb753","@latticexyz/solecs":"2.0.0-alpha.1.193+a18fb753","@latticexyz/store":"2.0.0-alpha.1.193+a18fb753","@latticexyz/utils":"2.0.0-alpha.1.193+a18fb753","@latticexyz/world":"2.0.0-alpha.1.193+a18fb753","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"a18fb753aefc74519f4345ee35b04802e1057309","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.193","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-teEL4aBdtqJLzeLXAVZvcLG7i2rm7P2qtoPcZt++6Ucowe585QuJhylcT9CSCWg7t7IIb4wCXIsYurBEL1cxaA==","shasum":"49a5ff50723cd56da83e8a71ff09922f4a93d430","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.193.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDOFiIwIW654m5eNGrlurS0iNBiaZJdXzRIyAOpB3n4EAiEAzmUnEn1OvtGyIzS6H081ZFfF8o2Hdva17ljw2hAoo1k="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.193_1684833164449_0.7690396095093053"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.194":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.194","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.194+595ecfed","@latticexyz/recs":"2.0.0-alpha.1.194+595ecfed","@latticexyz/schema-type":"2.0.0-alpha.1.194+595ecfed","@latticexyz/services":"2.0.0-alpha.1.194+595ecfed","@latticexyz/solecs":"2.0.0-alpha.1.194+595ecfed","@latticexyz/store":"2.0.0-alpha.1.194+595ecfed","@latticexyz/utils":"2.0.0-alpha.1.194+595ecfed","@latticexyz/world":"2.0.0-alpha.1.194+595ecfed","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"595ecfed718f6a54da0a50106920bebf3c92aa46","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.194","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-dWtGJyX7NwbHV3EYl/C+bY4UAAWMrhOA0ju4w4fmqNClWCovsY2WHwnoJv16HJI7nYiqBlcmgDHTVpmDrjFpPw==","shasum":"819b0852a095d7641574b2c649627d97292d68d1","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.194.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFqbCRQM4TQI2OjObJYzHb5WTcER/91Evql3hTeSHq/GAiAHWoYp1BYg3qrLwFaS4WpVfjglrfzwPgEgXLIANdYYIQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.194_1684835315534_0.8715807773999584"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.195":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.195","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.195+67ce0daf","@latticexyz/recs":"2.0.0-alpha.1.195+67ce0daf","@latticexyz/schema-type":"2.0.0-alpha.1.195+67ce0daf","@latticexyz/services":"2.0.0-alpha.1.195+67ce0daf","@latticexyz/solecs":"2.0.0-alpha.1.195+67ce0daf","@latticexyz/store":"2.0.0-alpha.1.195+67ce0daf","@latticexyz/utils":"2.0.0-alpha.1.195+67ce0daf","@latticexyz/world":"2.0.0-alpha.1.195+67ce0daf","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"67ce0daf0cec697932833281e4d753161eb60212","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.195","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-LfvkflJX4mdII1Q2ZBlof9a8Tiw8W8hW18Sc+kQizBQSQ7drfKRvISBnpZH6oYgRWfdDXRjKk2jYeY6FDQH9Ig==","shasum":"714e7cd76cdb57369c598c9c0a62f3f107b7d281","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.195.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICGq/GB17vdzre8fv8J4xB0qMX2V8y5ULJqXjQydP42rAiAY1AGXD+X6PbFHMNWuI2GK2kAm2TojBTcq2IrV1cYB5w=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.195_1684840354876_0.7606542185186353"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.196":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.196","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.196+dd841334","@latticexyz/recs":"2.0.0-alpha.1.196+dd841334","@latticexyz/schema-type":"2.0.0-alpha.1.196+dd841334","@latticexyz/services":"2.0.0-alpha.1.196+dd841334","@latticexyz/solecs":"2.0.0-alpha.1.196+dd841334","@latticexyz/store":"2.0.0-alpha.1.196+dd841334","@latticexyz/utils":"2.0.0-alpha.1.196+dd841334","@latticexyz/world":"2.0.0-alpha.1.196+dd841334","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"dd8413340c429ec28f909bbb1b96fd117cf23a5e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.196","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-sP5+J2b6gt3D7Icqo/jOdHUnU0iH6mTum0YD9McivEqmWx2hTnhOaqESjxfGTuIWopZwAZtMXNTHirFOW3SgBg==","shasum":"ea6260e89d6d791b875a943803bb3f485da00ae8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.196.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG9HCj3c6Tr2lzoxfzh0amDUOcVQmyd2dvfK4x68NUm9AiAkPHuoo3fRgNJg5GWb3AH4j7mHQuzY65m3mG12zXs8uA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.196_1684855985921_0.9521207378427747"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.197":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.197","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.197+5e6cc0f5","@latticexyz/recs":"2.0.0-alpha.1.197+5e6cc0f5","@latticexyz/schema-type":"2.0.0-alpha.1.197+5e6cc0f5","@latticexyz/services":"2.0.0-alpha.1.197+5e6cc0f5","@latticexyz/solecs":"2.0.0-alpha.1.197+5e6cc0f5","@latticexyz/store":"2.0.0-alpha.1.197+5e6cc0f5","@latticexyz/utils":"2.0.0-alpha.1.197+5e6cc0f5","@latticexyz/world":"2.0.0-alpha.1.197+5e6cc0f5","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5e6cc0f5e39caa23c7751398ca8af0afb02f4652","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.197","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-h+jkTI/0tKcRyM2Xv5LfrIGC2oiUjHcHI8A/+tJt+mgTqZEFFk2+QBXRIBnQrC2Ydb0L2ZMcdBB4waQek2liHQ==","shasum":"27b8f740c3d57071299bb74dd00a17455b1210ea","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.197.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC+y9VnxL/C9qTdF+JMrCBQeeGhN4lh42+8hqQ6lmA+nwIhAP8ggrESFxA1xaht0sGZjH9nYd6048dM5rex4az/qvOi"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.197_1684877333402_0.5596941632669148"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.198":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.198","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.198+8abe6233","@latticexyz/recs":"2.0.0-alpha.1.198+8abe6233","@latticexyz/schema-type":"2.0.0-alpha.1.198+8abe6233","@latticexyz/services":"2.0.0-alpha.1.198+8abe6233","@latticexyz/solecs":"2.0.0-alpha.1.198+8abe6233","@latticexyz/store":"2.0.0-alpha.1.198+8abe6233","@latticexyz/utils":"2.0.0-alpha.1.198+8abe6233","@latticexyz/world":"2.0.0-alpha.1.198+8abe6233","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"8abe6233bc9a12b8db1011738daf8b60d068f430","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.198","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-BOF2+cI35w60Fe7ry0QCgluK9OjgUNBUAL5gLX6zA5U45k1QvKFpthBXbmqFNBQ4HpAqZvyj65LOrcrr3G6O8Q==","shasum":"36ce32cbbce3782b9b53915e10b3151034f9b1e0","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.198.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGdBc9gB3kKB2HsMhO6l9iunPLOL/wcDOeIB02GtzLOqAiEA491pML8nHFDUipVqwJp0O1Kuhj2P7rN35nOSd7KgAE4="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.198_1685518309669_0.1606299917787375"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.199":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.199","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.199+b421c2d5","@latticexyz/recs":"2.0.0-alpha.1.199+b421c2d5","@latticexyz/schema-type":"2.0.0-alpha.1.199+b421c2d5","@latticexyz/services":"2.0.0-alpha.1.199+b421c2d5","@latticexyz/solecs":"2.0.0-alpha.1.199+b421c2d5","@latticexyz/store":"2.0.0-alpha.1.199+b421c2d5","@latticexyz/utils":"2.0.0-alpha.1.199+b421c2d5","@latticexyz/world":"2.0.0-alpha.1.199+b421c2d5","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"b421c2d58d462458e63b11776bf9652d6605c2e8","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.199","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-xTD97jOCSj3K/9h8JNv3kH+lNViA8EGb7GoNViYbG9oehMWRKXeLzsAFfwB+yLdQP3br6sX2Hlx0QEl+0h++Vw==","shasum":"4795c32189cafc4147e376829a967d4c65ee70ac","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.199.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGXKKjnkz5+DdNd2mm7hSCnzU2auBSRTfvSDs5qiyR9eAiEAq5l9E8KmIuyUeox+Y3gq6DKgotmBCqi7r4vPyc+MkPA="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.199_1685627737139_0.30107586693246247"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.200":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.200","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.200+21a177ef","@latticexyz/recs":"2.0.0-alpha.1.200+21a177ef","@latticexyz/schema-type":"2.0.0-alpha.1.200+21a177ef","@latticexyz/services":"2.0.0-alpha.1.200+21a177ef","@latticexyz/solecs":"2.0.0-alpha.1.200+21a177ef","@latticexyz/store":"2.0.0-alpha.1.200+21a177ef","@latticexyz/utils":"2.0.0-alpha.1.200+21a177ef","@latticexyz/world":"2.0.0-alpha.1.200+21a177ef","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"21a177efa05fd07b01078e06288278e1811fb602","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.200","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-YMzvPf9eBP38Q9JweJTU0EJoszdRiUaP8F/LS1Pa7sIW6Rg30vo4InifSVgnwWMLeKin+1V+H2axe5NpBwNC9A==","shasum":"725fe6f740e1078e7b64ed355720c2a14388940d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.200.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAdRpqEwrz7OzCbUdCFRMuYoVETr4D19SZvNq09yWDIyAiB91tfCok2bZ2vY3p9i3Zm8PFJvJwM2w+DiuRWWuOSLLQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.200_1685653360181_0.776071469423179"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.201":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.201","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.201+fe745661","@latticexyz/recs":"2.0.0-alpha.1.201+fe745661","@latticexyz/schema-type":"2.0.0-alpha.1.201+fe745661","@latticexyz/services":"2.0.0-alpha.1.201+fe745661","@latticexyz/solecs":"2.0.0-alpha.1.201+fe745661","@latticexyz/store":"2.0.0-alpha.1.201+fe745661","@latticexyz/utils":"2.0.0-alpha.1.201+fe745661","@latticexyz/world":"2.0.0-alpha.1.201+fe745661","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"fe74566187ab356697bfcaa845cf647aff8339fa","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.201","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-sTbTk/ZnsKwsrqlOMXqOVrQeMlitQxwIcCjhUwk2UQtaSgLEsPfVlqYifkTpLk8+md7S1GUir4JhEm7HxlODWQ==","shasum":"8af840485828edac948df61c07207ba90792bd76","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.201.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAOJ6cNDFXB8LNmqbptwhETJJyZqlrAblrLCEVZgZOjmAiAua+yMkIdZ4trDAb1ybnNAOcUCpWjk/3/DPksyhMuYhg=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.201_1685653789962_0.0671688498001517"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.202":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.202","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.202+c0b30b6c","@latticexyz/recs":"2.0.0-alpha.1.202+c0b30b6c","@latticexyz/schema-type":"2.0.0-alpha.1.202+c0b30b6c","@latticexyz/services":"2.0.0-alpha.1.202+c0b30b6c","@latticexyz/solecs":"2.0.0-alpha.1.202+c0b30b6c","@latticexyz/store":"2.0.0-alpha.1.202+c0b30b6c","@latticexyz/utils":"2.0.0-alpha.1.202+c0b30b6c","@latticexyz/world":"2.0.0-alpha.1.202+c0b30b6c","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"c0b30b6c73ee22db473812af1328fbb99570bc2b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.202","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-2+yUECBgDUQpvRDmRHXBkYTlGQ1wf5U447JwygPnpRJEJNkaE10qM2jcmf4fzorrwDDCAtxoiKkZct52jVac6A==","shasum":"ef6ac177a892e8d3c256ccd9d0e93cdab493bff8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.202.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDG4xSBgjRhSmLWKG4XFsnOviQdcW+FZmMjEvolBwqAugIgdcoyN3nAYQjuFdaI1tNg1lElX91t7EA0IMtZis3ckMU="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.202_1685662009841_0.24405914230297499"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.203":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.203","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.203+f9c92f40","@latticexyz/recs":"2.0.0-alpha.1.203+f9c92f40","@latticexyz/schema-type":"2.0.0-alpha.1.203+f9c92f40","@latticexyz/services":"2.0.0-alpha.1.203+f9c92f40","@latticexyz/solecs":"2.0.0-alpha.1.203+f9c92f40","@latticexyz/store":"2.0.0-alpha.1.203+f9c92f40","@latticexyz/utils":"2.0.0-alpha.1.203+f9c92f40","@latticexyz/world":"2.0.0-alpha.1.203+f9c92f40","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"f9c92f40618cc00cec2f7d57e5af57090a867dd0","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.203","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-uvbgvHou5tIN5de4mJkKROlo2NsdDo6ssZN3alGt4eE43RUDuMFbNne8DYheNsV7UcwSs44i43gs3qMIQAcdvA==","shasum":"c5d71c8eba7ef4a890d3581aeb1c50196fdf02cb","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.203.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBGvYVg50ZcKBG/cYJ1qlxwLHXixMtJ1Xeyr2gJzo9cfAiEAhLUvEJRE1TI8+qbzlG0QqKB/pSG4wMZdcLHxRqee1jg="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.203_1685980398397_0.8351390582320284"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.204":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.204","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.204+d97282b6","@latticexyz/recs":"2.0.0-alpha.1.204+d97282b6","@latticexyz/schema-type":"2.0.0-alpha.1.204+d97282b6","@latticexyz/services":"2.0.0-alpha.1.204+d97282b6","@latticexyz/solecs":"2.0.0-alpha.1.204+d97282b6","@latticexyz/store":"2.0.0-alpha.1.204+d97282b6","@latticexyz/utils":"2.0.0-alpha.1.204+d97282b6","@latticexyz/world":"2.0.0-alpha.1.204+d97282b6","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"d97282b6df04fdeb70905d5be4e9fe43daa3f6ab","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.204","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-AWHNvuDoBUBSnw3SNdT/CEERF0EZEDk62Ri3Mg2gUExo7NQpQpz6NvUZcINjn1Kf0N4nAxnGhetY5ZlR6k4zAw==","shasum":"8afeedd3bc08a4fbfafa647437dedb20c6c9020f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.204.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGwjc4gLmthVLx/VGD7cPE8Knqcl9BQoq18qmRAYoZ6QAiEA4driweb1uob7aUA2ALhojFzsMvYBlUIUMOxRkZ/jpNg="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.204_1686148969028_0.9813894510742427"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.206":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.206","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.206+81fc22bd","@latticexyz/recs":"2.0.0-alpha.1.206+81fc22bd","@latticexyz/schema-type":"2.0.0-alpha.1.206+81fc22bd","@latticexyz/services":"2.0.0-alpha.1.206+81fc22bd","@latticexyz/solecs":"2.0.0-alpha.1.206+81fc22bd","@latticexyz/store":"2.0.0-alpha.1.206+81fc22bd","@latticexyz/utils":"2.0.0-alpha.1.206+81fc22bd","@latticexyz/world":"2.0.0-alpha.1.206+81fc22bd","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"81fc22bdceb39944d62879520772de8717fd0834","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.206","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-lvxiob57CvnQ/dHDzvO4pFzAFbVVP8hhNVsgnPrQ2OTAoDmPMGt2PsGu3oZS3rvFTVccqlmztasM0YjIDWnSCw==","shasum":"1fcbc9db0e8ab6360c1acb8e481e16b2e47526e9","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.206.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCAd4XiQiSRWNEwXQv3SoXhki/RC3OYYCluDNChOAsEfQIhANvc36Um9JIHyZ+ruyj6LGS0DjsSg7FtGz92WIrEvV0n"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.206_1686177041327_0.12705060468485407"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.205":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.205","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.205+7b60b63b","@latticexyz/recs":"2.0.0-alpha.1.205+7b60b63b","@latticexyz/schema-type":"2.0.0-alpha.1.205+7b60b63b","@latticexyz/services":"2.0.0-alpha.1.205+7b60b63b","@latticexyz/solecs":"2.0.0-alpha.1.205+7b60b63b","@latticexyz/store":"2.0.0-alpha.1.205+7b60b63b","@latticexyz/utils":"2.0.0-alpha.1.205+7b60b63b","@latticexyz/world":"2.0.0-alpha.1.205+7b60b63b","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"7b60b63b7147954008736a9d3a867d64ea8b44ab","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.205","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-usWJwsx4igZOPGsEicKk4bBJZxY7FwW0BvIbcPuOSf7eg+JGdQHF6PuebKsYz0eBz8efGxyY5Z+mBy7oZ2dkFg==","shasum":"f90b2860cda56698f68d97e4c95f988263024820","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.205.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA3Nr8JdrlGylTniueRSJ8nhls2pG3EYAaPYOjoOxtZOAiAC8BSyJszUTyqitwuDbrK7TxNpvTQDE0gEkc/LJaerrw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.205_1686177054528_0.8925963335653182"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.207":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.207","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.207+6f68267d","@latticexyz/recs":"2.0.0-alpha.1.207+6f68267d","@latticexyz/schema-type":"2.0.0-alpha.1.207+6f68267d","@latticexyz/services":"2.0.0-alpha.1.207+6f68267d","@latticexyz/solecs":"2.0.0-alpha.1.207+6f68267d","@latticexyz/store":"2.0.0-alpha.1.207+6f68267d","@latticexyz/utils":"2.0.0-alpha.1.207+6f68267d","@latticexyz/world":"2.0.0-alpha.1.207+6f68267d","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"6f68267d68c7d29197995a7b81ad1e0e6313780b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.207","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-j9jGZrQDK4L7Rq9YDPLRWVQe2j6TF/QbexD43vR6nVEUAbaWlXHfhRkpbcA0ZXADXZEbsM3YZvJ+nxO9WwrAXQ==","shasum":"c330b6823f18cfbd7099f9faa4858f89eb8aa37c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.207.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH/LZToAKZuluqvabU6Ck+XP/gkQU26vXJBIKPeTV837AiBLHQayrLTx69tzuj0cEdW0gvYNPgIfK4EIvx/mc+VNDQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.207_1686220217637_0.6523893418499895"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.208":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.208","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.208+cd0c3f19","@latticexyz/recs":"2.0.0-alpha.1.208+cd0c3f19","@latticexyz/schema-type":"2.0.0-alpha.1.208+cd0c3f19","@latticexyz/services":"2.0.0-alpha.1.208+cd0c3f19","@latticexyz/solecs":"2.0.0-alpha.1.208+cd0c3f19","@latticexyz/store":"2.0.0-alpha.1.208+cd0c3f19","@latticexyz/utils":"2.0.0-alpha.1.208+cd0c3f19","@latticexyz/world":"2.0.0-alpha.1.208+cd0c3f19","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"cd0c3f19202f9de5c6c545ff0c3d5a3e4c65843b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.208","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-Za9K42sJgVwh6LzXb5bpGQZ9vTVtmMSoUfh4Pay3C31qDZPMm1ppYsEd00HVOQVKzVeeoTcIh8JPlJcx07bb4g==","shasum":"e80a1d35d0ae9e4bd5f5b7af75abbcbfda47b927","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.208.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDkLs8RBsaQ+zlMSsV4AJo5FY37bDNcq2rwk2c802HpPgIgdcUSJhJddycb/AAU1QOB07aRdrWJX0Ry9KBCWJ2pnhA="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.208_1686241391103_0.596621893412979"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.209":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.209","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.209+fdfd5f60","@latticexyz/recs":"2.0.0-alpha.1.209+fdfd5f60","@latticexyz/schema-type":"2.0.0-alpha.1.209+fdfd5f60","@latticexyz/services":"2.0.0-alpha.1.209+fdfd5f60","@latticexyz/solecs":"2.0.0-alpha.1.209+fdfd5f60","@latticexyz/store":"2.0.0-alpha.1.209+fdfd5f60","@latticexyz/utils":"2.0.0-alpha.1.209+fdfd5f60","@latticexyz/world":"2.0.0-alpha.1.209+fdfd5f60","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"fdfd5f6098d44ecee283719ba15f99ef6af306c9","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.209","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-muXglnPntMcuP12EZ6baHi/Zmbwbuh6/LG0Gcb8+jIsACDybfWOR1rgidfYqSEHmnrqxxdpxNDwnj01gD0p0wg==","shasum":"4d5449ae9b2f717af74cfaf06784f90961ed5a58","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.209.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC/BXdSiH9/LLgEEfiVsoIvJOsERWtyuYbmjIKOwjjCuQIhAIeaiqAoxE9Mba2Lk1wxlbmAqNR91fg4oBfgY0CNpPjj"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.209_1686242634913_0.8166414379793863"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.210":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.210","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.210+69c126a9","@latticexyz/recs":"2.0.0-alpha.1.210+69c126a9","@latticexyz/schema-type":"2.0.0-alpha.1.210+69c126a9","@latticexyz/services":"2.0.0-alpha.1.210+69c126a9","@latticexyz/solecs":"2.0.0-alpha.1.210+69c126a9","@latticexyz/store":"2.0.0-alpha.1.210+69c126a9","@latticexyz/utils":"2.0.0-alpha.1.210+69c126a9","@latticexyz/world":"2.0.0-alpha.1.210+69c126a9","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"69c126a9e3d95a451b88d36c50e30279cc628a9d","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.210","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-7vwt1CNv2H9XoKKHnEyIwzpyd5stdTlZ2RMBXzNQKBgnkwrVZy/zpMKqphLl17HSITEgAEne4alwjghateGnnw==","shasum":"0d8b7cef5657fc52a7d8ff611ecc6e2241f191b1","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.210.tgz","fileCount":79,"unpackedSize":489636,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBhw6TaX27NNfCpGMMb28RZ6OGswb+bJO+nP0r7ZEdghAiEAu+MTnsZprU50J544lqrzpAR8wa1aq1W9ZqaDhY8NV1Y="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.210_1686246033976_0.5812631860281563"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.211":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.211","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.211+80a9a33b","@latticexyz/recs":"2.0.0-alpha.1.211+80a9a33b","@latticexyz/schema-type":"2.0.0-alpha.1.211+80a9a33b","@latticexyz/services":"2.0.0-alpha.1.211+80a9a33b","@latticexyz/solecs":"2.0.0-alpha.1.211+80a9a33b","@latticexyz/store":"2.0.0-alpha.1.211+80a9a33b","@latticexyz/utils":"2.0.0-alpha.1.211+80a9a33b","@latticexyz/world":"2.0.0-alpha.1.211+80a9a33b","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"80a9a33bc79f22d347f72c7ba9d99a11f40e7fcd","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.211","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-IQ19Q8oJCwImKqoaWX+gGDqeGIvaONieA8Rai6T/640ugIddZViFk7dKveQbXmfb0EO/VEGZGwHswlG49ZWecA==","shasum":"bb4b6379b7a2b4e5e5de0cd3f5c1642901eef976","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.211.tgz","fileCount":80,"unpackedSize":486240,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCqMObDLXru8mYLF8ECdDdWevWCSLURtipV81rIJxXsCQIhAI0UZ4DXA7TEgWExaUwlQNRYySfZeCoJdYMS6vQN8kAF"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.211_1686248884174_0.6930452058474232"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.212":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.212","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.212+22efa6ed","@latticexyz/recs":"2.0.0-alpha.1.212+22efa6ed","@latticexyz/schema-type":"2.0.0-alpha.1.212+22efa6ed","@latticexyz/services":"2.0.0-alpha.1.212+22efa6ed","@latticexyz/solecs":"2.0.0-alpha.1.212+22efa6ed","@latticexyz/store":"2.0.0-alpha.1.212+22efa6ed","@latticexyz/utils":"2.0.0-alpha.1.212+22efa6ed","@latticexyz/world":"2.0.0-alpha.1.212+22efa6ed","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"22efa6ed561c9bfdbb23b9172b23b675a8c28cc9","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.212","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-0sdfpKOiDaV1vemWkEogzJbJNXlF2T0I86YeVF11SF1FFtLmvTkB6FfjaS3HiL70YNyE1rIOicefL/Gsg5ieRw==","shasum":"8b7dcbee351feb3952f8312c7ae85c4888f3e422","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.212.tgz","fileCount":80,"unpackedSize":486240,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH0WHPBp5W/k9Q4Z5KSA1v9yr+OUdH1z9SO0e2bVe0ytAiEA5drsyor4QbtbAhU+50+Drdo7cUe076HSDlhNNujVgDU="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.212_1686261626303_0.038589677072777606"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.213":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.213","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.213+282cc43c","@latticexyz/recs":"2.0.0-alpha.1.213+282cc43c","@latticexyz/schema-type":"2.0.0-alpha.1.213+282cc43c","@latticexyz/services":"2.0.0-alpha.1.213+282cc43c","@latticexyz/solecs":"2.0.0-alpha.1.213+282cc43c","@latticexyz/store":"2.0.0-alpha.1.213+282cc43c","@latticexyz/utils":"2.0.0-alpha.1.213+282cc43c","@latticexyz/world":"2.0.0-alpha.1.213+282cc43c","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"282cc43cfbbb0bafa1f4ddd3d5ec12e80a9e53e3","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.213","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-+4O29A4fmAhyYgLa/8caXDSh4d1tLEC+ryTcjym2OZ6lwltXE64iHi9xCjD0ES9+JC0isMHg4SDpMUCeB78cRg==","shasum":"8e1a4952cdaeaee8be62ee2890df094c8677f366","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.213.tgz","fileCount":80,"unpackedSize":486240,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGQpHQZzxPoyT7XzglYV/UdBrJbjxlJ9aBaF0d3L753fAiAPjqqcKyuqUp79EjLoSDeYJutD4HgHjYMcaZsJO+ZvXQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.213_1686589728271_0.4913156595870187"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.214":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.214","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.214+d3c3cd4c","@latticexyz/recs":"2.0.0-alpha.1.214+d3c3cd4c","@latticexyz/schema-type":"2.0.0-alpha.1.214+d3c3cd4c","@latticexyz/services":"2.0.0-alpha.1.214+d3c3cd4c","@latticexyz/solecs":"2.0.0-alpha.1.214+d3c3cd4c","@latticexyz/store":"2.0.0-alpha.1.214+d3c3cd4c","@latticexyz/utils":"2.0.0-alpha.1.214+d3c3cd4c","@latticexyz/world":"2.0.0-alpha.1.214+d3c3cd4c","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"d3c3cd4ca2f5521b41a0046bda6e6191d2c4b682","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.214","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-14FiDHtutUW91Y5qHiDWaA6U8B60q5Nub/EOktuecaJgbDyae+e2YQDpOgm4m6gV64qGlZedP+3BXrdqyIhiCg==","shasum":"922c7d26e86ac168b0f73ca9b6756c5cbede6766","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.214.tgz","fileCount":80,"unpackedSize":486240,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHhAzVfNr1Z5EjyT9kBfLSthXAOvOloAuVXH1hG2juGjAiEAjLpgfhDskVA/EL3kI05rLKf2eixhkh/n+Ra26pJKkJY="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.214_1686591864815_0.17840449987343643"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.215":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.215","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.215+a2342969","@latticexyz/recs":"2.0.0-alpha.1.215+a2342969","@latticexyz/schema-type":"2.0.0-alpha.1.215+a2342969","@latticexyz/services":"2.0.0-alpha.1.215+a2342969","@latticexyz/solecs":"2.0.0-alpha.1.215+a2342969","@latticexyz/store":"2.0.0-alpha.1.215+a2342969","@latticexyz/utils":"2.0.0-alpha.1.215+a2342969","@latticexyz/world":"2.0.0-alpha.1.215+a2342969","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"a234296986869f498be90a4944b1d4659be9139a","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.215","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-NqytrdGKRGVeXsdLTpOmQC2RiILhEqnjv2skS3XPF3LWOGpqqMGMojxCLpke2y3/2zBmryMfQlAte6U+IqeZuA==","shasum":"295a847f6fc1bd9d5c35c3e1b65b33560f35ecbf","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.215.tgz","fileCount":80,"unpackedSize":486240,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDXp2SA1meTl/ecwn/wRWSsKQIU0uOQ91l8eo3arak3/wIgdIOvjqWJrOQrilvzBIVtuXYEGmfMw5/T1paBX/IdhTM="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.215_1686592619892_0.02331133268858876"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.216":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.216","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.216+2908c80c","@latticexyz/recs":"2.0.0-alpha.1.216+2908c80c","@latticexyz/schema-type":"2.0.0-alpha.1.216+2908c80c","@latticexyz/services":"2.0.0-alpha.1.216+2908c80c","@latticexyz/solecs":"2.0.0-alpha.1.216+2908c80c","@latticexyz/store":"2.0.0-alpha.1.216+2908c80c","@latticexyz/utils":"2.0.0-alpha.1.216+2908c80c","@latticexyz/world":"2.0.0-alpha.1.216+2908c80c","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"2908c80c37f09e430991a50ded40d1abcef964f0","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.216","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-fz6AMoA+xRyeZddXdYQTIqtLpYB88L2ROrJduX90l/MPOUym5RV0m401FWweYpVKKlaJDNTtJdezHmm31WfERw==","shasum":"33e4cd70ce727a1272763844322e220d10d3b569","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.216.tgz","fileCount":80,"unpackedSize":486087,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD2pzwu5XFLlqo6GmSWfUwYjEBZKE5YQEnVnMPlJR93vwIgIUknp4swAk21f9i/RpqsOYEJskaR8NREpAQgUvbrwOs="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.216_1686597109742_0.786398757917419"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.217":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.217","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.217+5fda2d7b","@latticexyz/recs":"2.0.0-alpha.1.217+5fda2d7b","@latticexyz/schema-type":"2.0.0-alpha.1.217+5fda2d7b","@latticexyz/services":"2.0.0-alpha.1.217+5fda2d7b","@latticexyz/solecs":"2.0.0-alpha.1.217+5fda2d7b","@latticexyz/store":"2.0.0-alpha.1.217+5fda2d7b","@latticexyz/utils":"2.0.0-alpha.1.217+5fda2d7b","@latticexyz/world":"2.0.0-alpha.1.217+5fda2d7b","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5fda2d7bc8a3715fb091bb27c4140bb1ccc60957","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.217","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-G6UfLLpjuDZM0weM3buBj+2K1NAjgaT1P234yMOUYGgjNBygTM7eDvGRLDQKCn1T6pGlSejjG3vg/1Mdi8Gu6g==","shasum":"925eebb42c7f3052289ec6161c54ba736c92439c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.217.tgz","fileCount":80,"unpackedSize":486087,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDUXSW3r6EP1WDr5q94BxoygmWnSVuLXaUqfFFpkch2FAIhANhJ8G1vygDruPTrFHur99E4gpbo5f83C6EzaCZQhWJQ"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.217_1686671598868_0.5300050142820736"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.218":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.218","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.218+1025ce0a","@latticexyz/recs":"2.0.0-alpha.1.218+1025ce0a","@latticexyz/schema-type":"2.0.0-alpha.1.218+1025ce0a","@latticexyz/services":"2.0.0-alpha.1.218+1025ce0a","@latticexyz/solecs":"2.0.0-alpha.1.218+1025ce0a","@latticexyz/store":"2.0.0-alpha.1.218+1025ce0a","@latticexyz/utils":"2.0.0-alpha.1.218+1025ce0a","@latticexyz/world":"2.0.0-alpha.1.218+1025ce0a","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"^0.3.18"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"1025ce0a29efcfc9fbb50a8f88a9cd5ea740849c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.218","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-jvmckFcrPzpiFKsYWGT7dsWLhvQ/oBN1ab1Mh+Xo9bEfNgh23gBT5VlGEPqDKc78lKA5w8iCdi2A5SVA+3tq5w==","shasum":"6e7b7b5bdd0f9e47e8593ec2ad11fcaae6a57b77","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.218.tgz","fileCount":80,"unpackedSize":486087,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFaU6kIeXvilqJbGAtx2KclPSCCzieuQ62xz2pqH7GFkAiEAz+3PZH7kmK9Sb1k2rSSXNfJr90evWwoeHqhj/0TI28E="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.218_1686675564415_0.9445527984708755"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.221":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.221","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.221+ee17fc75","@latticexyz/recs":"2.0.0-alpha.1.221+ee17fc75","@latticexyz/schema-type":"2.0.0-alpha.1.221+ee17fc75","@latticexyz/services":"2.0.0-alpha.1.221+ee17fc75","@latticexyz/solecs":"2.0.0-alpha.1.221+ee17fc75","@latticexyz/store":"2.0.0-alpha.1.221+ee17fc75","@latticexyz/utils":"2.0.0-alpha.1.221+ee17fc75","@latticexyz/world":"2.0.0-alpha.1.221+ee17fc75","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"ee17fc756ac96cfdac2d7baaabe5b65b4267bc5c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.221","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-azEHOTq08Up2vOqstRmFWfSZ7s70XU1JEJEJxfSi+N3R58lR0O8ySMvenKX0lWDlG7UX4r1YCEGujX9Agbi9iQ==","shasum":"889a262ee7bae85f9f033c5cf14adcb4a98e1020","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.221.tgz","fileCount":80,"unpackedSize":486085,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCPVdGwPV7OIpAAVlInX5c8HBj6hQSl5rx7xSudYCUhHwIgCQku5076WfRdQjN4oaE+bDJlUvP6O/SupHHhNLkNJh0="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.221_1686679082843_0.27088332271632143"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.222":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.222","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.222+7c2d6351","@latticexyz/recs":"2.0.0-alpha.1.222+7c2d6351","@latticexyz/schema-type":"2.0.0-alpha.1.222+7c2d6351","@latticexyz/services":"2.0.0-alpha.1.222+7c2d6351","@latticexyz/solecs":"2.0.0-alpha.1.222+7c2d6351","@latticexyz/store":"2.0.0-alpha.1.222+7c2d6351","@latticexyz/utils":"2.0.0-alpha.1.222+7c2d6351","@latticexyz/world":"2.0.0-alpha.1.222+7c2d6351","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"7c2d6351294741009c6631441b5395cddef4aabc","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.222","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-LY5GbycaQQfSSdho9/63Dk79BiMcAkqFdONAbLin2ii3mJ7wREPQ/KWUA7834/RnrewaNjdrQ+krKR3udvkbTQ==","shasum":"af45388c0ffd4de11ae1f44b4f51b6d3b3b4aac8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.222.tgz","fileCount":80,"unpackedSize":486085,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD37MbBUgvOUNzqHQ260oa5P9Ajp97UFktsLtBFQEuHcQIgXDy6QyvMLriRNiLlL6r9PF6DQMgesFDoX04SeoqLzzA="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.222_1686682599153_0.6137492419654047"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.223":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.223","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.223+43a75626","@latticexyz/recs":"2.0.0-alpha.1.223+43a75626","@latticexyz/schema-type":"2.0.0-alpha.1.223+43a75626","@latticexyz/services":"2.0.0-alpha.1.223+43a75626","@latticexyz/solecs":"2.0.0-alpha.1.223+43a75626","@latticexyz/store":"2.0.0-alpha.1.223+43a75626","@latticexyz/utils":"2.0.0-alpha.1.223+43a75626","@latticexyz/world":"2.0.0-alpha.1.223+43a75626","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"43a75626592e01a1a2fa2351ebc75541a64f0d18","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.223","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-QZp5Ykb2Yq8ydS+iYVIKeZgSlWDchjpkb863GkHJt9iVBj+aTgKdYCpRknwtntQYLIIq9nPSp7vlzFf977Ituw==","shasum":"2143095c489af66b27ea9f94589a65ceec8e3646","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.223.tgz","fileCount":80,"unpackedSize":486085,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFFHt8t9sTe8bJ7+DnnnUlMTpOOe++vvE62jvZT79MqGAiEApk0B+eE5R8Ysy7TxlMwNL6BW7t+EGShIKGhZjgnXLVY="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.223_1686806158048_0.42259170295708026"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.224":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.224","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.224+5bfad00f","@latticexyz/recs":"2.0.0-alpha.1.224+5bfad00f","@latticexyz/schema-type":"2.0.0-alpha.1.224+5bfad00f","@latticexyz/services":"2.0.0-alpha.1.224+5bfad00f","@latticexyz/solecs":"2.0.0-alpha.1.224+5bfad00f","@latticexyz/store":"2.0.0-alpha.1.224+5bfad00f","@latticexyz/utils":"2.0.0-alpha.1.224+5bfad00f","@latticexyz/world":"2.0.0-alpha.1.224+5bfad00f","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5bfad00fbd07a18639c3945117cae4aa9ff3626f","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.224","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-Pxmm48LJN5GbEVWXKQxXbsU+TD6ePInVtsCNUR84HtrdPjCYQXAwr0nWiVo02/+NUXTrto54psTLRcDZwgm8TA==","shasum":"aebeea789180f00019549ce140f4c269bab83c99","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.224.tgz","fileCount":80,"unpackedSize":486085,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDOC5mPfQKgLXxMSDp9B/8ugJV4nZ/cJbxVdMnlaI3dlgIgNNSUq303GY+pCouwM7aFdwvTx4LFdtSolOEkuRUXWNY="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.224_1686844075687_0.681532452068619"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.225":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.225","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.225+5f05b8a9","@latticexyz/recs":"2.0.0-alpha.1.225+5f05b8a9","@latticexyz/schema-type":"2.0.0-alpha.1.225+5f05b8a9","@latticexyz/services":"2.0.0-alpha.1.225+5f05b8a9","@latticexyz/solecs":"2.0.0-alpha.1.225+5f05b8a9","@latticexyz/store":"2.0.0-alpha.1.225+5f05b8a9","@latticexyz/utils":"2.0.0-alpha.1.225+5f05b8a9","@latticexyz/world":"2.0.0-alpha.1.225+5f05b8a9","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5f05b8a9625d830a7689d92c27ad3fae267f4b43","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.225","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-qK18k37t0jAmOVZO+0Khu6fgUEi0Vk7pwHq4TKAI+T7nNhv2RoGpsKNAzhkRsMBzmCDri+rbCsu96XueN5dW1g==","shasum":"4f1dcc8ebb320412a5c66db5bc99320ca87f51cb","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.225.tgz","fileCount":80,"unpackedSize":486085,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFCn2sOOvczC5XcQUSfVyaiw/bnbEwhA/GWHQL/fzaaLAiEAvsBWZlLzFJEOJBOQupFcxLJXW/nt7nb5iUMIxRrPeMU="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.225_1686844964864_0.842402685444156"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.226":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.226","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.226+b86c5d1a","@latticexyz/recs":"2.0.0-alpha.1.226+b86c5d1a","@latticexyz/schema-type":"2.0.0-alpha.1.226+b86c5d1a","@latticexyz/services":"2.0.0-alpha.1.226+b86c5d1a","@latticexyz/solecs":"2.0.0-alpha.1.226+b86c5d1a","@latticexyz/store":"2.0.0-alpha.1.226+b86c5d1a","@latticexyz/utils":"2.0.0-alpha.1.226+b86c5d1a","@latticexyz/world":"2.0.0-alpha.1.226+b86c5d1a","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"b86c5d1a2a14b225c5a8b3b8e8427c8501bcbdf9","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.226","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-6C8X1eof88eNY9MLg7Mb4YbQe4Ow1DtBx0OWL7UUiPTL2maaRHbEudtI38nul9Ji0GgNfMrG1KmpmoVOqcuE9w==","shasum":"a13b4b7e743fac1220b377933e40a4380280e916","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.226.tgz","fileCount":80,"unpackedSize":486085,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB0cODCcWasBYd1viXkrdJ1LdIDK2daePmudQPzlhpxSAiA0w+oNORl86XQzNHzNPaVXuuY26ljGrgMgqJpkSypuew=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.226_1686913597697_0.7648181114301633"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.227":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.227","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.227+1525c1a0","@latticexyz/recs":"2.0.0-alpha.1.227+1525c1a0","@latticexyz/schema-type":"2.0.0-alpha.1.227+1525c1a0","@latticexyz/services":"2.0.0-alpha.1.227+1525c1a0","@latticexyz/solecs":"2.0.0-alpha.1.227+1525c1a0","@latticexyz/store":"2.0.0-alpha.1.227+1525c1a0","@latticexyz/utils":"2.0.0-alpha.1.227+1525c1a0","@latticexyz/world":"2.0.0-alpha.1.227+1525c1a0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"1525c1a02c715f5c61a03c850fae0a6ccd1d504a","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.227","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-RC0OsB56OUX7gffKoIpYJlBDEzug/NWGlYU/arhxUMRSjvamI3l/sb59OVyCZurecmcAmIocssU10so8yJVg6A==","shasum":"0e28329835596d61c59fe0a69ad0ebf35e74e8fa","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.227.tgz","fileCount":80,"unpackedSize":486991,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDdwuckfrrVfZ3fBb2Q+Q/XeJ7xF/bch/FUVeMwaGcJSgIhAIEfYi6Xj/9qolbQ9Ojz5K0Ed6CGRdd/wTtFZkKNoYRn"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.227_1686913666165_0.17978923296437843"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.228":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.228","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.228+770bdaaa","@latticexyz/recs":"2.0.0-alpha.1.228+770bdaaa","@latticexyz/schema-type":"2.0.0-alpha.1.228+770bdaaa","@latticexyz/services":"2.0.0-alpha.1.228+770bdaaa","@latticexyz/solecs":"2.0.0-alpha.1.228+770bdaaa","@latticexyz/store":"2.0.0-alpha.1.228+770bdaaa","@latticexyz/utils":"2.0.0-alpha.1.228+770bdaaa","@latticexyz/world":"2.0.0-alpha.1.228+770bdaaa","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"770bdaaa22321c4c87f2cafb44691d45d9251b08","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.228","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-TcKpv3fkmua739Vkwg6RYfuRPhS2cM8JdL8LpzisTvo2taU/qMU7aH/mx7Xg0+2O/YOVpyf0UlcaS/WwYnRYFg==","shasum":"c99fea17b50c64cbbfcda751240c2680d419d14d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.228.tgz","fileCount":80,"unpackedSize":486991,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC378I2cnckFpwa/6FMVxgXmrYt6JVwiFD8LqP1OZcCiAiEAvOz2KcnLCQNlspfZlfsGHJom5vrjlpUDWUwomDMDRUo="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.228_1686915019744_0.2948179781973017"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.229":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.229","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.229+c3b75ced","@latticexyz/recs":"2.0.0-alpha.1.229+c3b75ced","@latticexyz/schema-type":"2.0.0-alpha.1.229+c3b75ced","@latticexyz/services":"2.0.0-alpha.1.229+c3b75ced","@latticexyz/solecs":"2.0.0-alpha.1.229+c3b75ced","@latticexyz/store":"2.0.0-alpha.1.229+c3b75ced","@latticexyz/utils":"2.0.0-alpha.1.229+c3b75ced","@latticexyz/world":"2.0.0-alpha.1.229+c3b75ced","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"c3b75cedd014f541849709315f1852a0b9a92630","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.229","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-OF73lbfIjmRMTb9D+Nx5ymW778+MNKuozSHjEmEEAMuBQUQr2up4MZTnmqCMuG/X8aOV0Ssg3NrfbFuv8kNjSQ==","shasum":"8eed933ffa4831bc6922de71a76e462f5332d777","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.229.tgz","fileCount":80,"unpackedSize":486991,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBVLCOqmEZtRgGvvMl4iJocm4NcAzrRNlV52RU5P9wFdAiA+DtgwQUoPLjVkdhQnmUgCDt/s5hTvgNdKUTKKxihlKQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.229_1686916690974_0.2439581257356005"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.230":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.230","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.230+02043cb5","@latticexyz/recs":"2.0.0-alpha.1.230+02043cb5","@latticexyz/schema-type":"2.0.0-alpha.1.230+02043cb5","@latticexyz/services":"2.0.0-alpha.1.230+02043cb5","@latticexyz/solecs":"2.0.0-alpha.1.230+02043cb5","@latticexyz/store":"2.0.0-alpha.1.230+02043cb5","@latticexyz/utils":"2.0.0-alpha.1.230+02043cb5","@latticexyz/world":"2.0.0-alpha.1.230+02043cb5","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"02043cb5dd7a50d0ce18ecc5210fa69b35f66be4","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.230","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-H4aMk+uGseOSHg/u5YIuqZKJd2gP2QI8ARDzbwDW4ptfDKQ9n0512M/WXt2RbR2vXcnRrYbusco64X2N4QEz9A==","shasum":"6e25720ff5fd1b29afebfcdb0e9094ccfb6ef76c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.230.tgz","fileCount":80,"unpackedSize":486991,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCv8cvzufmku2jkLxZVxQUGH+3sHEGgjEqDNVXvuc1aAwIgbzU7Vr7MjBHRO37PBSXLAIV+MSGhYsTTtvZCixJO12I="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.230_1686919322466_0.7594674923926663"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.231":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.231","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.231+5a4e28a7","@latticexyz/recs":"2.0.0-alpha.1.231+5a4e28a7","@latticexyz/schema-type":"2.0.0-alpha.1.231+5a4e28a7","@latticexyz/services":"2.0.0-alpha.1.231+5a4e28a7","@latticexyz/solecs":"2.0.0-alpha.1.231+5a4e28a7","@latticexyz/store":"2.0.0-alpha.1.231+5a4e28a7","@latticexyz/utils":"2.0.0-alpha.1.231+5a4e28a7","@latticexyz/world":"2.0.0-alpha.1.231+5a4e28a7","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5a4e28a7aaa09a584a0804580dd305815e7e4e3b","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.231","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-nZ+T8bBub7xjmwF3z0ITxaGLph4cfNv69Qw4JjCye1ZqFpYnNumXj8MDHxG6CI1xcuDjYdg4vvPg4sJkDoc2LA==","shasum":"f0730dedc305e8a65bccee13e300394d603f5500","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.231.tgz","fileCount":80,"unpackedSize":486991,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG1fXTmzRZVOmBEq49Eag71EkIbrvpyjnfd4NYPWbcr4AiABSS0OZAv3SGohcx0NNObuzCWrsHdGsekSFXATk4zm/g=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.231_1686924072050_0.4520002791309876"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.232":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.232","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.232+3d6b0917","@latticexyz/recs":"2.0.0-alpha.1.232+3d6b0917","@latticexyz/schema-type":"2.0.0-alpha.1.232+3d6b0917","@latticexyz/services":"2.0.0-alpha.1.232+3d6b0917","@latticexyz/solecs":"2.0.0-alpha.1.232+3d6b0917","@latticexyz/store":"2.0.0-alpha.1.232+3d6b0917","@latticexyz/utils":"2.0.0-alpha.1.232+3d6b0917","@latticexyz/world":"2.0.0-alpha.1.232+3d6b0917","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"3d6b0917f2a722e3207b1e306396caa3042f1ace","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.232","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-vzG6bXYF4xQqRzkeQmyp4u5QAY45YlPfRDjA4b+u+cSOB1NriTe7md1ZS+LEO3qmxwScKrWNMpoG2Ym0x0YAOw==","shasum":"38627e48be24ae56210e0de425d5dd88286653ec","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.232.tgz","fileCount":80,"unpackedSize":486991,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA49l+UfVzuCq8E594GJN+93ggLINmONaA86yMjm9lAuAiEAxWRfT23IBTnnXtL9Ubu+WHGMT5sGpLP+Efuoutisgxs="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.232_1686924714507_0.1770791051183147"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.233":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.233","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.233+82d8dd9d","@latticexyz/recs":"2.0.0-alpha.1.233+82d8dd9d","@latticexyz/schema-type":"2.0.0-alpha.1.233+82d8dd9d","@latticexyz/services":"2.0.0-alpha.1.233+82d8dd9d","@latticexyz/solecs":"2.0.0-alpha.1.233+82d8dd9d","@latticexyz/store":"2.0.0-alpha.1.233+82d8dd9d","@latticexyz/utils":"2.0.0-alpha.1.233+82d8dd9d","@latticexyz/world":"2.0.0-alpha.1.233+82d8dd9d","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"82d8dd9dae040fd163c2039fa0e42fd95e8ce5b5","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.233","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-09MFuP1voTlowPiAg5qjAi2FyVu8OuiH91jR54a4c9gTzox794Mnv2gK1EfzmmS+eC+4Iz/df3UsZETsU9zTJA==","shasum":"815b02d0f81b1f9f78292c2326da7ee0911ad993","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.233.tgz","fileCount":80,"unpackedSize":486991,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC+89sv7eqNz7IhsViSWK2n1nqB7zjxgiH6PWHEsugbcgIhAJA35sX1Lzs/6/EaNr13hO0Ay7gXqZd5h5V7F7Eu3Y4j"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.233_1686926114609_0.9010798758990812"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.234":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.234","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.234+18606e3b","@latticexyz/recs":"2.0.0-alpha.1.234+18606e3b","@latticexyz/schema-type":"2.0.0-alpha.1.234+18606e3b","@latticexyz/services":"2.0.0-alpha.1.234+18606e3b","@latticexyz/solecs":"2.0.0-alpha.1.234+18606e3b","@latticexyz/store":"2.0.0-alpha.1.234+18606e3b","@latticexyz/utils":"2.0.0-alpha.1.234+18606e3b","@latticexyz/world":"2.0.0-alpha.1.234+18606e3b","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"18606e3bada1cadf12a0aadbad66c5d991790fb5","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.234","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-Yx8Yi1KkA7TvE28gsPOQeXOQeObiCCIyUkzOmRewWl+t9eTGGP30jLpK3UVXvv9utID0kaKZV5KVgGm5B6i6hw==","shasum":"bd0818acd4437e12160460ec06a2b798da15882a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.234.tgz","fileCount":80,"unpackedSize":486991,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD9+WfWTei+KxXUMKNDCz8Ypq1C+OoXSiZZtFK2w7p0VQIhAMN1OikYmv1stChnoad3Tq7u9JZgwamQwoCYgNikh2f9"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.234_1686933875779_0.9147197401299219"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.235":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.235","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.235+8aafafa3","@latticexyz/recs":"2.0.0-alpha.1.235+8aafafa3","@latticexyz/schema-type":"2.0.0-alpha.1.235+8aafafa3","@latticexyz/services":"2.0.0-alpha.1.235+8aafafa3","@latticexyz/solecs":"2.0.0-alpha.1.235+8aafafa3","@latticexyz/store":"2.0.0-alpha.1.235+8aafafa3","@latticexyz/utils":"2.0.0-alpha.1.235+8aafafa3","@latticexyz/world":"2.0.0-alpha.1.235+8aafafa3","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"8aafafa34b5576c914ed80e08ea14580a4cacb0d","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.235","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-bBudplvvPdCa7nfcwootvKayRa6IR3b4cuFbdpBOon6dw8OksBOcGx25xnkchcZKdtJZLj299+gl2rC6QCxwjQ==","shasum":"6a27293866318742a4efd833694b1f41237bf2f0","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.235.tgz","fileCount":80,"unpackedSize":486991,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEbAfkJWBr9dqBhSIWSV5n0SO+RzWE86KnmHIsoghGmrAiBi386cynBW4iUJ+/3w0+EK+yMcMTraUcwgW2cEmyoGnA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.235_1686934294524_0.5722289502534388"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.236":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.236","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.236+b62be9d2","@latticexyz/recs":"2.0.0-alpha.1.236+b62be9d2","@latticexyz/schema-type":"2.0.0-alpha.1.236+b62be9d2","@latticexyz/services":"2.0.0-alpha.1.236+b62be9d2","@latticexyz/solecs":"2.0.0-alpha.1.236+b62be9d2","@latticexyz/store":"2.0.0-alpha.1.236+b62be9d2","@latticexyz/utils":"2.0.0-alpha.1.236+b62be9d2","@latticexyz/world":"2.0.0-alpha.1.236+b62be9d2","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"b62be9d2d11bf2ea3284454b9103a08edff19a58","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.236","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-A9VvJYdlKtMBccpOdC4LF/h+38fSL++Km8JvGn/wj4c2EUNddR9ttkP61kwhfDgaojoh8uZ7GjCDNLkDprvQyw==","shasum":"99655a05200dc5d4bf95b1542833d92ec28284d8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.236.tgz","fileCount":80,"unpackedSize":486991,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGsPlsfwVNbAIh+uOIB47WzWAyxfIEM0Z/0mnMHtkAmqAiAPwxvnj6J9fc9FhLL9nJlYq6v03WNOitjGL2S09kEgNQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.236_1686934745240_0.9548468885763255"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.237":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.237","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.237+5f34d52d","@latticexyz/recs":"2.0.0-alpha.1.237+5f34d52d","@latticexyz/schema-type":"2.0.0-alpha.1.237+5f34d52d","@latticexyz/services":"2.0.0-alpha.1.237+5f34d52d","@latticexyz/solecs":"2.0.0-alpha.1.237+5f34d52d","@latticexyz/store":"2.0.0-alpha.1.237+5f34d52d","@latticexyz/utils":"2.0.0-alpha.1.237+5f34d52d","@latticexyz/world":"2.0.0-alpha.1.237+5f34d52d","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5f34d52dbea3e83eafe0ff06deebe3b7af2f3abc","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.237","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-Hv4kJ63OhEgrzHD8lnvGJC8t6l4pMpYGDt9Ss3Iy0hRq9nTa+ghkeobbZrZwbaUzhebcmrQrOmjOYoB9j6sH8Q==","shasum":"2e5fdb2b748dbf4887afb7aaa7148068b8f359db","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.237.tgz","fileCount":80,"unpackedSize":486991,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHetPkraKbBBeszFlFx+g8qBIeQ1+TW0mYI1IhuTtS8NAiBjSfEbKcNHcUDVNp4/1PbTei+VD4fuO9kop2gULVbhjQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.237_1686934892824_0.7724424225857738"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.238":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.238","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.238+36f52988","@latticexyz/recs":"2.0.0-alpha.1.238+36f52988","@latticexyz/schema-type":"2.0.0-alpha.1.238+36f52988","@latticexyz/services":"2.0.0-alpha.1.238+36f52988","@latticexyz/solecs":"2.0.0-alpha.1.238+36f52988","@latticexyz/store":"2.0.0-alpha.1.238+36f52988","@latticexyz/utils":"2.0.0-alpha.1.238+36f52988","@latticexyz/world":"2.0.0-alpha.1.238+36f52988","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"36f52988e4a93448edbd3d6468a6686f7466d5db","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.238","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-CJw2hPSRE6KgzOo5TH2v5UaxzYUu8mCfiDAmC6EEhc1Z0QtQaCn7AfIfOk1iDpMCA/tdfILmp6c6plQPJFEuvQ==","shasum":"a7553265ea5d44ade87672efcdaf832ca90fa900","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.238.tgz","fileCount":80,"unpackedSize":486991,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDKhmkwiqXpb5ZPaYggNX6dk9zY2lgKwwJ2aOVhotlJoQIgQqhSqDyUb9f8mIkI7kqOrHiBG3hoEB+lIhlHBZOJxPA="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.238_1686934904481_0.18381103160440548"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.239":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.239","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.239+5afabfac","@latticexyz/recs":"2.0.0-alpha.1.239+5afabfac","@latticexyz/schema-type":"2.0.0-alpha.1.239+5afabfac","@latticexyz/services":"2.0.0-alpha.1.239+5afabfac","@latticexyz/solecs":"2.0.0-alpha.1.239+5afabfac","@latticexyz/store":"2.0.0-alpha.1.239+5afabfac","@latticexyz/utils":"2.0.0-alpha.1.239+5afabfac","@latticexyz/world":"2.0.0-alpha.1.239+5afabfac","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"5afabfaca2755b3fe1869f6d8a614ac14836a4c2","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.239","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-YImXn0J9g8JeqxF+uKst2U3RbUMys02Z4WKy+0sAUBDZVfgaXfstEJ6wmZaNpFr/69dsACm0fRrGFooFVq6+lQ==","shasum":"e5da16f7c9e28985a8eef6b0cdc2c4b248d324ea","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.239.tgz","fileCount":80,"unpackedSize":490950,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICvtayssHbSAMDzdeMXdSqMQaRKzZH+EBbzO//k0rpEAAiAIyhDG/aCMrms/X8jN8eW0rjTarsGHXEAjT8Lmed4oXA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.239_1686944353758_0.40405651282736343"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.242":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.242","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.242+8c869bff","@latticexyz/recs":"2.0.0-alpha.1.242+8c869bff","@latticexyz/schema-type":"2.0.0-alpha.1.242+8c869bff","@latticexyz/services":"2.0.0-alpha.1.242+8c869bff","@latticexyz/solecs":"2.0.0-alpha.1.242+8c869bff","@latticexyz/store":"2.0.0-alpha.1.242+8c869bff","@latticexyz/utils":"2.0.0-alpha.1.242+8c869bff","@latticexyz/world":"2.0.0-alpha.1.242+8c869bff","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"8c869bff7a7d505ab00abb38110c72bb7436e4ef","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.242","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-SYiJzTA9ErP6nZUVx+KsMgCpZndT51qfRGUjLa1WA8YeTD664M7gWmqjibz2fJRBzn9n6q4hM5OlCF1vw7rRbg==","shasum":"a5a5093f9bbce370d2648714714ed3ac5be62ae3","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.242.tgz","fileCount":80,"unpackedSize":490950,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCysoSqJ59T8ATH7ZpTlXO+I+Z9sChjzXkiAaO4GjeD7AIgC/nBZzs3ISH+VkF0PJ5FxtFLQzwZUtt5erEJjciV6TQ="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.242_1686952822121_0.25128473247789307"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.243":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.243","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.243+fc3bd590","@latticexyz/recs":"2.0.0-alpha.1.243+fc3bd590","@latticexyz/schema-type":"2.0.0-alpha.1.243+fc3bd590","@latticexyz/services":"2.0.0-alpha.1.243+fc3bd590","@latticexyz/solecs":"2.0.0-alpha.1.243+fc3bd590","@latticexyz/store":"2.0.0-alpha.1.243+fc3bd590","@latticexyz/utils":"2.0.0-alpha.1.243+fc3bd590","@latticexyz/world":"2.0.0-alpha.1.243+fc3bd590","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"fc3bd590c5b3b9f10fe391c0a68e1e99d1dd34cc","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.243","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-ORpS1sF1SI1O0Bxu3nvoen5eDc0o7rF0YIpjPvTcx4Ost5F5L/31CdGedDppE23iLBJ0DwkBZDih0O5nk+kqEQ==","shasum":"b1bfbd4072115537bbcc60970e30c37c60efb184","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.243.tgz","fileCount":80,"unpackedSize":491330,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEnzzguvDf8vRzScuhmae5JWJ/dW1FjZJb2r279z5/mfAiAKhgpTFWvevdpjD4F1CPET4DilM4/HemelV2nF65BRug=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.243_1686953766033_0.2795118587136245"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.244":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.244","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.244+93f28516","@latticexyz/recs":"2.0.0-alpha.1.244+93f28516","@latticexyz/schema-type":"2.0.0-alpha.1.244+93f28516","@latticexyz/services":"2.0.0-alpha.1.244+93f28516","@latticexyz/solecs":"2.0.0-alpha.1.244+93f28516","@latticexyz/store":"2.0.0-alpha.1.244+93f28516","@latticexyz/utils":"2.0.0-alpha.1.244+93f28516","@latticexyz/world":"2.0.0-alpha.1.244+93f28516","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"93f285168d7ce8ec9fb2d06d68549b91f31be417","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.244","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-sOgFg/hZZrS5zaTAEEohL6Y9zvbNIgdk3McK8E4ucoK6dtQI/SgUfNVIoCdEr8heOk4E8s3ku0pSVCeUYL1nFA==","shasum":"67dc85c12ddd1b71ec6a37416af6aa7a664458d1","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.244.tgz","fileCount":80,"unpackedSize":491330,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFSBhdfs+jC3Mbmqrfu1dqfNyXuF4/+huXmhOxOgqK+lAiBdKBszdb1+F86wA70432Iz0eMRL6u6rH2tqlWtVaDcKw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.244_1687262506150_0.908150087851165"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.247":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.247","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.247+0f5d3100","@latticexyz/recs":"2.0.0-alpha.1.247+0f5d3100","@latticexyz/schema-type":"2.0.0-alpha.1.247+0f5d3100","@latticexyz/services":"2.0.0-alpha.1.247+0f5d3100","@latticexyz/solecs":"2.0.0-alpha.1.247+0f5d3100","@latticexyz/store":"2.0.0-alpha.1.247+0f5d3100","@latticexyz/utils":"2.0.0-alpha.1.247+0f5d3100","@latticexyz/world":"2.0.0-alpha.1.247+0f5d3100","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"0f5d310030349600f6fb612bcc3aec674d988d37","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.247","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-oUCs8Zh2NesyrQK13+of4a8r0fcWiEbtcKsBy7sb6cZK1DKd+RFV6ZfCKlHruVa78Nix4aTIGs1YSwKVa4atVQ==","shasum":"4b1d0cc74fe23ef974202c7939faf2cff8046e55","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.247.tgz","fileCount":80,"unpackedSize":491330,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICWHWtoQtZM24Al7EPb0FG8K4aG7RAqRYiXOzoXbGITOAiEA9Cshr9/LssoZX7rZhuotgJIbsJim/Kib8rZNntGVecg="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.247_1687282346365_0.2697433150310895"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.248":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.248","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.248+17ea07b6","@latticexyz/recs":"2.0.0-alpha.1.248+17ea07b6","@latticexyz/schema-type":"2.0.0-alpha.1.248+17ea07b6","@latticexyz/services":"2.0.0-alpha.1.248+17ea07b6","@latticexyz/solecs":"2.0.0-alpha.1.248+17ea07b6","@latticexyz/store":"2.0.0-alpha.1.248+17ea07b6","@latticexyz/utils":"2.0.0-alpha.1.248+17ea07b6","@latticexyz/world":"2.0.0-alpha.1.248+17ea07b6","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"17ea07b614d7bae295a6c58e1442a6af952c6c68","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.248","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-fu8F1dvhceh7IULlszugp985rJ9padYTbaZ3Rt+Lbb6HwXgiZ+hkc4/dwJFxzMWNWb7a5JdKD0Cr5ijmzGK63A==","shasum":"c4aeb783e7f060565fae0a2060b73a34869f93cf","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.248.tgz","fileCount":80,"unpackedSize":491128,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAHU6YeQYrVwCr51OSUyK/iifJ/XDbcS6Uuy2NT9IqrKAiBK4gt0k1ShGgJNkaobsDe2igxvHFhTFJaw/59JUB71jQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.248_1687513101060_0.1263688995076293"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.249":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.249","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.249+ba1d98fa","@latticexyz/recs":"2.0.0-alpha.1.249+ba1d98fa","@latticexyz/schema-type":"2.0.0-alpha.1.249+ba1d98fa","@latticexyz/services":"2.0.0-alpha.1.249+ba1d98fa","@latticexyz/solecs":"2.0.0-alpha.1.249+ba1d98fa","@latticexyz/store":"2.0.0-alpha.1.249+ba1d98fa","@latticexyz/utils":"2.0.0-alpha.1.249+ba1d98fa","@latticexyz/world":"2.0.0-alpha.1.249+ba1d98fa","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"ba1d98fa70307be9de2d14737991f9c85003453e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.249","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-QSz+cFUX/FxDPTJQEHHsdCZwsUhixwWfX8wp1N+ZoW6tmyNDFcILZ3vIeqS/XxCD6sabgBKEJ5H+j3+rPqGD+A==","shasum":"bba55296f79082af646e4778138f97f5903417ca","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.249.tgz","fileCount":80,"unpackedSize":491128,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDvm+TFgX4jbXRzVQDjLx1JdxovEmfNPX9B5tjJ0PD93AIhAOE9xzI5MbwqgzxW0CMCkSBsaP1Ujz+mpJQCjCXPzpUq"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.249_1687518388812_0.6517872739157184"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.250":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.250","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.250+6f8c2c4f","@latticexyz/recs":"2.0.0-alpha.1.250+6f8c2c4f","@latticexyz/schema-type":"2.0.0-alpha.1.250+6f8c2c4f","@latticexyz/services":"2.0.0-alpha.1.250+6f8c2c4f","@latticexyz/solecs":"2.0.0-alpha.1.250+6f8c2c4f","@latticexyz/store":"2.0.0-alpha.1.250+6f8c2c4f","@latticexyz/utils":"2.0.0-alpha.1.250+6f8c2c4f","@latticexyz/world":"2.0.0-alpha.1.250+6f8c2c4f","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"6f8c2c4f979158f5c111e0e6a8d083806fcd2557","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.250","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-OR/ig+noYYnpfRwsfjAdROCBH5cdu+0fxm6VWtjSnJOJXHpM6/xFogD+sIvAHtVafDJfs8ceWKYbauJ7RIA/jA==","shasum":"545a49f0c4ba5a2cca1bf142bc29d098da7ad02f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.250.tgz","fileCount":80,"unpackedSize":491128,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICTTrpPmCEyFNlIvTIzXCGhcqJ9AgA2Ci3fBGgR2reHgAiBvkr8F9az5SHeKw6rQ448Ta+/Gc0c+fcHqO9RCklUrCw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.250_1687521181918_0.3560013359477292"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.251":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.251","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.251+deda0235","@latticexyz/recs":"2.0.0-alpha.1.251+deda0235","@latticexyz/schema-type":"2.0.0-alpha.1.251+deda0235","@latticexyz/services":"2.0.0-alpha.1.251+deda0235","@latticexyz/solecs":"2.0.0-alpha.1.251+deda0235","@latticexyz/store":"2.0.0-alpha.1.251+deda0235","@latticexyz/utils":"2.0.0-alpha.1.251+deda0235","@latticexyz/world":"2.0.0-alpha.1.251+deda0235","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"^7.5.5","threads":"^1.7.0","viem":"1.0.6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"deda02355bf971e3bd41e54518df8b291e759df8","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.251","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-fkNWGyXynWqi1GulDgtclOwMfMomLtISrJAZcaBUeNkEpja06sx38bwTELm3vpwIIkRWsp3Ufyi0cue5/gP9Zw==","shasum":"f20e8f18de790a6a30701493d4db48b18c08e95b","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.251.tgz","fileCount":80,"unpackedSize":491128,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEe8I3keLKG3JEaoCD9dX3px8zWueo/p6eBVASEufKHEAiAV0cuyjYaYSY/WwHjFuJaKmaIGtgkFz/Q3bPegCqnXvg=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.251_1687623290230_0.06992454953591953"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.252":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.252","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.252+2bcc6dee","@latticexyz/recs":"2.0.0-alpha.1.252+2bcc6dee","@latticexyz/schema-type":"2.0.0-alpha.1.252+2bcc6dee","@latticexyz/services":"2.0.0-alpha.1.252+2bcc6dee","@latticexyz/solecs":"2.0.0-alpha.1.252+2bcc6dee","@latticexyz/store":"2.0.0-alpha.1.252+2bcc6dee","@latticexyz/utils":"2.0.0-alpha.1.252+2bcc6dee","@latticexyz/world":"2.0.0-alpha.1.252+2bcc6dee","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"2bcc6dee7ae3312678f32cd4db1154e4024a4a02","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.252","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-oK6GvGEqwicjCYiVO6cnRNw4fUa33FPNylDEoTFP3mUtgXOzkdpcNNuprKaevuuM3kxN11JzYQFl2pGiKmDhsQ==","shasum":"eb94cc90aadc5edcdfb7f4b02063a1075c3248e3","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.252.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD6LEw733+Y5rRgQJQw8EkdTuLNJ2PpmvgDr1wvZy1XjQIhAJUU2aR1i/2VbSz7W4EcNOVWWa2gA7Z4YKoaLav0cc7k"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.252_1687774237759_0.8206736446506924"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.253":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.253","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.253+77b940de","@latticexyz/recs":"2.0.0-alpha.1.253+77b940de","@latticexyz/schema-type":"2.0.0-alpha.1.253+77b940de","@latticexyz/services":"2.0.0-alpha.1.253+77b940de","@latticexyz/solecs":"2.0.0-alpha.1.253+77b940de","@latticexyz/store":"2.0.0-alpha.1.253+77b940de","@latticexyz/utils":"2.0.0-alpha.1.253+77b940de","@latticexyz/world":"2.0.0-alpha.1.253+77b940de","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"77b940de9a935f529c3c4ccd824b56bd278adba0","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.253","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-mo4F7NxKa2Z3o3XKizEuPV4Xmiu5EPYH0Vy5N7yU5HKpwQXdqk+9NyprxqMCPC5EYZWWH6sLXl2QpEiu5uHwQA==","shasum":"e7523b4d3e69f6a3d45e033429609e2fb43d9c85","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.253.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA5SGXA/G0Upq2Aht3ybMCIgCNqOfHNJXGJS/ll4u5+yAiB0y1s9NoyKc3b/1R9W4tm5fxX/308ecZJd61Pi+zRYVw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.253_1687777845642_0.3519307762039998"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.254":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.254","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.254+ddd17653","@latticexyz/recs":"2.0.0-alpha.1.254+ddd17653","@latticexyz/schema-type":"2.0.0-alpha.1.254+ddd17653","@latticexyz/services":"2.0.0-alpha.1.254+ddd17653","@latticexyz/solecs":"2.0.0-alpha.1.254+ddd17653","@latticexyz/store":"2.0.0-alpha.1.254+ddd17653","@latticexyz/utils":"2.0.0-alpha.1.254+ddd17653","@latticexyz/world":"2.0.0-alpha.1.254+ddd17653","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"ddd176536fc3080c5d6928183c48fd66a3acd24c","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.254","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-KZOOz0gz1VZZ5na+wXQPXe0Cjo0WBDStdeCtok9E+PLQ8z4HRQC9wkAqU88zpexWyGVJ2E4G0OvyeUjNqFCyWw==","shasum":"d16829e5c4be4a828d136a7ad716940a4c395bd2","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.254.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCvhxbg2SQwvW7Nqbq2h3Z2xJBVhzZ0N3ekRi35TFxIcgIgY5jUPOHqWPmZ4S0Jhr+bskqhZ5YYwIoqofRidZ4LI9s="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.254_1687787150571_0.29587950071890257"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.255":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.255","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.255+2094bf35","@latticexyz/recs":"2.0.0-alpha.1.255+2094bf35","@latticexyz/schema-type":"2.0.0-alpha.1.255+2094bf35","@latticexyz/services":"2.0.0-alpha.1.255+2094bf35","@latticexyz/solecs":"2.0.0-alpha.1.255+2094bf35","@latticexyz/store":"2.0.0-alpha.1.255+2094bf35","@latticexyz/utils":"2.0.0-alpha.1.255+2094bf35","@latticexyz/world":"2.0.0-alpha.1.255+2094bf35","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"2094bf35e0df6a69b893582ccb4e4e0d72fa9372","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.255","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-dfhBIagM6X6cHauC+r7/W77zu0RDn72Ivvzvs6ZATq1wB86XIhr5R5kfe+vqKLuOuIQzZhw2z1K+NBee9+W9PQ==","shasum":"627a98972a05ea9762cd8a3312f565acc7a70eaa","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.255.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCGQj1tQhIWtGCxt601XIO3xqUm+/souldVG2YZTLjFtwIgEVpsRkD9Jnbmh+rmS2RIeP4LWmlgJXBoxawlU2099Fc="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.255_1687793044549_0.4315217919783867"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.256":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.256","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.256+e3260c8a","@latticexyz/recs":"2.0.0-alpha.1.256+e3260c8a","@latticexyz/schema-type":"2.0.0-alpha.1.256+e3260c8a","@latticexyz/services":"2.0.0-alpha.1.256+e3260c8a","@latticexyz/solecs":"2.0.0-alpha.1.256+e3260c8a","@latticexyz/store":"2.0.0-alpha.1.256+e3260c8a","@latticexyz/utils":"2.0.0-alpha.1.256+e3260c8a","@latticexyz/world":"2.0.0-alpha.1.256+e3260c8a","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"e3260c8a237b42b6f2b875314203756a47bdce2e","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.256","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-71JhSYMR8BoyEdansEBFqJjx1vaMROISQ683LJIrftMfKtj4au+mI8akDcp9iKNTUUfdhq/5tXeV2yKrxZboxw==","shasum":"000b018282606470ea5c65a58459e802eb71271d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.256.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG1fgTybdlDyQW+oizPR05/FuyFmd9law5oRlho+XJlRAiB2wSiyJzjXfqkIswys8GugN7u3rv2QkN5ffyh8kIs5dQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.256_1687799084039_0.4318421445048992"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.257":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.257","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.257+2be15c1b","@latticexyz/recs":"2.0.0-alpha.1.257+2be15c1b","@latticexyz/schema-type":"2.0.0-alpha.1.257+2be15c1b","@latticexyz/services":"2.0.0-alpha.1.257+2be15c1b","@latticexyz/solecs":"2.0.0-alpha.1.257+2be15c1b","@latticexyz/store":"2.0.0-alpha.1.257+2be15c1b","@latticexyz/utils":"2.0.0-alpha.1.257+2be15c1b","@latticexyz/world":"2.0.0-alpha.1.257+2be15c1b","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"2be15c1b61bc5d13a4003d42b640a571cd98d032","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.257","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-2SWQD7PdGCMQzAxoR5dtdNmCuwU177bdxm1dfjb/nu9MSBIT3heS9LMy5fXUyQBlVM64erg+qwYwchPNxsY9EQ==","shasum":"28bfd905414acae9506e46f43d3744e569e65cc8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.257.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIACi6NACOHDyfzvSuQmoSm+yxH1s4t3GmC/y6tgfgWTBAiEA3316qbjdYMmYzWW3v0ILWTx/a0Fh34K6Yf0gTpRqbpI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.257_1687801901889_0.4548288965770346"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.258":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.258","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.258+1aef9099","@latticexyz/recs":"2.0.0-alpha.1.258+1aef9099","@latticexyz/schema-type":"2.0.0-alpha.1.258+1aef9099","@latticexyz/services":"2.0.0-alpha.1.258+1aef9099","@latticexyz/solecs":"2.0.0-alpha.1.258+1aef9099","@latticexyz/store":"2.0.0-alpha.1.258+1aef9099","@latticexyz/utils":"2.0.0-alpha.1.258+1aef9099","@latticexyz/world":"2.0.0-alpha.1.258+1aef9099","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"1aef9099b2c9e02ac758abc993d070cfcf182bc1","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.258","_nodeVersion":"18.16.0","_npmVersion":"lerna/6.6.1/node@v18.16.0+x64 (linux)","dist":{"integrity":"sha512-67mesq1ojJhWMN5sT5pSj0/gvyK3nHLt04lqsyLf3MxiXMgrJs8tidoLfaioNe38GrX7p8raP5RpmEZbBhWw2w==","shasum":"017cb499511984bda60d39d8f5656a4b8bbee2ea","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.258.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD3AgJN5ipTq2mENqhdzOMHKi+Iwht13WupxVkl3QuhrAIgRbIOmYdag0NIjkQ6vn7Wu/hDql6dyrluyzSohl3B/To="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.258_1687967251141_0.5958667146567989"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.259":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.259","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.259+6feef632","@latticexyz/recs":"2.0.0-alpha.1.259+6feef632","@latticexyz/schema-type":"2.0.0-alpha.1.259+6feef632","@latticexyz/services":"2.0.0-alpha.1.259+6feef632","@latticexyz/solecs":"2.0.0-alpha.1.259+6feef632","@latticexyz/store":"2.0.0-alpha.1.259+6feef632","@latticexyz/utils":"2.0.0-alpha.1.259+6feef632","@latticexyz/world":"2.0.0-alpha.1.259+6feef632","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"6feef63218866996a2b5469011736261f780d5c4","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.259","_nodeVersion":"18.16.1","_npmVersion":"lerna/6.6.1/node@v18.16.1+x64 (linux)","dist":{"integrity":"sha512-GZdm4rSSPdMWXSxisURJnpfD9TjhS4rC3y+fQfYK79xGsHxGAu/GAP4vBAlDu/QfHxf7VZyJvLuWk965ozjFHw==","shasum":"737737f87eb459b1af5eded9388c0a7b99883cb8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.259.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEjaPe+6y8zuIQYFniYwITlSLqxES22/3aSlSCX4niBRAiEAxF93DT/NHAmgQMfJLchA+PHU3NrCjA4L7GpAdTy7e3I="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.259_1688031563093_0.3167923386104552"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.260":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.260","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.260+03012e6c","@latticexyz/recs":"2.0.0-alpha.1.260+03012e6c","@latticexyz/schema-type":"2.0.0-alpha.1.260+03012e6c","@latticexyz/services":"2.0.0-alpha.1.260+03012e6c","@latticexyz/solecs":"2.0.0-alpha.1.260+03012e6c","@latticexyz/store":"2.0.0-alpha.1.260+03012e6c","@latticexyz/utils":"2.0.0-alpha.1.260+03012e6c","@latticexyz/world":"2.0.0-alpha.1.260+03012e6c","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"03012e6ce640e22452a697f37df6139ed3eface2","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.260","_nodeVersion":"18.16.1","_npmVersion":"lerna/6.6.1/node@v18.16.1+x64 (linux)","dist":{"integrity":"sha512-2i1NtNbndKZ1dhiDN9dfGsPjB55jVrIY5/4EJJy7HeKMfyX7TFASayxtMtqe+p0x3XBfEmXVHdKSPDlDCDdF8g==","shasum":"08507b7ac9214b7771abc6685dbb7e01c6e93b25","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.260.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDxfZeZ3i3QsH7BlJbRr6R0yeGH50x5n2rWR6bnWQw0gAIhAMbxWLwzfKdHZ0pohZyRe7tXoNERPZHl3MtuRVprBt0x"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.260_1688038379269_0.15457091832859193"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.261":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.261","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.261+0d7ddf1b","@latticexyz/recs":"2.0.0-alpha.1.261+0d7ddf1b","@latticexyz/schema-type":"2.0.0-alpha.1.261+0d7ddf1b","@latticexyz/services":"2.0.0-alpha.1.261+0d7ddf1b","@latticexyz/solecs":"2.0.0-alpha.1.261+0d7ddf1b","@latticexyz/store":"2.0.0-alpha.1.261+0d7ddf1b","@latticexyz/utils":"2.0.0-alpha.1.261+0d7ddf1b","@latticexyz/world":"2.0.0-alpha.1.261+0d7ddf1b","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"0d7ddf1bfb69ab2ac27948030d48bf5c13262fe1","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.261","_nodeVersion":"18.16.1","_npmVersion":"lerna/6.6.1/node@v18.16.1+x64 (linux)","dist":{"integrity":"sha512-4cMYw/0cKs0JoKUlL7udKqVNaFhio6jS8rcphwgoWEhcZQs2h7dothp7ZCmNh9dWvL1wc3jgFxkT8S97NLwsdQ==","shasum":"bb02e017d33ec738fb2eeaae88b5092bc6685731","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.261.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBu6RzPB4ceHS/xGGakLfAXgePM3N3rgqUf8R354COP0AiEAvI5WBOJYN+NO8v174mtjzDyZsZ6kfWgOtrZiwNm654E="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.261_1688377427373_0.7496576912739557"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.262":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.262","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.262+6575d133","@latticexyz/recs":"2.0.0-alpha.1.262+6575d133","@latticexyz/schema-type":"2.0.0-alpha.1.262+6575d133","@latticexyz/services":"2.0.0-alpha.1.262+6575d133","@latticexyz/solecs":"2.0.0-alpha.1.262+6575d133","@latticexyz/store":"2.0.0-alpha.1.262+6575d133","@latticexyz/utils":"2.0.0-alpha.1.262+6575d133","@latticexyz/world":"2.0.0-alpha.1.262+6575d133","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"6575d133e72764acb76a7978bac44ebdc5856d13","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.262","_nodeVersion":"18.16.1","_npmVersion":"lerna/6.6.1/node@v18.16.1+x64 (linux)","dist":{"integrity":"sha512-hkaGqVUKQPM2yMl21s6z4ld32TN0qyB4YgZQMgvX2t+LI8hUnmJwGyR72HjepRCj+SpJZEME4ylKVb5MDjpYog==","shasum":"5ddc8be69d1a625828fc856d4821356d76f7e8bd","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.262.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCQTUhXFaFUfEyd9aJI6pjI69rR2G1tRUUNX2XDK/SNGgIgQWQTJrk+AkN+j8UrME3iOqLt5/PRBOsultmMn8YfdO0="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.262_1688378999111_0.9767596527676079"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.263":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.263","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.263+b6e22931","@latticexyz/recs":"2.0.0-alpha.1.263+b6e22931","@latticexyz/schema-type":"2.0.0-alpha.1.263+b6e22931","@latticexyz/services":"2.0.0-alpha.1.263+b6e22931","@latticexyz/solecs":"2.0.0-alpha.1.263+b6e22931","@latticexyz/store":"2.0.0-alpha.1.263+b6e22931","@latticexyz/utils":"2.0.0-alpha.1.263+b6e22931","@latticexyz/world":"2.0.0-alpha.1.263+b6e22931","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"b6e22931ecf023f347f17c505bb4a56bdebf5061","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.263","_nodeVersion":"18.16.1","_npmVersion":"lerna/6.6.1/node@v18.16.1+x64 (linux)","dist":{"integrity":"sha512-Hk7vrNGAt93rCMG/1MPKPxJXXcG7F5r+g5Mql7J5jTWlWxLzlOay9s0/fAvWJCO3vD/cBc393koKodN8RVw8Qg==","shasum":"41ae6a7b9744b0b006e5733e55a1e96e79bd5497","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.263.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDKaTKxjF11gm81uCQ7aPCQwVQHNOCin5uoMs1tWDgBwAIhANUi50AYrrRd2EdsaPZD5Q8kFnzjJJpeeuj2wRg4bkWM"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.263_1688386299211_0.45710737000837076"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.264":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.264","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.264+9e117648","@latticexyz/recs":"2.0.0-alpha.1.264+9e117648","@latticexyz/schema-type":"2.0.0-alpha.1.264+9e117648","@latticexyz/services":"2.0.0-alpha.1.264+9e117648","@latticexyz/solecs":"2.0.0-alpha.1.264+9e117648","@latticexyz/store":"2.0.0-alpha.1.264+9e117648","@latticexyz/utils":"2.0.0-alpha.1.264+9e117648","@latticexyz/world":"2.0.0-alpha.1.264+9e117648","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"9e11764879bcbd6493478775b3c7ccd2046611f2","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.264","_nodeVersion":"18.16.1","_npmVersion":"lerna/6.6.1/node@v18.16.1+x64 (linux)","dist":{"integrity":"sha512-odXcxhuUT2vql5bRR4lsN8bg2J2Lx4FUmeg8oj6fcY1feCf/yYqYf8EwZmQ5yTwyvGCtCrHnSI/obkOf70x1RQ==","shasum":"6720a01e7994dfd21a70b2bf6b963b2c9db61a14","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.264.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFcBSrAkW+oo3FW1YDHMDRB0eVyuEpKsU84CbZBF/QnlAiBsE1iEq0JeaAG8isrSg8xidszJHnUTp8Vsa4dk+OR5XA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.264_1688386325331_0.6650323210489535"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.265":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.265","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.265+469ca13a","@latticexyz/recs":"2.0.0-alpha.1.265+469ca13a","@latticexyz/schema-type":"2.0.0-alpha.1.265+469ca13a","@latticexyz/services":"2.0.0-alpha.1.265+469ca13a","@latticexyz/solecs":"2.0.0-alpha.1.265+469ca13a","@latticexyz/store":"2.0.0-alpha.1.265+469ca13a","@latticexyz/utils":"2.0.0-alpha.1.265+469ca13a","@latticexyz/world":"2.0.0-alpha.1.265+469ca13a","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"469ca13ab110863426bb8be2ff634e3ca8dd4440","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.265","_nodeVersion":"18.16.1","_npmVersion":"lerna/6.6.1/node@v18.16.1+x64 (linux)","dist":{"integrity":"sha512-3CISlYN0onb0EQZXVwktUWrEAKyiSaJW58uFaZwO0RaPsr2Dxq0cVhUTPgQHwBQXQMw9c0JQ2tzT/afzOp5jkw==","shasum":"0b3733851f0b9b61616107d01c9a3839d42f7877","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.265.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHfF/73VAsizsPRGa4MYfEGVQVJUsQG5kvtl46c2ke66AiBriAF/j1dtXJe7lNqk7+X0gqqxV3E4kNNuKSz+Axk6Kg=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.265_1688386389501_0.38576945074513125"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.266":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.266","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.266+b9319d16","@latticexyz/recs":"2.0.0-alpha.1.266+b9319d16","@latticexyz/schema-type":"2.0.0-alpha.1.266+b9319d16","@latticexyz/services":"2.0.0-alpha.1.266+b9319d16","@latticexyz/solecs":"2.0.0-alpha.1.266+b9319d16","@latticexyz/store":"2.0.0-alpha.1.266+b9319d16","@latticexyz/utils":"2.0.0-alpha.1.266+b9319d16","@latticexyz/world":"2.0.0-alpha.1.266+b9319d16","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"b9319d1673e14241126e46e31d89f62f3fcc0e45","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.266","_nodeVersion":"18.16.1","_npmVersion":"lerna/6.6.1/node@v18.16.1+x64 (linux)","dist":{"integrity":"sha512-BSVaklXzwT1njLzd75BewOtJqV2GHGpmHyh9oGDbvSwUHLOtiE74OSVbdwToX/wW40hWBXY2ckc3u9d+WxxcGw==","shasum":"9ea753644f504fea744c458ca8abbf16d0b5c285","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.266.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGwc9Gf6NLx894UHqsco49rkPD+rlGSi5Z2Y6Bh/3u8jAiEA1sjAp+14K2haZskDcUdX2MdJ3++6jwGjv0Uem4NjVa4="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.266_1688406317386_0.5137427981627012"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.267":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.267","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.267+8619d150","@latticexyz/recs":"2.0.0-alpha.1.267+8619d150","@latticexyz/schema-type":"2.0.0-alpha.1.267+8619d150","@latticexyz/services":"2.0.0-alpha.1.267+8619d150","@latticexyz/solecs":"2.0.0-alpha.1.267+8619d150","@latticexyz/store":"2.0.0-alpha.1.267+8619d150","@latticexyz/utils":"2.0.0-alpha.1.267+8619d150","@latticexyz/world":"2.0.0-alpha.1.267+8619d150","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"8619d1503c31aca32474d618a8a0eda650cb9d16","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.267","_nodeVersion":"18.16.1","_npmVersion":"lerna/6.6.1/node@v18.16.1+x64 (linux)","dist":{"integrity":"sha512-4pWAg9ytfrSJ/YxRkCUZN4sUA7/G7F7GWgJth9+UCG/dtnx8vIEJ458i2O9t3kv2gPem3+gDKaAm6uCUOr8QPg==","shasum":"6e2cc237925c8559cc970bfdecc3276482463341","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.267.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAG532AhNKPZEmxEbOMYhhtVBlThsZee0MiKtFarhsyxAiEAscRoSeDjcIiHKUaUw/waRUQC0EZiDy7kDEK9xCT/cFQ="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.267_1688412758197_0.2490598734223679"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-alpha.1.268":{"name":"@latticexyz/network","version":"2.0.0-alpha.1.268","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@latticexyz/common":"2.0.0-alpha.1.268+15e65311","@latticexyz/recs":"2.0.0-alpha.1.268+15e65311","@latticexyz/schema-type":"2.0.0-alpha.1.268+15e65311","@latticexyz/services":"2.0.0-alpha.1.268+15e65311","@latticexyz/solecs":"2.0.0-alpha.1.268+15e65311","@latticexyz/store":"2.0.0-alpha.1.268+15e65311","@latticexyz/utils":"2.0.0-alpha.1.268+15e65311","@latticexyz/world":"2.0.0-alpha.1.268+15e65311","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"15e65311feda89e8d3dc3f9c0326252065c424b9","readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-alpha.1.268","_nodeVersion":"18.16.1","_npmVersion":"lerna/6.6.1/node@v18.16.1+x64 (linux)","dist":{"integrity":"sha512-Br+2a3wMcIbATlTy4AMDKuoJxNUw8Q4/KyWXskj9svfyohydJ+a3/sAhepfY+fjpWw4GWSnObhp5RxjFCentbw==","shasum":"df7140dd952f5b70e0a67ac6e87777041b84bfe7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-alpha.1.268.tgz","fileCount":80,"unpackedSize":491127,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICJTbaxTjblx0DIk7J6pA/3Ri1DVwDjGTlURsuN3FlUtAiAfvrz3CjLnjZnqR/Im5BLDL+xoazkWFMwRqctwisCtNg=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-alpha.1.268_1688454999466_0.9461281280885792"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230704121617":{"name":"@latticexyz/network","version":"0.0.0-main-20230704121617","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230704121617","@latticexyz/solecs":"1.42.0","@latticexyz/store":"1.42.0","@latticexyz/utils":"1.42.0","@latticexyz/world":"1.42.0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230704121617","_integrity":"sha512-wlggFY/T7lNLCwCcd6K12Ecg4x2fMQQi8T7X+JYQ/z4iCF1hCp0CV7vZJPlRxzkc1SUsbpFWOtZr3SHw2mWAQA==","_resolved":"/tmp/9e88190df48b9f61400d7f045dff2c03/latticexyz-network-0.0.0-main-20230704121617.tgz","_from":"file:latticexyz-network-0.0.0-main-20230704121617.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-wlggFY/T7lNLCwCcd6K12Ecg4x2fMQQi8T7X+JYQ/z4iCF1hCp0CV7vZJPlRxzkc1SUsbpFWOtZr3SHw2mWAQA==","shasum":"990c65c0a533ad57fd92b1af0f7721bac76a95f6","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230704121617.tgz","fileCount":80,"unpackedSize":491207,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCbf1nudC3BgpJNAzhr2UD3dp3XCfez57ZIIH4dQJ/6mwIgSflGTv92qryI+xv3IOt9u4Pl8v0RsT2tYet3uAk70vI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230704121617_1688473037264_0.709812466121053"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230705095946":{"name":"@latticexyz/network","version":"0.0.0-main-20230705095946","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230705095946","@latticexyz/solecs":"1.42.0","@latticexyz/store":"1.42.0","@latticexyz/utils":"1.42.0","@latticexyz/world":"1.42.0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230705095946","_integrity":"sha512-h9/FgMkvivXAdlkar/MQ6Q+OIGKB1nA71MuIZDBDLn5Td5uod37WBUw5pD1x38OlqdVR2NxtI7RQyzppLtc4oA==","_resolved":"/tmp/cd1b8858530cd19c9792cdd15d83d30b/latticexyz-network-0.0.0-main-20230705095946.tgz","_from":"file:latticexyz-network-0.0.0-main-20230705095946.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-h9/FgMkvivXAdlkar/MQ6Q+OIGKB1nA71MuIZDBDLn5Td5uod37WBUw5pD1x38OlqdVR2NxtI7RQyzppLtc4oA==","shasum":"5ab3bbed6184d18b8579e9a1776a60d678399f83","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230705095946.tgz","fileCount":80,"unpackedSize":491207,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEJ3J1wSkbPGY5aZ6x+m3ltv9ibfJRcrRASXk7V+g3SjAiEAjomFYdMgwei1Xd4sunBC8eEkJokxVjxPxti7juCcb9s="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230705095946_1688551247276_0.3545643566562262"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230705152036":{"name":"@latticexyz/network","version":"0.0.0-main-20230705152036","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230705152036","@latticexyz/solecs":"1.42.0","@latticexyz/store":"1.42.0","@latticexyz/utils":"1.42.0","@latticexyz/world":"1.42.0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230705152036","_integrity":"sha512-LCMSG98eIGHS2OTrEd3vc+4Ov6cQ+iXbOOnYuYCeAAP/MfEltNXRSj9fdBg7Q+ckhL6Az/Skn8s3i+4oYsZ55g==","_resolved":"/tmp/4c457127594c2dba3fb9afbc59238ae4/latticexyz-network-0.0.0-main-20230705152036.tgz","_from":"file:latticexyz-network-0.0.0-main-20230705152036.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-LCMSG98eIGHS2OTrEd3vc+4Ov6cQ+iXbOOnYuYCeAAP/MfEltNXRSj9fdBg7Q+ckhL6Az/Skn8s3i+4oYsZ55g==","shasum":"da77641da86be69f59e8cc546911d6a16aca6816","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230705152036.tgz","fileCount":80,"unpackedSize":491207,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDXkvrEJk2aThXlQvMysC7D6D6UBxxz9B53UkfxBHTm0AIgSVkF6kx/IPbY7GjGhsZcy2Rh3IBuK+leKUEWoUJnNuY="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230705152036_1688570512306_0.10036544737508923"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230705224651":{"name":"@latticexyz/network","version":"0.0.0-main-20230705224651","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230705224651","@latticexyz/solecs":"1.42.0","@latticexyz/store":"1.42.0","@latticexyz/utils":"1.42.0","@latticexyz/world":"1.42.0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230705224651","_integrity":"sha512-YGefik5ELUPOiuUPnDEhNSI0RBfbkwbyKXvsVNOqJvBGq4nnPXWb29iWScpIoLTyIgDE/Sy8A8IhqJOZO6xb3A==","_resolved":"/tmp/8e8cfccda7183f6ef15f945e1ebafe70/latticexyz-network-0.0.0-main-20230705224651.tgz","_from":"file:latticexyz-network-0.0.0-main-20230705224651.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-YGefik5ELUPOiuUPnDEhNSI0RBfbkwbyKXvsVNOqJvBGq4nnPXWb29iWScpIoLTyIgDE/Sy8A8IhqJOZO6xb3A==","shasum":"4484f20dd1025035ad489bc3b3f4d52fae08ba17","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230705224651.tgz","fileCount":80,"unpackedSize":491207,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICLjiZnCPqVjzEHbSHEgGcnsjfSzoQai0LdcTcOJsuy6AiB+dyLAwYnhHqsg7j4rTQe9WUoBZ6QXvJD9bUlz+L57dA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230705224651_1688597268148_0.24723100050614621"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230705225731":{"name":"@latticexyz/network","version":"0.0.0-main-20230705225731","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230705225731","@latticexyz/solecs":"1.42.0","@latticexyz/store":"1.42.0","@latticexyz/utils":"1.42.0","@latticexyz/world":"1.42.0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230705225731","_integrity":"sha512-ek+Uwmm//BwptG6KOvvf74tDYvdExvrxXCgTNXoV0Cix9UK6jSG4XqrgB60SvVsFNMklBYeyIYm+GksW/FZZeA==","_resolved":"/tmp/d0220f72ac34b1a5dc090e77cbce3bbf/latticexyz-network-0.0.0-main-20230705225731.tgz","_from":"file:latticexyz-network-0.0.0-main-20230705225731.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-ek+Uwmm//BwptG6KOvvf74tDYvdExvrxXCgTNXoV0Cix9UK6jSG4XqrgB60SvVsFNMklBYeyIYm+GksW/FZZeA==","shasum":"23f5e2416961ea02954fa95e9c56b44a5ee3a9d8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230705225731.tgz","fileCount":80,"unpackedSize":491207,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEKuU+2M+J82BpfIxGJxPk5Jw2Zb9zNMTGykyndhsXRrAiBe7dUlYCatPOlJj+A5pO94Ok5uojgczIumzv8+LkxQTw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230705225731_1688597910341_0.5972931893668763"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230705230250":{"name":"@latticexyz/network","version":"0.0.0-main-20230705230250","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230705230250","@latticexyz/solecs":"1.42.0","@latticexyz/store":"1.42.0","@latticexyz/utils":"1.42.0","@latticexyz/world":"1.42.0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230705230250","_integrity":"sha512-Vhb+HozuT0wbfqL0BY6kkMfQ5FAXz6CCgSTgNymkC+UVknssT5WiM6nNiiekizA/xlRA7ogo2hCU77rYx9o8xA==","_resolved":"/tmp/439175068d750c2652b2c2ba7bc7577f/latticexyz-network-0.0.0-main-20230705230250.tgz","_from":"file:latticexyz-network-0.0.0-main-20230705230250.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-Vhb+HozuT0wbfqL0BY6kkMfQ5FAXz6CCgSTgNymkC+UVknssT5WiM6nNiiekizA/xlRA7ogo2hCU77rYx9o8xA==","shasum":"768d743729f409097c4368945be798bd1d877845","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230705230250.tgz","fileCount":80,"unpackedSize":491207,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG9LiD6iE0N3xrBHK/iqXD7GHy4pKLQ2G7MKhmF8QPOrAiBtlRndnlKYUytMsDBHQJ3FgQNxRz1nF3kq8gcGcq+UGQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230705230250_1688598242611_0.5449710295765646"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230706101146":{"name":"@latticexyz/network","version":"0.0.0-main-20230706101146","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230706101146","@latticexyz/solecs":"1.42.0","@latticexyz/store":"1.42.0","@latticexyz/utils":"1.42.0","@latticexyz/world":"1.42.0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230706101146","_integrity":"sha512-8xRObMfuifJ3c2RijJMUF8n+LTUZskZgv3wQsQYogZEeO63M0ey2FPYxoxJyXkLlz90Q4P81t0ykXOWIEZZ52g==","_resolved":"/tmp/d48cb5d2c8dcc2fa150776d144406c04/latticexyz-network-0.0.0-main-20230706101146.tgz","_from":"file:latticexyz-network-0.0.0-main-20230706101146.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-8xRObMfuifJ3c2RijJMUF8n+LTUZskZgv3wQsQYogZEeO63M0ey2FPYxoxJyXkLlz90Q4P81t0ykXOWIEZZ52g==","shasum":"97a0b2db84475fd7f9d4b305bc3d5a0ae33783f2","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230706101146.tgz","fileCount":80,"unpackedSize":491207,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE9SvM2vkDCwdz6vCLTls65pBa7TR3//7jur9epNe6ERAiEAhQxCYlPK9ZFhKpVIzE9IvqKUimbEZBTasDPGNnGmTJk="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230706101146_1688638367885_0.7729855690558463"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230706110436":{"name":"@latticexyz/network","version":"0.0.0-main-20230706110436","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230706110436","@latticexyz/solecs":"1.42.0","@latticexyz/store":"0.0.0-main-20230706110436","@latticexyz/utils":"1.42.0","@latticexyz/world":"0.0.0-main-20230706110436"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230706110436","_integrity":"sha512-JAdjpbPmNxjsS51wgub5dCOhoJxSVbBGh2aFt6zMjZdn8mOvm7Mz4y4ZDupIzbx7cwvDTxpiSDYa1KvaCAhexg==","_resolved":"/tmp/7abd91377f9d64bc8859c74558daad8e/latticexyz-network-0.0.0-main-20230706110436.tgz","_from":"file:latticexyz-network-0.0.0-main-20230706110436.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-JAdjpbPmNxjsS51wgub5dCOhoJxSVbBGh2aFt6zMjZdn8mOvm7Mz4y4ZDupIzbx7cwvDTxpiSDYa1KvaCAhexg==","shasum":"68d2fe89bdcf7e64f48fb0a49906701f1e917200","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230706110436.tgz","fileCount":80,"unpackedSize":491438,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGPLpnp4s8xE3TPV/qZ0veZQ11LNWryLNw9EURIoHCm+AiEArJl4cFVLTslGzSJVrngqgvbNf1AviWIeaXfV7yAsEQU="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230706110436_1688641542196_0.6562793126156865"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230706111131":{"name":"@latticexyz/network","version":"0.0.0-main-20230706111131","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230706111131","@latticexyz/solecs":"1.42.0","@latticexyz/store":"0.0.0-main-20230706111131","@latticexyz/utils":"1.42.0","@latticexyz/world":"0.0.0-main-20230706111131"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230706111131","_integrity":"sha512-mXD9kx4hzwqpC5NiknNCqp3etToF2xifm7oY+51i/CltD2wyHJRvvnzM24JitzvVVmuUXlJBToylYineDlHgRA==","_resolved":"/tmp/6fdfb82485143203d5087438098fde53/latticexyz-network-0.0.0-main-20230706111131.tgz","_from":"file:latticexyz-network-0.0.0-main-20230706111131.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-mXD9kx4hzwqpC5NiknNCqp3etToF2xifm7oY+51i/CltD2wyHJRvvnzM24JitzvVVmuUXlJBToylYineDlHgRA==","shasum":"55de43162466b466491515acc4bcc8e87a61baab","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230706111131.tgz","fileCount":80,"unpackedSize":492458,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCjFJ7OggbtbpPJdGPqbbjcA6dnx/wOIQ+NtntFGBe1agIgabPhkSDUh3Nd6/OK7ZomphlgUevBEwl0xXnXgW3vXHM="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230706111131_1688641954618_0.020553223262045117"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230706134710":{"name":"@latticexyz/network","version":"0.0.0-main-20230706134710","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230706134710","@latticexyz/solecs":"1.42.0","@latticexyz/store":"0.0.0-main-20230706134710","@latticexyz/utils":"1.42.0","@latticexyz/world":"0.0.0-main-20230706134710"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230706134710","_integrity":"sha512-EuYHeAE//fA5/niDkD3cB13m3jt5GMKjiCmuW0ZiCxeKKiSfCjz5dfqicNssbIE1mugRxpoBMhddLCyOW1qQ2Q==","_resolved":"/tmp/d2c486c81798d6d79226752ac687af49/latticexyz-network-0.0.0-main-20230706134710.tgz","_from":"file:latticexyz-network-0.0.0-main-20230706134710.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-EuYHeAE//fA5/niDkD3cB13m3jt5GMKjiCmuW0ZiCxeKKiSfCjz5dfqicNssbIE1mugRxpoBMhddLCyOW1qQ2Q==","shasum":"7750feb88c590d3045d1e11df5a8242a13aca74a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230706134710.tgz","fileCount":80,"unpackedSize":492458,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHxGQuh6fHUa+Hd6qViRasbxKgwMqcomvEJlT8pcCQ6eAiEAh2Auo30+urKrkUQeBKw9J7zIG79WqPpPwCHi637gWzk="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230706134710_1688651305451_0.22103530500164403"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-indexing-20230707130424":{"name":"@latticexyz/network","version":"0.0.0-indexing-20230707130424","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-indexing-20230707130424","@latticexyz/solecs":"1.42.0","@latticexyz/store":"0.0.0-indexing-20230707130424","@latticexyz/utils":"1.42.0","@latticexyz/world":"0.0.0-indexing-20230707130424"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-indexing-20230707130424","_integrity":"sha512-HV747Tq5yhnxW7SIaOdNtcBlUZTDX1Jgk1p5yjqnHlG0bYu4rZvcIHroXRe/kceT7o6EVgzMURrP7x4AZQAjow==","_resolved":"/tmp/81dfc9355cc17a29a76e6606f3e36029/latticexyz-network-0.0.0-indexing-20230707130424.tgz","_from":"file:latticexyz-network-0.0.0-indexing-20230707130424.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-HV747Tq5yhnxW7SIaOdNtcBlUZTDX1Jgk1p5yjqnHlG0bYu4rZvcIHroXRe/kceT7o6EVgzMURrP7x4AZQAjow==","shasum":"ea5d675aa7140c43fad4469d08f8e3c4de5f2cf0","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-indexing-20230707130424.tgz","fileCount":80,"unpackedSize":492604,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFCA7OhLAK5/KZ1QXMdfy0auOmDj0mk5VOZGVAEjg5f9AiEAtflg5EWKhZm6PyRhWNpjROvDZA8cZ31lLLCZGqFr0EQ="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-indexing-20230707130424_1688735153239_0.5646581299347626"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230711112802":{"name":"@latticexyz/network","version":"0.0.0-main-20230711112802","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230711112802","@latticexyz/solecs":"1.42.0","@latticexyz/store":"0.0.0-main-20230711112802","@latticexyz/utils":"1.42.0","@latticexyz/world":"0.0.0-main-20230711112802"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230711112802","_integrity":"sha512-3KMQFuZhIUBlYSXg2gMJ23uyPewMc8EUA7RaezU7A7jhUH+uTwca7krFiK3SfshFh3EY9c+z0GwXjltc0jAAOw==","_resolved":"/tmp/043b83c5d02ce1cc4e6913f14c285336/latticexyz-network-0.0.0-main-20230711112802.tgz","_from":"file:latticexyz-network-0.0.0-main-20230711112802.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-3KMQFuZhIUBlYSXg2gMJ23uyPewMc8EUA7RaezU7A7jhUH+uTwca7krFiK3SfshFh3EY9c+z0GwXjltc0jAAOw==","shasum":"21ecd3996d76f15c49d78f5908af0b8e143383e7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230711112802.tgz","fileCount":80,"unpackedSize":492458,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHS6MpCIK1MvLRn/0Qo333n1plR86vjlQasQNJsQO18eAiEAwgfDysnzxCDah/+2WqN9sUkf4qhPNonvnwfwUtTos4Y="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230711112802_1689074946802_0.12157056458760418"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230712123334":{"name":"@latticexyz/network","version":"0.0.0-main-20230712123334","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230712123334","@latticexyz/solecs":"1.42.0","@latticexyz/store":"0.0.0-main-20230712123334","@latticexyz/utils":"1.42.0","@latticexyz/world":"0.0.0-main-20230712123334"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230712123334","_integrity":"sha512-WVRQL49mjMAOT4WupRqDyHrWPyl1HaO4lQDLtRTbOmK4KHz/+2HxpWX8AdAQZdI3rrMAIHUY56/lRBHzR07tEA==","_resolved":"/tmp/fd9e29bad3b326304717e677e06c76c8/latticexyz-network-0.0.0-main-20230712123334.tgz","_from":"file:latticexyz-network-0.0.0-main-20230712123334.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-WVRQL49mjMAOT4WupRqDyHrWPyl1HaO4lQDLtRTbOmK4KHz/+2HxpWX8AdAQZdI3rrMAIHUY56/lRBHzR07tEA==","shasum":"c1b8fa0f4de8abb585a718ec1be99d9a21f1de05","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230712123334.tgz","fileCount":80,"unpackedSize":492555,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGEHP2aBXrL6kAeuBGxVoczFjI6FfsxFWz0yv9dUicnnAiEAoXsglLD1+1VSc+pFT7+/RSuTtqoU2OQyF4H5aL+WrVc="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230712123334_1689165280354_0.9440951089586391"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230712164118":{"name":"@latticexyz/network","version":"0.0.0-main-20230712164118","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230712164118","@latticexyz/solecs":"1.42.0","@latticexyz/store":"0.0.0-main-20230712164118","@latticexyz/utils":"1.42.0","@latticexyz/world":"0.0.0-main-20230712164118"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230712164118","_integrity":"sha512-sFlINQnwBuottPKRJPtLQfdefOgGlFa5vFgtLsGFmlEN4vFo60gd9D0y6UKl5QDJW9HBwLF2rVu0zODgd/0C+g==","_resolved":"/tmp/c51e231919d13abc0ec1dff97cf8fe7b/latticexyz-network-0.0.0-main-20230712164118.tgz","_from":"file:latticexyz-network-0.0.0-main-20230712164118.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-sFlINQnwBuottPKRJPtLQfdefOgGlFa5vFgtLsGFmlEN4vFo60gd9D0y6UKl5QDJW9HBwLF2rVu0zODgd/0C+g==","shasum":"57e5d92d6db57e03b7127c919f2074efcc12c733","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230712164118.tgz","fileCount":80,"unpackedSize":492555,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDN+qqEj5ND4Tb+epS62YGVQLKDzUDN9hY1gFwU7+C0kwIhAMxYD0QGyqp5oaoqTGvtLyfhva2iN3XJoFgOrF7G8Vdt"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230712164118_1689180156500_0.7053330799275763"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230713085937":{"name":"@latticexyz/network","version":"0.0.0-main-20230713085937","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230713085937","@latticexyz/solecs":"1.42.0","@latticexyz/store":"0.0.0-main-20230713085937","@latticexyz/utils":"1.42.0","@latticexyz/world":"0.0.0-main-20230713085937"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230713085937","_integrity":"sha512-KS3i9sRcLsq3YzhGWVLHuBpL+dPtXa30190nkhC26YBFaam8Dg0W4ua7r/bcLydMcd5mlT+FsJVBh59PdiSLig==","_resolved":"/tmp/b59bebed67bc6150cf67f212855dca6d/latticexyz-network-0.0.0-main-20230713085937.tgz","_from":"file:latticexyz-network-0.0.0-main-20230713085937.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-KS3i9sRcLsq3YzhGWVLHuBpL+dPtXa30190nkhC26YBFaam8Dg0W4ua7r/bcLydMcd5mlT+FsJVBh59PdiSLig==","shasum":"69f14349b94f5a14238f2f95f8725fe3af57e298","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230713085937.tgz","fileCount":80,"unpackedSize":492555,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQChZitofvB4kwSqAE9JEPOPI5gMmfNq6qFv1oWFx0JGTQIhAJ2KoFoMrsnW68uQU/yDkjMP1Hz61/52UH8gjYl+oK4g"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230713085937_1689238842542_0.3778289706118785"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230713090002":{"name":"@latticexyz/network","version":"0.0.0-main-20230713090002","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230713090002","@latticexyz/solecs":"1.42.0","@latticexyz/store":"0.0.0-main-20230713090002","@latticexyz/utils":"1.42.0","@latticexyz/world":"0.0.0-main-20230713090002"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230713090002","_integrity":"sha512-hb7Aa89BA0wWv3wAHdI89udZrx9KOmOtPQPlMNuHzJD+/mEDShLxVPOMd5evTFIYMCqN5VywHZUcTRfTBL5hBw==","_resolved":"/tmp/07c51ab61693209ab4bac30f90f643f0/latticexyz-network-0.0.0-main-20230713090002.tgz","_from":"file:latticexyz-network-0.0.0-main-20230713090002.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-hb7Aa89BA0wWv3wAHdI89udZrx9KOmOtPQPlMNuHzJD+/mEDShLxVPOMd5evTFIYMCqN5VywHZUcTRfTBL5hBw==","shasum":"792aae382a531e9009774a0cb5636bde8802c3f7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230713090002.tgz","fileCount":80,"unpackedSize":492555,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEPIepxmj2WWuAKQDHtShRv2Y+8R81yPwV0gT+pzadirAiEAoJIvv/tjGhtcPrZc8UKZ79TzIWMgR4dTgQu+z8pTPoY="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230713090002_1689238866974_0.17056769544206118"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.0.0-main-20230713104632":{"name":"@latticexyz/network","version":"0.0.0-main-20230713104632","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"1.42.0","@latticexyz/recs":"1.42.0","@latticexyz/schema-type":"1.42.0","@latticexyz/services":"0.0.0-main-20230713104632","@latticexyz/solecs":"1.42.0","@latticexyz/store":"0.0.0-main-20230713104632","@latticexyz/utils":"1.42.0","@latticexyz/world":"0.0.0-main-20230713104632"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@0.0.0-main-20230713104632","_integrity":"sha512-65YAdSb/vj+2mXS4FN6ueGk535YPD1/VgQ5Cm88Rjkv2uwya6Dq9JxOF48w2BlSFrbyrxV078vs0Dt7TFsBAoA==","_resolved":"/tmp/c18947230a51cf47d70d2e846af96636/latticexyz-network-0.0.0-main-20230713104632.tgz","_from":"file:latticexyz-network-0.0.0-main-20230713104632.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-65YAdSb/vj+2mXS4FN6ueGk535YPD1/VgQ5Cm88Rjkv2uwya6Dq9JxOF48w2BlSFrbyrxV078vs0Dt7TFsBAoA==","shasum":"ff9fcbab8131537b6f78769cff51830579d81939","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-0.0.0-main-20230713104632.tgz","fileCount":80,"unpackedSize":492555,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHPhLMhHlIQ4EulYCDzHB5IRo9fVs8YXpTPDVsYRLn2ZAiEAsbRkNjuHpENOVsZRbeCmYSexpD4p5polrr6v1M6cubY="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_0.0.0-main-20230713104632_1689245253986_0.3897193741653622"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-0d434816":{"name":"@latticexyz/network","version":"2.0.0-main-0d434816","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-0d434816","@latticexyz/recs":"2.0.0-main-0d434816","@latticexyz/schema-type":"2.0.0-main-0d434816","@latticexyz/services":"2.0.0-main-0d434816","@latticexyz/solecs":"2.0.0-main-0d434816","@latticexyz/store":"2.0.0-main-0d434816","@latticexyz/utils":"2.0.0-main-0d434816","@latticexyz/world":"2.0.0-main-0d434816"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-0d434816","_integrity":"sha512-domuoJV4RYSeyXU+Cp86x+1Oh7qdxFLU6t0mzUSBty/XuxdO6Q9RZ6qfwEKy1GbH1rMO9bTF/ZVW4ijYh/Vdhw==","_resolved":"/tmp/7dd842a0c41bf9995ff533d3df63c1ef/latticexyz-network-2.0.0-main-0d434816.tgz","_from":"file:latticexyz-network-2.0.0-main-0d434816.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-domuoJV4RYSeyXU+Cp86x+1Oh7qdxFLU6t0mzUSBty/XuxdO6Q9RZ6qfwEKy1GbH1rMO9bTF/ZVW4ijYh/Vdhw==","shasum":"789c4e96389736017a4758b34f1a67f84ed1e709","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-0d434816.tgz","fileCount":80,"unpackedSize":492789,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCSFGxb19BWkjzZofXwPMougtReBCp+nAKETs0cgs5FawIhAO89vAy+37Lk2TWvxvvlk9/lXu8FMqaX43fWHYJ6kjq+"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-0d434816_1689259795100_0.8207496358428235"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-indexing-7e4f029f":{"name":"@latticexyz/network","version":"2.0.0-indexing-7e4f029f","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-indexing-7e4f029f","@latticexyz/recs":"2.0.0-indexing-7e4f029f","@latticexyz/schema-type":"2.0.0-indexing-7e4f029f","@latticexyz/services":"2.0.0-indexing-7e4f029f","@latticexyz/solecs":"2.0.0-indexing-7e4f029f","@latticexyz/store":"2.0.0-indexing-7e4f029f","@latticexyz/utils":"2.0.0-indexing-7e4f029f","@latticexyz/world":"2.0.0-indexing-7e4f029f"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-indexing-7e4f029f","_integrity":"sha512-a/F83nkA//y9/m19h4X3kXIH1F+vb64Fk5jD+WkSnpF1EWYGbyuEXSn9hZcjOL+sqcrAFjEzftU48TxHOfd7iw==","_resolved":"/tmp/c222483f3b61f3ea0467beab0b85de87/latticexyz-network-2.0.0-indexing-7e4f029f.tgz","_from":"file:latticexyz-network-2.0.0-indexing-7e4f029f.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-a/F83nkA//y9/m19h4X3kXIH1F+vb64Fk5jD+WkSnpF1EWYGbyuEXSn9hZcjOL+sqcrAFjEzftU48TxHOfd7iw==","shasum":"4d7aa2e19eaeb077b124d6aa9262b70303e72c3c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-indexing-7e4f029f.tgz","fileCount":80,"unpackedSize":494105,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAY3M6acZO73u2x3uESvbEik2rBZMW1oZ2pjvmk6hdsCAiEArj6ddGysC8n7UZaqa/xacOlP3O+d50Je6zhcG7QvAu0="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-indexing-7e4f029f_1689261981824_0.39640630910371955"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-8d51a034":{"name":"@latticexyz/network","version":"2.0.0-main-8d51a034","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-8d51a034","@latticexyz/recs":"2.0.0-main-8d51a034","@latticexyz/schema-type":"2.0.0-main-8d51a034","@latticexyz/services":"2.0.0-main-8d51a034","@latticexyz/solecs":"2.0.0-main-8d51a034","@latticexyz/store":"2.0.0-main-8d51a034","@latticexyz/utils":"2.0.0-main-8d51a034","@latticexyz/world":"2.0.0-main-8d51a034"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-8d51a034","_integrity":"sha512-0JymzB4XK48ThvUxLkQktZH1bZ2BWcfYG8I3OCgPQhbACdJPV+uphaaxC5Thp8A86WPJnoeyar5kvOsVCVnXdg==","_resolved":"/tmp/7ae68b7ecde90fbd2575fc590e60d5a1/latticexyz-network-2.0.0-main-8d51a034.tgz","_from":"file:latticexyz-network-2.0.0-main-8d51a034.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-0JymzB4XK48ThvUxLkQktZH1bZ2BWcfYG8I3OCgPQhbACdJPV+uphaaxC5Thp8A86WPJnoeyar5kvOsVCVnXdg==","shasum":"e184bb8a8342172a4d50ead7d2c520c85b0ec497","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-8d51a034.tgz","fileCount":80,"unpackedSize":492886,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAzNr5aXe7WmwUkgXLcWvnkyYvUcW8NdN0V0glZL7Fp7AiEAuuN05EE6lupArEE7Vr75T962nn8ymS2upKZoOMLoX0E="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-8d51a034_1689263441380_0.667397173964879"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-db19ea39":{"name":"@latticexyz/network","version":"2.0.0-main-db19ea39","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-db19ea39","@latticexyz/recs":"2.0.0-main-db19ea39","@latticexyz/schema-type":"2.0.0-main-db19ea39","@latticexyz/services":"2.0.0-main-db19ea39","@latticexyz/solecs":"2.0.0-main-db19ea39","@latticexyz/store":"2.0.0-main-db19ea39","@latticexyz/utils":"2.0.0-main-db19ea39","@latticexyz/world":"2.0.0-main-db19ea39"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-db19ea39","_integrity":"sha512-qSQWAk41jcgGGjmNc6YX2mBlJ3pNb4DtaG6BKdzvgdnmBjfGLhc49q8g7EKWzhStYGmgT1ahZj3c+NXFzodYBA==","_resolved":"/tmp/f90a9dda2efc9daaa60583deda423388/latticexyz-network-2.0.0-main-db19ea39.tgz","_from":"file:latticexyz-network-2.0.0-main-db19ea39.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-qSQWAk41jcgGGjmNc6YX2mBlJ3pNb4DtaG6BKdzvgdnmBjfGLhc49q8g7EKWzhStYGmgT1ahZj3c+NXFzodYBA==","shasum":"3785d7702c440640ccd2882a47459244ff9304df","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-db19ea39.tgz","fileCount":80,"unpackedSize":492886,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGVcciLHYpGX0o5ua6S3EaZxrSgiio0UHwHl05C5jmiCAiBJWO4KjHGWWtRPyp0qfFHiQz2Mmzf1i7gTDTpcEXd6Fg=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-db19ea39_1689265808752_0.2940384393365527"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-184d5b52":{"name":"@latticexyz/network","version":"2.0.0-main-184d5b52","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-184d5b52","@latticexyz/recs":"2.0.0-main-184d5b52","@latticexyz/schema-type":"2.0.0-main-184d5b52","@latticexyz/services":"2.0.0-main-184d5b52","@latticexyz/solecs":"2.0.0-main-184d5b52","@latticexyz/store":"2.0.0-main-184d5b52","@latticexyz/utils":"2.0.0-main-184d5b52","@latticexyz/world":"2.0.0-main-184d5b52"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-184d5b52","_integrity":"sha512-X4SAJJr9wq6J6JhZ6ZvDP1yif4bWggaNE6psoqP34fTl80N38g0pnaMQ3maUZ+YZdsEVB/GMFxCzVqx/db3ZyA==","_resolved":"/tmp/67cc1a095035d0643153048c88ad200e/latticexyz-network-2.0.0-main-184d5b52.tgz","_from":"file:latticexyz-network-2.0.0-main-184d5b52.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-X4SAJJr9wq6J6JhZ6ZvDP1yif4bWggaNE6psoqP34fTl80N38g0pnaMQ3maUZ+YZdsEVB/GMFxCzVqx/db3ZyA==","shasum":"05b9205e17a38312871c7f51b8926fde24246949","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-184d5b52.tgz","fileCount":80,"unpackedSize":492886,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHEh//TH/5UZuLPvsVGQ75cVjYK/SmawOwMEn+0ovm55AiAJN1gkQhLWR+jEr+6EAQnZ4JV0vc7HuT3I2xiTpPZ/1A=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-184d5b52_1689270838036_0.9843472276236787"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-c36ffd13":{"name":"@latticexyz/network","version":"2.0.0-main-c36ffd13","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-c36ffd13","@latticexyz/recs":"2.0.0-main-c36ffd13","@latticexyz/schema-type":"2.0.0-main-c36ffd13","@latticexyz/services":"2.0.0-main-c36ffd13","@latticexyz/solecs":"2.0.0-main-c36ffd13","@latticexyz/store":"2.0.0-main-c36ffd13","@latticexyz/utils":"2.0.0-main-c36ffd13","@latticexyz/world":"2.0.0-main-c36ffd13"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-c36ffd13","_integrity":"sha512-hnNUmS9UfdLi1yLeL7Mk/VXaFF7EGKA4y2IldRkOZgONTNpO0sp7mMHBy/BDPKWE/EReOhiIChOrgfUxH1bllw==","_resolved":"/tmp/e61addce94768863f4fd57c270fc3a31/latticexyz-network-2.0.0-main-c36ffd13.tgz","_from":"file:latticexyz-network-2.0.0-main-c36ffd13.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-hnNUmS9UfdLi1yLeL7Mk/VXaFF7EGKA4y2IldRkOZgONTNpO0sp7mMHBy/BDPKWE/EReOhiIChOrgfUxH1bllw==","shasum":"e37a5613b1394a9aff9440271aa3c3720bdffee8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-c36ffd13.tgz","fileCount":80,"unpackedSize":492886,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDCbCDsDEEsNon+ZKWt43+s8QID8CrJb3Wt8VE8jCRiMQIhANrhs0NzhghxZ9jf/KSn2tWet3l9BWzibo+fxXddQ+E9"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-c36ffd13_1689273572925_0.19779379076649417"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-de2245b6":{"name":"@latticexyz/network","version":"2.0.0-main-de2245b6","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-de2245b6","@latticexyz/recs":"2.0.0-main-de2245b6","@latticexyz/schema-type":"2.0.0-main-de2245b6","@latticexyz/services":"2.0.0-main-de2245b6","@latticexyz/solecs":"2.0.0-main-de2245b6","@latticexyz/store":"2.0.0-main-de2245b6","@latticexyz/utils":"2.0.0-main-de2245b6","@latticexyz/world":"2.0.0-main-de2245b6"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-de2245b6","_integrity":"sha512-8GOq6JwpIX88D2dXa48vY58sGhRlm6xJHQe6Iz76maMLCRXiitwAwrtuMJ/xHCsixPCNEtKNqdDZ2LxuAmqvjA==","_resolved":"/tmp/781507321588bd39b2520192b77cd10d/latticexyz-network-2.0.0-main-de2245b6.tgz","_from":"file:latticexyz-network-2.0.0-main-de2245b6.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-8GOq6JwpIX88D2dXa48vY58sGhRlm6xJHQe6Iz76maMLCRXiitwAwrtuMJ/xHCsixPCNEtKNqdDZ2LxuAmqvjA==","shasum":"cdfc669c785dcca8a0b10c8f63c8b1e3a1e94028","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-de2245b6.tgz","fileCount":80,"unpackedSize":492886,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAgnTg4hAVqf3EtAVR2/4Kh4ODDwclAp1yEAYDOVULc8AiEA0OJ8UpDiasV/xanMhN3xH132XjhTv1ZYR/L7dRK0qh0="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-de2245b6_1689331872726_0.9453417058303246"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-78b3b1de":{"name":"@latticexyz/network","version":"2.0.0-main-78b3b1de","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-78b3b1de","@latticexyz/recs":"2.0.0-main-78b3b1de","@latticexyz/schema-type":"2.0.0-main-78b3b1de","@latticexyz/services":"2.0.0-main-78b3b1de","@latticexyz/solecs":"2.0.0-main-78b3b1de","@latticexyz/store":"2.0.0-main-78b3b1de","@latticexyz/utils":"2.0.0-main-78b3b1de","@latticexyz/world":"2.0.0-main-78b3b1de"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-78b3b1de","_integrity":"sha512-9thceB7ADGoo2CDxFRRIuN9mG5Rn2Wvvz5VZlZtmknqGrdLax9HtOdkTsQxpbp4c1vYZmhFyUwKszmEGK4M5CQ==","_resolved":"/tmp/e38a95c656e60efd7443dfbf653ad2dd/latticexyz-network-2.0.0-main-78b3b1de.tgz","_from":"file:latticexyz-network-2.0.0-main-78b3b1de.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-9thceB7ADGoo2CDxFRRIuN9mG5Rn2Wvvz5VZlZtmknqGrdLax9HtOdkTsQxpbp4c1vYZmhFyUwKszmEGK4M5CQ==","shasum":"55b32f773abd3c134624603fdae912ffc46fcde8","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-78b3b1de.tgz","fileCount":80,"unpackedSize":492886,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCPBBAKei6BPRlxRiJvVfE3twvMJhQZGaj1l+aB9TXWOQIgAWbuou41Px7wypXCw+/OJL59M2l/VqlGYWHIJjPDLqU="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-78b3b1de_1689332006308_0.10330242083298868"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-e9258dae":{"name":"@latticexyz/network","version":"2.0.0-main-e9258dae","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-e9258dae","@latticexyz/recs":"2.0.0-main-e9258dae","@latticexyz/schema-type":"2.0.0-main-e9258dae","@latticexyz/services":"2.0.0-main-e9258dae","@latticexyz/solecs":"2.0.0-main-e9258dae","@latticexyz/store":"2.0.0-main-e9258dae","@latticexyz/utils":"2.0.0-main-e9258dae","@latticexyz/world":"2.0.0-main-e9258dae"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-e9258dae","_integrity":"sha512-4aLWiGAvlBamDx8IjHcQCAcoetzt5T78/wu4iLu40cfSjnAYcvGxAlTssAEa/20cpwLkTExS6bkYLrOHXJiCtg==","_resolved":"/tmp/ae423ce93090b80a4adc9519d8fe147c/latticexyz-network-2.0.0-main-e9258dae.tgz","_from":"file:latticexyz-network-2.0.0-main-e9258dae.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-4aLWiGAvlBamDx8IjHcQCAcoetzt5T78/wu4iLu40cfSjnAYcvGxAlTssAEa/20cpwLkTExS6bkYLrOHXJiCtg==","shasum":"f86273804e24f0bbe8f2e0599624f41b64b658f9","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-e9258dae.tgz","fileCount":80,"unpackedSize":492886,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC+7nQgUvSwG64AE+3543xTRnReOml8+Z1thySNDh3EngIgH6EmHQxDWwXULkRvpr0/cDryulIzeJkFJXGGOFzAiJQ="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-e9258dae_1689332067462_0.20969454895096362"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-a7b30c79":{"name":"@latticexyz/network","version":"2.0.0-main-a7b30c79","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-a7b30c79","@latticexyz/recs":"2.0.0-main-a7b30c79","@latticexyz/schema-type":"2.0.0-main-a7b30c79","@latticexyz/services":"2.0.0-main-a7b30c79","@latticexyz/solecs":"2.0.0-main-a7b30c79","@latticexyz/store":"2.0.0-main-a7b30c79","@latticexyz/utils":"2.0.0-main-a7b30c79","@latticexyz/world":"2.0.0-main-a7b30c79"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-a7b30c79","_integrity":"sha512-a5XFbJKMEW7+ChRWoPXz6oNlOqgU6zp3olKf8KPS2QSn4uEGQ/IRrRLlXljEYHToLlhwPvkvtHlKcBEg/g1Wzg==","_resolved":"/tmp/7cab2dd2cfc1b1837a6600a0bc7436a2/latticexyz-network-2.0.0-main-a7b30c79.tgz","_from":"file:latticexyz-network-2.0.0-main-a7b30c79.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-a5XFbJKMEW7+ChRWoPXz6oNlOqgU6zp3olKf8KPS2QSn4uEGQ/IRrRLlXljEYHToLlhwPvkvtHlKcBEg/g1Wzg==","shasum":"87fb7493db47dad9267e40789045287adf8e1c5f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-a7b30c79.tgz","fileCount":80,"unpackedSize":492983,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHNfxc8GC5HpoHh9ke7+I0QCvwYPdGAnKZYnX9HMu6RDAiBY3zz0paBQQSz7qDFaS0/Cu2LZW4HDVopobQUgmAP1Iw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-a7b30c79_1689676345232_0.01552860067710915"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-1e2ad78e":{"name":"@latticexyz/network","version":"2.0.0-main-1e2ad78e","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-1e2ad78e","@latticexyz/recs":"2.0.0-main-1e2ad78e","@latticexyz/schema-type":"2.0.0-main-1e2ad78e","@latticexyz/services":"2.0.0-main-1e2ad78e","@latticexyz/solecs":"2.0.0-main-1e2ad78e","@latticexyz/store":"2.0.0-main-1e2ad78e","@latticexyz/utils":"2.0.0-main-1e2ad78e","@latticexyz/world":"2.0.0-main-1e2ad78e"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-1e2ad78e","_integrity":"sha512-cIQiGz1bilHoX1mpn7k6ITW/HntxJ5MAaS02tC3ICucN9mM/HAVE62Zhzob+GNII91TE33SI+wWIGwGBUVKVzw==","_resolved":"/tmp/c028feeeece8e9dc8d85945b4d838984/latticexyz-network-2.0.0-main-1e2ad78e.tgz","_from":"file:latticexyz-network-2.0.0-main-1e2ad78e.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-cIQiGz1bilHoX1mpn7k6ITW/HntxJ5MAaS02tC3ICucN9mM/HAVE62Zhzob+GNII91TE33SI+wWIGwGBUVKVzw==","shasum":"6df2c7591f90f1a53e0964bd473b6a510246f06a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-1e2ad78e.tgz","fileCount":80,"unpackedSize":493080,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC7F9rCAY2/JmR3feRb2P+bi+ZiUkXVKdm0zgLp6y+4kAiA254ujuu3lfi+0xzBXah7LmY00ykf3bbFj5uYPBETWHQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-1e2ad78e_1689676448342_0.8013092007765843"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-48909d15":{"name":"@latticexyz/network","version":"2.0.0-main-48909d15","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-48909d15","@latticexyz/recs":"2.0.0-main-48909d15","@latticexyz/schema-type":"2.0.0-main-48909d15","@latticexyz/services":"2.0.0-main-48909d15","@latticexyz/solecs":"2.0.0-main-48909d15","@latticexyz/store":"2.0.0-main-48909d15","@latticexyz/utils":"2.0.0-main-48909d15","@latticexyz/world":"2.0.0-main-48909d15"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-48909d15","_integrity":"sha512-tE2a/PkAAdMqXtlORU6FATSDiueG9jrERZjOPa0RXYQ9B8pNv7PYGzES9t1xVCS8V91ZUSbD9pZSDwzzrMoCdg==","_resolved":"/tmp/3798ffc53c5724e12fb776a478aa4366/latticexyz-network-2.0.0-main-48909d15.tgz","_from":"file:latticexyz-network-2.0.0-main-48909d15.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-tE2a/PkAAdMqXtlORU6FATSDiueG9jrERZjOPa0RXYQ9B8pNv7PYGzES9t1xVCS8V91ZUSbD9pZSDwzzrMoCdg==","shasum":"9982fb0300e296963bb96892218283a2dfb63453","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-48909d15.tgz","fileCount":80,"unpackedSize":493177,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG7MYzF2mqFJ/FEHUDvdbfTPHvc0OVhdAs2FE8xzDD4EAiAWujmcprl7ZIRf2r6XiQxwj1+mk4oxDJjhHIrhVKgWhA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-48909d15_1689676491307_0.07446315542753923"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-4e4a3415":{"name":"@latticexyz/network","version":"2.0.0-main-4e4a3415","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-4e4a3415","@latticexyz/recs":"2.0.0-main-4e4a3415","@latticexyz/schema-type":"2.0.0-main-4e4a3415","@latticexyz/services":"2.0.0-main-4e4a3415","@latticexyz/solecs":"2.0.0-main-4e4a3415","@latticexyz/store":"2.0.0-main-4e4a3415","@latticexyz/utils":"2.0.0-main-4e4a3415","@latticexyz/world":"2.0.0-main-4e4a3415"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0","typedoc":"0.23.21","typedoc-plugin-markdown":"^3.13.6"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","docs":"rimraf API && typedoc src && find API -type f -name '*.md' -exec sed -E -i \"\" \"s/(#.*)(<.*>)/\\1/\" {} \\;","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-4e4a3415","_integrity":"sha512-x0eUhQ9vNSYzox4mBbzUjjZ4TQ6cR5wX17A/mW3qbnIP4DO9pa63EZR8ZJtoOxaDqDyetCQoFT0mPWY3JpGtdw==","_resolved":"/tmp/067b54b56b1b2e4575764942c46f6ad7/latticexyz-network-2.0.0-main-4e4a3415.tgz","_from":"file:latticexyz-network-2.0.0-main-4e4a3415.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-x0eUhQ9vNSYzox4mBbzUjjZ4TQ6cR5wX17A/mW3qbnIP4DO9pa63EZR8ZJtoOxaDqDyetCQoFT0mPWY3JpGtdw==","shasum":"bee5ebb841027500487efa5cf3445d49dee370d5","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-4e4a3415.tgz","fileCount":80,"unpackedSize":493274,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDXOpdrY7SdMTKexQqHUbhIxI29Np99lspa8/94yBSnegIhAOYcDAQhp13xbapQ6LCF+tFySCQaK3RoXAki9qjG5EGn"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-4e4a3415_1689677374973_0.30129226127268605"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-708122b7":{"name":"@latticexyz/network","version":"2.0.0-main-708122b7","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-708122b7","@latticexyz/recs":"2.0.0-main-708122b7","@latticexyz/schema-type":"2.0.0-main-708122b7","@latticexyz/services":"2.0.0-main-708122b7","@latticexyz/solecs":"2.0.0-main-708122b7","@latticexyz/store":"2.0.0-main-708122b7","@latticexyz/utils":"2.0.0-main-708122b7","@latticexyz/world":"2.0.0-main-708122b7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-708122b7","_integrity":"sha512-1wf+0hrh6rzR5uQIREDE7WYI729WA3SdAC8ZPAxYtVycBZv9rLK42z3OaLY1IdTYVMTXe4eRt+jMdAh5PjEV1Q==","_resolved":"/tmp/11282bd05f19c16d612409bdf6779174/latticexyz-network-2.0.0-main-708122b7.tgz","_from":"file:latticexyz-network-2.0.0-main-708122b7.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-1wf+0hrh6rzR5uQIREDE7WYI729WA3SdAC8ZPAxYtVycBZv9rLK42z3OaLY1IdTYVMTXe4eRt+jMdAh5PjEV1Q==","shasum":"e0afb7429591a10ff7020447ea435da7b88c3427","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-708122b7.tgz","fileCount":80,"unpackedSize":493081,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDMDWIQg58jPshjCsv+SeWv9i9J6rdskt3RO/Lf53B1qwIhANZNvWyvoIzZpMesnbexVf+QZkT4wYpuNPvn/z0dmEUs"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-708122b7_1689678244759_0.08040837018185187"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-b0a1a727":{"name":"@latticexyz/network","version":"2.0.0-main-b0a1a727","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-b0a1a727","@latticexyz/recs":"2.0.0-main-b0a1a727","@latticexyz/schema-type":"2.0.0-main-b0a1a727","@latticexyz/services":"2.0.0-main-b0a1a727","@latticexyz/solecs":"2.0.0-main-b0a1a727","@latticexyz/store":"2.0.0-main-b0a1a727","@latticexyz/utils":"2.0.0-main-b0a1a727","@latticexyz/world":"2.0.0-main-b0a1a727"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-b0a1a727","_integrity":"sha512-JUjzBsPn9/bIoaebaaGsHEkMZEh03LLQQT4nOf8CUZN1TK/T9pvdxWJrw9WN4SQ740WnpGEjjyEzshhrIRUjeQ==","_resolved":"/tmp/a570d40f839ec3a7a4bb4dd8eb0821c7/latticexyz-network-2.0.0-main-b0a1a727.tgz","_from":"file:latticexyz-network-2.0.0-main-b0a1a727.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-JUjzBsPn9/bIoaebaaGsHEkMZEh03LLQQT4nOf8CUZN1TK/T9pvdxWJrw9WN4SQ740WnpGEjjyEzshhrIRUjeQ==","shasum":"3ecc48a2d5056c0f487dc718fd0a2265dffacda2","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-b0a1a727.tgz","fileCount":80,"unpackedSize":493081,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDxYRxA74061KKHtt4Apn/9QUZtNefOB3NquQKPl7IsBAIhAMbyssBNmP9/m/rPd8on4K07904JwGQaLRycHnqn9LL2"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-b0a1a727_1689687193159_0.31379074361563797"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-b38f2df1":{"name":"@latticexyz/network","version":"2.0.0-main-b38f2df1","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-b38f2df1","@latticexyz/recs":"2.0.0-main-b38f2df1","@latticexyz/schema-type":"2.0.0-main-b38f2df1","@latticexyz/services":"2.0.0-main-b38f2df1","@latticexyz/solecs":"2.0.0-main-b38f2df1","@latticexyz/store":"2.0.0-main-b38f2df1","@latticexyz/utils":"2.0.0-main-b38f2df1","@latticexyz/world":"2.0.0-main-b38f2df1"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-b38f2df1","_integrity":"sha512-k1cTzYYcnofLjMYt22rzVJPkMUryN3XgpKnRf5Duob8Kdyvh7g0T3zZ2hiKEPqcb4g6A6bV+Kdv8F6akM1aaIg==","_resolved":"/tmp/1dac69e87a29f500f7edb5807e61cddd/latticexyz-network-2.0.0-main-b38f2df1.tgz","_from":"file:latticexyz-network-2.0.0-main-b38f2df1.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-k1cTzYYcnofLjMYt22rzVJPkMUryN3XgpKnRf5Duob8Kdyvh7g0T3zZ2hiKEPqcb4g6A6bV+Kdv8F6akM1aaIg==","shasum":"91be675066acc5719000f86d5ac2a096bbcefc3a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-b38f2df1.tgz","fileCount":80,"unpackedSize":493081,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFwTulnn1qnTcWnFFcbIWsuu+BVEbTOssJxMNC8vXR7VAiBzRfRzDaKvKl0L2ueGmq2usUH0Wi1fOkrmQhCmcnJclg=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-b38f2df1_1689688850635_0.773956052567722"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-9cdcd02e":{"name":"@latticexyz/network","version":"2.0.0-main-9cdcd02e","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-9cdcd02e","@latticexyz/recs":"2.0.0-main-9cdcd02e","@latticexyz/schema-type":"2.0.0-main-9cdcd02e","@latticexyz/services":"2.0.0-main-9cdcd02e","@latticexyz/solecs":"2.0.0-main-9cdcd02e","@latticexyz/store":"2.0.0-main-9cdcd02e","@latticexyz/utils":"2.0.0-main-9cdcd02e","@latticexyz/world":"2.0.0-main-9cdcd02e"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-9cdcd02e","_integrity":"sha512-pcbzwz8acQpfQx2xCftkAAIuevZD9Y/es2+I+5SbtRds9p5LewGBzfMIubNhN4ETRr9eHlZu+9k6XUcUi25fSw==","_resolved":"/tmp/dc3cc0360243eaf35e548bb941087565/latticexyz-network-2.0.0-main-9cdcd02e.tgz","_from":"file:latticexyz-network-2.0.0-main-9cdcd02e.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-pcbzwz8acQpfQx2xCftkAAIuevZD9Y/es2+I+5SbtRds9p5LewGBzfMIubNhN4ETRr9eHlZu+9k6XUcUi25fSw==","shasum":"971389a5c5c86a15677d86c5dd3cfb79851d51ba","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-9cdcd02e.tgz","fileCount":80,"unpackedSize":493081,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCoICsUp3U1zopVe9XE0pQ1wCVCOYsx+kamNACHUD0ahQIgQffO+/lf5CmEYa+8/a4q0JpnN+4KRo2xa/WlRBmoRwk="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-9cdcd02e_1689689603408_0.7806804202004882"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-f03531d9":{"name":"@latticexyz/network","version":"2.0.0-main-f03531d9","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-f03531d9","@latticexyz/recs":"2.0.0-main-f03531d9","@latticexyz/schema-type":"2.0.0-main-f03531d9","@latticexyz/services":"2.0.0-main-f03531d9","@latticexyz/solecs":"2.0.0-main-f03531d9","@latticexyz/store":"2.0.0-main-f03531d9","@latticexyz/utils":"2.0.0-main-f03531d9","@latticexyz/world":"2.0.0-main-f03531d9"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-f03531d9","_integrity":"sha512-qvBnQjB7HF+/SQxft/EOkGQ5i2sQpYN7ix9SPC8GJ3a9eC4Cs4lcJjl3quI1QVoTurbpMk2dEsxVBEH0COFcJw==","_resolved":"/tmp/f0503190f59f912bdebbab62faf90250/latticexyz-network-2.0.0-main-f03531d9.tgz","_from":"file:latticexyz-network-2.0.0-main-f03531d9.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-qvBnQjB7HF+/SQxft/EOkGQ5i2sQpYN7ix9SPC8GJ3a9eC4Cs4lcJjl3quI1QVoTurbpMk2dEsxVBEH0COFcJw==","shasum":"cc0154d3ca36d165b09a3b6fac5356e4513e9bcf","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-f03531d9.tgz","fileCount":80,"unpackedSize":493178,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDtkDygCQ2P54gglUUC65GLJlY0qZ8Yy8JEUGsBq6FD9AiEAhxEo0cqYIi/uBwBCJvRPgKM5m9HxBjJGbbWbxfrkSEk="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-f03531d9_1689703059032_0.3083078163053583"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-4bb7e8cb":{"name":"@latticexyz/network","version":"2.0.0-main-4bb7e8cb","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-4bb7e8cb","@latticexyz/recs":"2.0.0-main-4bb7e8cb","@latticexyz/schema-type":"2.0.0-main-4bb7e8cb","@latticexyz/services":"2.0.0-main-4bb7e8cb","@latticexyz/solecs":"2.0.0-main-4bb7e8cb","@latticexyz/store":"2.0.0-main-4bb7e8cb","@latticexyz/utils":"2.0.0-main-4bb7e8cb","@latticexyz/world":"2.0.0-main-4bb7e8cb"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-4bb7e8cb","_integrity":"sha512-1twFBJJE4Wiu1sCo7R0mBK1X26IZlHo9JoExgrB7xbER2ZF6X4G7SsagJ8Fh0iZ+w0ToLdvHi8GG+zJj15kjvQ==","_resolved":"/tmp/75790994f6c8e68f8685e818ca68dbf8/latticexyz-network-2.0.0-main-4bb7e8cb.tgz","_from":"file:latticexyz-network-2.0.0-main-4bb7e8cb.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-1twFBJJE4Wiu1sCo7R0mBK1X26IZlHo9JoExgrB7xbER2ZF6X4G7SsagJ8Fh0iZ+w0ToLdvHi8GG+zJj15kjvQ==","shasum":"977baf51a2a2edd80f993e53948e8909d31543da","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-4bb7e8cb.tgz","fileCount":80,"unpackedSize":493178,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFJhqM4PLf3wJ9PagVudvEx/zvOeeVYJfYwfUTRH7KgcAiEA3iQgNainz/HrcWX6AGsVVBKRPFlWGSkG9iZEHIbPgIY="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-4bb7e8cb_1689753869474_0.7062437019924368"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-df85e0c0":{"name":"@latticexyz/network","version":"2.0.0-main-df85e0c0","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-main-df85e0c0","@latticexyz/recs":"2.0.0-main-df85e0c0","@latticexyz/schema-type":"2.0.0-main-df85e0c0","@latticexyz/services":"2.0.0-main-df85e0c0","@latticexyz/solecs":"2.0.0-main-df85e0c0","@latticexyz/store":"2.0.0-main-df85e0c0","@latticexyz/utils":"2.0.0-main-df85e0c0","@latticexyz/world":"2.0.0-main-df85e0c0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-df85e0c0","_integrity":"sha512-85+BEFLMDnvz4xSMVXw+7ZCAQPF0JanV10JYm6Fcc+3BpzvbUe1Jhz3vBNrCh2KJMkfM+Fr2Nox8NnZi1S2wTQ==","_resolved":"/tmp/89fc006ba5cca338a0682ada514c65b6/latticexyz-network-2.0.0-main-df85e0c0.tgz","_from":"file:latticexyz-network-2.0.0-main-df85e0c0.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-85+BEFLMDnvz4xSMVXw+7ZCAQPF0JanV10JYm6Fcc+3BpzvbUe1Jhz3vBNrCh2KJMkfM+Fr2Nox8NnZi1S2wTQ==","shasum":"4dce9bef921e4ee4a2e23947d235ef3f4cce7b5f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-df85e0c0.tgz","fileCount":80,"unpackedSize":493178,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDxZNaefk0ARymmvK4ehx7OhbuvF+i7TBTPsnnmBGJMQAiA+/j/838u6gi9Rm0h+OVSoATQ0zFgC7AbS3k/ylS2i7A=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-df85e0c0_1689756460539_0.8314406366831555"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-indexing-1d07fea9":{"name":"@latticexyz/network","version":"2.0.0-indexing-1d07fea9","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@wagmi/chains":"^0.2.22","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.1.7","@latticexyz/common":"2.0.0-indexing-1d07fea9","@latticexyz/recs":"2.0.0-indexing-1d07fea9","@latticexyz/schema-type":"2.0.0-indexing-1d07fea9","@latticexyz/services":"2.0.0-indexing-1d07fea9","@latticexyz/solecs":"2.0.0-indexing-1d07fea9","@latticexyz/store":"2.0.0-indexing-1d07fea9","@latticexyz/utils":"2.0.0-indexing-1d07fea9","@latticexyz/world":"2.0.0-indexing-1d07fea9"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-indexing-1d07fea9","_integrity":"sha512-hpf5Ax6n5TOozeE7+gucET+3/5L4nUXBEe7tOubN/3qFlxvI8VCqO1y9UvSP0P5WKlKBuf01uPSVcMcL7Dl89A==","_resolved":"/tmp/4c0be35a0627f2f62d587fe6be6ce1b5/latticexyz-network-2.0.0-indexing-1d07fea9.tgz","_from":"file:latticexyz-network-2.0.0-indexing-1d07fea9.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-hpf5Ax6n5TOozeE7+gucET+3/5L4nUXBEe7tOubN/3qFlxvI8VCqO1y9UvSP0P5WKlKBuf01uPSVcMcL7Dl89A==","shasum":"cfd98e6aecb09f0f6eaf2632046da1c7f71068fb","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-indexing-1d07fea9.tgz","fileCount":80,"unpackedSize":494494,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDMi5NV+6B5CdhFXwvZDkqXiqf/VSOojvjm6dgr8s4WcAiEA++v4wZSREdraymwPyTKKoxZztyZbHCMV2mqwmg26kl4="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-indexing-1d07fea9_1689772622519_0.5467236324015343"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-53522998":{"name":"@latticexyz/network","version":"2.0.0-main-53522998","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.0","@latticexyz/common":"2.0.0-main-53522998","@latticexyz/recs":"2.0.0-main-53522998","@latticexyz/schema-type":"2.0.0-main-53522998","@latticexyz/services":"2.0.0-main-53522998","@latticexyz/solecs":"2.0.0-main-53522998","@latticexyz/store":"2.0.0-main-53522998","@latticexyz/utils":"2.0.0-main-53522998","@latticexyz/world":"2.0.0-main-53522998"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-53522998","_integrity":"sha512-CwqrSODL3j/o3o1vP0ggYFeMtKx7Ge+sZM0tITdOsGw3sQ7HpD/rhMC9cG6fz4dnEijrS0M4MkqISdmEw6m1vw==","_resolved":"/tmp/a68744ad944b34e6a89cb82fc129080f/latticexyz-network-2.0.0-main-53522998.tgz","_from":"file:latticexyz-network-2.0.0-main-53522998.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-CwqrSODL3j/o3o1vP0ggYFeMtKx7Ge+sZM0tITdOsGw3sQ7HpD/rhMC9cG6fz4dnEijrS0M4MkqISdmEw6m1vw==","shasum":"61bde62eb9cefb8aa93975454af22c16ef1672a6","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-53522998.tgz","fileCount":80,"unpackedSize":493917,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG1DMJWismBx69t4cDYT3+cCWMO73ZiC+DLh4m4FActLAiEAuEx4s49HDsYxOkuEjswu5oVQcD8RX1+B4TcBHClWTBI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-53522998_1689779472585_0.055609810035762264"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-0c4f9fea":{"name":"@latticexyz/network","version":"2.0.0-main-0c4f9fea","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.0","@latticexyz/common":"2.0.0-main-0c4f9fea","@latticexyz/recs":"2.0.0-main-0c4f9fea","@latticexyz/schema-type":"2.0.0-main-0c4f9fea","@latticexyz/services":"2.0.0-main-0c4f9fea","@latticexyz/solecs":"2.0.0-main-0c4f9fea","@latticexyz/store":"2.0.0-main-0c4f9fea","@latticexyz/utils":"2.0.0-main-0c4f9fea","@latticexyz/world":"2.0.0-main-0c4f9fea"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-0c4f9fea","_integrity":"sha512-8/v5d2zVqJBPXl6rYg1iPpd+m7Nh7tQkTfE44F9astLB6eQPdJlKskYZNGmlwXAEKqIW1ubZZLMZ6DEJjzWaOg==","_resolved":"/tmp/9233d779687f47d16166842b7506ec3c/latticexyz-network-2.0.0-main-0c4f9fea.tgz","_from":"file:latticexyz-network-2.0.0-main-0c4f9fea.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-8/v5d2zVqJBPXl6rYg1iPpd+m7Nh7tQkTfE44F9astLB6eQPdJlKskYZNGmlwXAEKqIW1ubZZLMZ6DEJjzWaOg==","shasum":"67fbd8a646a4852c4cc0a3273ea82f6a543e0e3f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-0c4f9fea.tgz","fileCount":80,"unpackedSize":494014,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHW0FYCBj6hk11Kk7ebMYihUXyX6C8nJxbdQ5DxxuYLeAiEA/MFtOOZNp5iyhwRRFn0IfWW0uidJNB5OCVF0XDQ8axU="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-0c4f9fea_1689779558474_0.17879601954863045"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-eeb15cc0":{"name":"@latticexyz/network","version":"2.0.0-main-eeb15cc0","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.0","@latticexyz/common":"2.0.0-main-eeb15cc0","@latticexyz/recs":"2.0.0-main-eeb15cc0","@latticexyz/schema-type":"2.0.0-main-eeb15cc0","@latticexyz/services":"2.0.0-main-eeb15cc0","@latticexyz/solecs":"2.0.0-main-eeb15cc0","@latticexyz/store":"2.0.0-main-eeb15cc0","@latticexyz/utils":"2.0.0-main-eeb15cc0","@latticexyz/world":"2.0.0-main-eeb15cc0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-eeb15cc0","_integrity":"sha512-F1O7ynYzHpgipqOY6iMWIEpl67IR5XCGAzpJ/u57qSHncgIv3nUya88QG0CcxR/fET9E3M7Y8xJiluPIXEUKbg==","_resolved":"/tmp/8e5909bf636409eaded8b5627b3589b4/latticexyz-network-2.0.0-main-eeb15cc0.tgz","_from":"file:latticexyz-network-2.0.0-main-eeb15cc0.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-F1O7ynYzHpgipqOY6iMWIEpl67IR5XCGAzpJ/u57qSHncgIv3nUya88QG0CcxR/fET9E3M7Y8xJiluPIXEUKbg==","shasum":"2bdece8b5acff5da3d7c8fa088142176c74bd2da","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-eeb15cc0.tgz","fileCount":80,"unpackedSize":494014,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDFgnhVBwmz/GQ230HoPCJckiZgNNB0YZN7gDxxFK93NwIhAJu4ONCpiOqQTpm4Bwi77VSBcfRAVn+TN5Waq33Us3sd"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-eeb15cc0_1689783896629_0.8686203998920012"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-353b9aa2":{"name":"@latticexyz/network","version":"2.0.0-main-353b9aa2","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-353b9aa2","@latticexyz/recs":"2.0.0-main-353b9aa2","@latticexyz/schema-type":"2.0.0-main-353b9aa2","@latticexyz/services":"2.0.0-main-353b9aa2","@latticexyz/solecs":"2.0.0-main-353b9aa2","@latticexyz/store":"2.0.0-main-353b9aa2","@latticexyz/utils":"2.0.0-main-353b9aa2","@latticexyz/world":"2.0.0-main-353b9aa2"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-353b9aa2","_integrity":"sha512-kIYuQfMndPNUUucYA2VXmJ6BsUh1ZV3XSVuyhqRBqFld8i/r28Fp3DItYUopzPetcoTHGoWZ+XxWB5sCHNmGNQ==","_resolved":"/tmp/a259711e7567433a180f9af8f04dd0c5/latticexyz-network-2.0.0-main-353b9aa2.tgz","_from":"file:latticexyz-network-2.0.0-main-353b9aa2.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-kIYuQfMndPNUUucYA2VXmJ6BsUh1ZV3XSVuyhqRBqFld8i/r28Fp3DItYUopzPetcoTHGoWZ+XxWB5sCHNmGNQ==","shasum":"2f4ea0a9b1261e271ac36795590706689391a351","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-353b9aa2.tgz","fileCount":80,"unpackedSize":494014,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDu2tRYDhH+VxM1MmCaD3OjsAwEIaIhDAjzMP5LOzO1MwIhANxhvfzMZIXtKAIrV4Kou5uXk3/0yA6WSeUJjafkU0FJ"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-353b9aa2_1689865021217_0.31904039860146516"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-6de86f16":{"name":"@latticexyz/network","version":"2.0.0-main-6de86f16","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-6de86f16","@latticexyz/recs":"2.0.0-main-6de86f16","@latticexyz/schema-type":"2.0.0-main-6de86f16","@latticexyz/services":"2.0.0-main-6de86f16","@latticexyz/solecs":"2.0.0-main-6de86f16","@latticexyz/store":"2.0.0-main-6de86f16","@latticexyz/utils":"2.0.0-main-6de86f16","@latticexyz/world":"2.0.0-main-6de86f16"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-6de86f16","_integrity":"sha512-fR4ENyvdTd++bN4p0UDbQOnZkEdvByHIQMOCAZuRNbktRoPdGjXTy3JFo3DaQGkLcLdr8FfiV2yXiX8Z71mTWg==","_resolved":"/tmp/8ca30d3237e361f9b3f24541cc56dc80/latticexyz-network-2.0.0-main-6de86f16.tgz","_from":"file:latticexyz-network-2.0.0-main-6de86f16.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-fR4ENyvdTd++bN4p0UDbQOnZkEdvByHIQMOCAZuRNbktRoPdGjXTy3JFo3DaQGkLcLdr8FfiV2yXiX8Z71mTWg==","shasum":"070422675a990c69f54b2e10960bd30b2e7a0d17","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-6de86f16.tgz","fileCount":80,"unpackedSize":494014,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD76YQShwVQZo/slhyFe8RQREyDgI5p304mwu8HZbS3xwIgHc4dOcDmEFIFyHFXvn5RaHid0ROJSifb2fBO/7ceBP4="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-6de86f16_1689924930103_0.04170821227091026"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-69a96f10":{"name":"@latticexyz/network","version":"2.0.0-main-69a96f10","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-69a96f10","@latticexyz/recs":"2.0.0-main-69a96f10","@latticexyz/schema-type":"2.0.0-main-69a96f10","@latticexyz/services":"2.0.0-main-69a96f10","@latticexyz/solecs":"2.0.0-main-69a96f10","@latticexyz/store":"2.0.0-main-69a96f10","@latticexyz/utils":"2.0.0-main-69a96f10","@latticexyz/world":"2.0.0-main-69a96f10"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-69a96f10","_integrity":"sha512-bccUEoIlpKQ4lVdlLi5mfL9Xql1Jmf4FMZ8i0toMKIP6JALWtgQhBc3knB5tKPE6FwCD/trR6qi7D7tcv0aFNg==","_resolved":"/tmp/bfc4a715de7e44f428db103d240cef58/latticexyz-network-2.0.0-main-69a96f10.tgz","_from":"file:latticexyz-network-2.0.0-main-69a96f10.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-bccUEoIlpKQ4lVdlLi5mfL9Xql1Jmf4FMZ8i0toMKIP6JALWtgQhBc3knB5tKPE6FwCD/trR6qi7D7tcv0aFNg==","shasum":"400c723dedebab105a0c916148b74fc7e741284c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-69a96f10.tgz","fileCount":80,"unpackedSize":494014,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIATVN7dhJ2Z8EXsNubslw2M5N+bbW/adZvV8vy/oOXi2AiEA6d2MixlXWZw/VMAbMViAIhXyS43Mh12xCbmIOW2xtug="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-69a96f10_1689933202239_0.31422565668360014"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-next.0":{"name":"@latticexyz/network","version":"2.0.0-next.0","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-next.0","@latticexyz/recs":"2.0.0-next.0","@latticexyz/schema-type":"2.0.0-next.0","@latticexyz/services":"2.0.0-next.0","@latticexyz/solecs":"2.0.0-next.0","@latticexyz/store":"2.0.0-next.0","@latticexyz/utils":"2.0.0-next.0","@latticexyz/world":"2.0.0-next.0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-next.0","_integrity":"sha512-9/XqgE/PAPiACtEWnIXs9o/OpR3npwEXNzkwxt3++G9B0wVQ8khkBtvr0yHWsR45hP20GDirKx5KvRad3pGVWg==","_resolved":"/tmp/151968f055b2e8eb5b922142f09bc24f/latticexyz-network-2.0.0-next.0.tgz","_from":"file:latticexyz-network-2.0.0-next.0.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-9/XqgE/PAPiACtEWnIXs9o/OpR3npwEXNzkwxt3++G9B0wVQ8khkBtvr0yHWsR45hP20GDirKx5KvRad3pGVWg==","shasum":"659d44ed042423d0c65699d9ab406b2482345521","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-next.0.tgz","fileCount":80,"unpackedSize":493888,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC4fODJNgSen8lmvxi7JaRl7BygNr7Nvpd/8XkCU7ToQgIhAPJoU2yKiRNpmoiMDF0+MtygKa+m/Xa0hP0t7oPkosW6"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-next.0_1689950857727_0.479770970966064"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-indexing-3b1f31fc":{"name":"@latticexyz/network","version":"2.0.0-indexing-3b1f31fc","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-indexing-3b1f31fc","@latticexyz/recs":"2.0.0-indexing-3b1f31fc","@latticexyz/schema-type":"2.0.0-indexing-3b1f31fc","@latticexyz/services":"2.0.0-indexing-3b1f31fc","@latticexyz/solecs":"2.0.0-indexing-3b1f31fc","@latticexyz/store":"2.0.0-indexing-3b1f31fc","@latticexyz/utils":"2.0.0-indexing-3b1f31fc","@latticexyz/world":"2.0.0-indexing-3b1f31fc"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-indexing-3b1f31fc","_integrity":"sha512-RkjYHjlwRG/h8hmc2tnkFn78bL/2xvTm0AjS5GOE1yUGUfbbo2SUXjUjR3XOxN5aq2ux0iW9poNgqcmwbuxGTA==","_resolved":"/tmp/a9147e5657627942f7e08a83cfacea7e/latticexyz-network-2.0.0-indexing-3b1f31fc.tgz","_from":"file:latticexyz-network-2.0.0-indexing-3b1f31fc.tgz","_nodeVersion":"18.17.0","_npmVersion":"9.6.7","dist":{"integrity":"sha512-RkjYHjlwRG/h8hmc2tnkFn78bL/2xvTm0AjS5GOE1yUGUfbbo2SUXjUjR3XOxN5aq2ux0iW9poNgqcmwbuxGTA==","shasum":"559c57dfd8caf4a602d271c928a6f4e148aacf1b","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-indexing-3b1f31fc.tgz","fileCount":80,"unpackedSize":495330,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDaRbNEm+qMzTcgK6Lq9lpgJ9bZ3OYxjIbeOgovKAydlwIhAK+DW+Eam3VRpTWK+aNtwNsjKHGFKGlWObizhiDX7+Js"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-indexing-3b1f31fc_1690292868834_0.6374848204240451"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-indexing-3fee14a7":{"name":"@latticexyz/network","version":"2.0.0-indexing-3fee14a7","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-indexing-3fee14a7","@latticexyz/recs":"2.0.0-indexing-3fee14a7","@latticexyz/schema-type":"2.0.0-indexing-3fee14a7","@latticexyz/services":"2.0.0-indexing-3fee14a7","@latticexyz/solecs":"2.0.0-indexing-3fee14a7","@latticexyz/store":"2.0.0-indexing-3fee14a7","@latticexyz/utils":"2.0.0-indexing-3fee14a7","@latticexyz/world":"2.0.0-indexing-3fee14a7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-indexing-3fee14a7","_integrity":"sha512-mbhRoWJUbE4hLhHIAxlY39g0DxZeIp5xeRVQutBglmJCcwIfd55sNRuc2dxDu1hFKwZw/FY6xQAOZqmwQtueCg==","_resolved":"/tmp/15bd8dc04aac7f238428b68e1a1c1292/latticexyz-network-2.0.0-indexing-3fee14a7.tgz","_from":"file:latticexyz-network-2.0.0-indexing-3fee14a7.tgz","_nodeVersion":"18.17.0","_npmVersion":"9.6.7","dist":{"integrity":"sha512-mbhRoWJUbE4hLhHIAxlY39g0DxZeIp5xeRVQutBglmJCcwIfd55sNRuc2dxDu1hFKwZw/FY6xQAOZqmwQtueCg==","shasum":"f08d17d1cab297e01c73df784f3c7d1cbad4c4a7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-indexing-3fee14a7.tgz","fileCount":80,"unpackedSize":495379,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA7lbql39DpQ9Ko/14T8XhDoiLXrd0phkovDd9E1J4eUAiBev5kl1pI8OZyE31aGIIH8jadFvjQ7Asjk3PV+2671xQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-indexing-3fee14a7_1690394713340_0.7535010706748113"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-70e4d8eb":{"name":"@latticexyz/network","version":"2.0.0-main-70e4d8eb","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-70e4d8eb","@latticexyz/recs":"2.0.0-main-70e4d8eb","@latticexyz/schema-type":"2.0.0-main-70e4d8eb","@latticexyz/services":"2.0.0-main-70e4d8eb","@latticexyz/solecs":"2.0.0-main-70e4d8eb","@latticexyz/store":"2.0.0-main-70e4d8eb","@latticexyz/utils":"2.0.0-main-70e4d8eb","@latticexyz/world":"2.0.0-main-70e4d8eb"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-70e4d8eb","_integrity":"sha512-t5WTe/wH0jMbWKDzUdLPHBBfnpHWJSlT6d3MbaGhFfewu14o2e/+XE9bDoB3Dbm+hW1cd5WnTbdOmkUUaNfSGQ==","_resolved":"/tmp/f2d9a928be48e7acdb7a56ecdab7904f/latticexyz-network-2.0.0-main-70e4d8eb.tgz","_from":"file:latticexyz-network-2.0.0-main-70e4d8eb.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-t5WTe/wH0jMbWKDzUdLPHBBfnpHWJSlT6d3MbaGhFfewu14o2e/+XE9bDoB3Dbm+hW1cd5WnTbdOmkUUaNfSGQ==","shasum":"1c65050e9ad95b543a542dbb1b0a43e2066dc8b3","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-70e4d8eb.tgz","fileCount":80,"unpackedSize":496370,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDBkgebqfqtRUd02at+m420A93vj2gPkrJ9ZmZe16zDoQIgFl9DsuDa5muvotbe6AXh5b0zteKjYQ24d+MhOfKHkkE="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-70e4d8eb_1690481495298_0.5235655500618792"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-e259ef79":{"name":"@latticexyz/network","version":"2.0.0-main-e259ef79","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-e259ef79","@latticexyz/recs":"2.0.0-main-e259ef79","@latticexyz/schema-type":"2.0.0-main-e259ef79","@latticexyz/services":"2.0.0-main-e259ef79","@latticexyz/solecs":"2.0.0-main-e259ef79","@latticexyz/store":"2.0.0-main-e259ef79","@latticexyz/utils":"2.0.0-main-e259ef79","@latticexyz/world":"2.0.0-main-e259ef79"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-e259ef79","_integrity":"sha512-X/GTZ6wkUHVeWY/XQ6YZnmqZ+Zqm55Sb1S4dpwLGpcmSxCG7h+2pDje1shPngsdtO4kom42YJBr9oC0in7IlTg==","_resolved":"/tmp/e618460cd289ae04df70f02376f17aa5/latticexyz-network-2.0.0-main-e259ef79.tgz","_from":"file:latticexyz-network-2.0.0-main-e259ef79.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-X/GTZ6wkUHVeWY/XQ6YZnmqZ+Zqm55Sb1S4dpwLGpcmSxCG7h+2pDje1shPngsdtO4kom42YJBr9oC0in7IlTg==","shasum":"b7b9c2c9699a62b5cddd677c6a9416ef0efb5520","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-e259ef79.tgz","fileCount":80,"unpackedSize":496370,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDDf8dc3SQ6V3LRoACVkJGth54h8zJP+ZN09UGQEOkAWAIhAIrEqIZ/AMc2C8xs3jTgIGvm+78Vn7TjurPC10c0s3xz"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-e259ef79_1690538229457_0.024695985698897305"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-5e9eb5a7":{"name":"@latticexyz/network","version":"2.0.0-main-5e9eb5a7","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-5e9eb5a7","@latticexyz/recs":"2.0.0-main-5e9eb5a7","@latticexyz/schema-type":"2.0.0-main-5e9eb5a7","@latticexyz/services":"2.0.0-main-5e9eb5a7","@latticexyz/solecs":"2.0.0-main-5e9eb5a7","@latticexyz/store":"2.0.0-main-5e9eb5a7","@latticexyz/utils":"2.0.0-main-5e9eb5a7","@latticexyz/world":"2.0.0-main-5e9eb5a7"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-5e9eb5a7","_integrity":"sha512-uTJRh76ElT5Cd8PuAnfwSDKsNIvQgU9R04EMEGo8txw9iwj/VG7qDq+XwGfOqrm4zKp+zLKwzqFwHLa8YW5N9Q==","_resolved":"/tmp/d6c48ce49603572640e1f1de009c1f46/latticexyz-network-2.0.0-main-5e9eb5a7.tgz","_from":"file:latticexyz-network-2.0.0-main-5e9eb5a7.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-uTJRh76ElT5Cd8PuAnfwSDKsNIvQgU9R04EMEGo8txw9iwj/VG7qDq+XwGfOqrm4zKp+zLKwzqFwHLa8YW5N9Q==","shasum":"ac33cdd8a8a32284a64183993c62592479fe8706","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-5e9eb5a7.tgz","fileCount":80,"unpackedSize":496370,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCvel0vvrbi+VxBhqjfQKMdwp62PGQ1Iq2OQ0bCmpq9zQIgW5mS7wP6YUrf5gpdm05GfQSC7MsySaLUg9UE1ZfLc5s="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-5e9eb5a7_1690539504437_0.9819623663250676"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-8dc847d4":{"name":"@latticexyz/network","version":"2.0.0-main-8dc847d4","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-8dc847d4","@latticexyz/recs":"2.0.0-main-8dc847d4","@latticexyz/schema-type":"2.0.0-main-8dc847d4","@latticexyz/services":"2.0.0-main-8dc847d4","@latticexyz/solecs":"2.0.0-main-8dc847d4","@latticexyz/store":"2.0.0-main-8dc847d4","@latticexyz/utils":"2.0.0-main-8dc847d4","@latticexyz/world":"2.0.0-main-8dc847d4"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-8dc847d4","_integrity":"sha512-oNIGkdZcP4i25u580BhZm6yn9AtRMPhW81UP/M9dN5PbmFj6WdcMx+GZlgiGjj3Wwfw8NS65A1U1E342IUo63g==","_resolved":"/tmp/5aa01cc58500e148cab00ea894db4348/latticexyz-network-2.0.0-main-8dc847d4.tgz","_from":"file:latticexyz-network-2.0.0-main-8dc847d4.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-oNIGkdZcP4i25u580BhZm6yn9AtRMPhW81UP/M9dN5PbmFj6WdcMx+GZlgiGjj3Wwfw8NS65A1U1E342IUo63g==","shasum":"5957fb16f2f87b12699c8e0f36e2fdb4b56be143","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-8dc847d4.tgz","fileCount":80,"unpackedSize":496370,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDJW7zJFdnf+m8FOnL2+79CANPKSn7rhOtPsI3GSPW90AIhAJXthWPs+Wna/qieHfMQ0JVdu8aNrTAEimAnkAmfCw0j"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-8dc847d4_1690539888958_0.3553183397076125"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-c963b46c":{"name":"@latticexyz/network","version":"2.0.0-main-c963b46c","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-c963b46c","@latticexyz/recs":"2.0.0-main-c963b46c","@latticexyz/schema-type":"2.0.0-main-c963b46c","@latticexyz/services":"2.0.0-main-c963b46c","@latticexyz/solecs":"2.0.0-main-c963b46c","@latticexyz/store":"2.0.0-main-c963b46c","@latticexyz/utils":"2.0.0-main-c963b46c","@latticexyz/world":"2.0.0-main-c963b46c"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-c963b46c","_integrity":"sha512-veFsn56IlME8JQ9VS3BUg/7X77ZuzNgEHEfA6cQoB9LqQ6Nyvn4S17AqBZktNLqxPCjAGR16R+BxNWI6maqu+Q==","_resolved":"/tmp/0abffe855e8f4cca57282125b8d5ecd3/latticexyz-network-2.0.0-main-c963b46c.tgz","_from":"file:latticexyz-network-2.0.0-main-c963b46c.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-veFsn56IlME8JQ9VS3BUg/7X77ZuzNgEHEfA6cQoB9LqQ6Nyvn4S17AqBZktNLqxPCjAGR16R+BxNWI6maqu+Q==","shasum":"9f0ca1e79195ad46d6ef81b8604b241e6f9a851f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-c963b46c.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDzNmHvPQ0cm0Fjwt0VbwpqJv8+01ZTXqTTdmcEJrsQRQIgaRA7t7VD2k3iuYDeiG977U6Oyy1waZWe0kmJCJoeQYk="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-c963b46c_1690554902972_0.555645686587086"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-168a4cb4":{"name":"@latticexyz/network","version":"2.0.0-main-168a4cb4","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-168a4cb4","@latticexyz/recs":"2.0.0-main-168a4cb4","@latticexyz/schema-type":"2.0.0-main-168a4cb4","@latticexyz/services":"2.0.0-main-168a4cb4","@latticexyz/solecs":"2.0.0-main-168a4cb4","@latticexyz/store":"2.0.0-main-168a4cb4","@latticexyz/utils":"2.0.0-main-168a4cb4","@latticexyz/world":"2.0.0-main-168a4cb4"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-168a4cb4","_integrity":"sha512-w0h+5QbW2rPQtwsqvJdXBPS+ljyzL6frh4GKldUgw95wKjJq8tzx/0NEB79Dp3W1GVxA5RE2bPi62fDWCQZl5Q==","_resolved":"/tmp/30ffdc155071f55b2bd2dadb3baef021/latticexyz-network-2.0.0-main-168a4cb4.tgz","_from":"file:latticexyz-network-2.0.0-main-168a4cb4.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-w0h+5QbW2rPQtwsqvJdXBPS+ljyzL6frh4GKldUgw95wKjJq8tzx/0NEB79Dp3W1GVxA5RE2bPi62fDWCQZl5Q==","shasum":"0a27d9fbb07d3e286dd105e8d56e30c6688b14fe","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-168a4cb4.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEyyjMyDvKrWO8zs9yC5rLgl68RG9Gj7WnQvC+qjxbrVAiEAljgWtwAqOhrk+wisKEheTf/2TC2MyKYQ4jhBEpTx7N4="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-168a4cb4_1690555647517_0.11538146054151777"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-16d8c43e":{"name":"@latticexyz/network","version":"2.0.0-main-16d8c43e","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-16d8c43e","@latticexyz/recs":"2.0.0-main-16d8c43e","@latticexyz/schema-type":"2.0.0-main-16d8c43e","@latticexyz/services":"2.0.0-main-16d8c43e","@latticexyz/solecs":"2.0.0-main-16d8c43e","@latticexyz/store":"2.0.0-main-16d8c43e","@latticexyz/utils":"2.0.0-main-16d8c43e","@latticexyz/world":"2.0.0-main-16d8c43e"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-16d8c43e","_integrity":"sha512-AW/arX0Mpo9V8oCdIbCzBNcw4bXghUInn+kM6D0gom7CC5TiAQI3O/sDUAewH4EY3JGRxqskuho6AmFBr7r8Gg==","_resolved":"/tmp/dc6ab30651942053ded27294b8acb91b/latticexyz-network-2.0.0-main-16d8c43e.tgz","_from":"file:latticexyz-network-2.0.0-main-16d8c43e.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-AW/arX0Mpo9V8oCdIbCzBNcw4bXghUInn+kM6D0gom7CC5TiAQI3O/sDUAewH4EY3JGRxqskuho6AmFBr7r8Gg==","shasum":"12659e06edfa4d5fbcac1a83563f0ce27c12fc89","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-16d8c43e.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBmgDaZ3KUYb+Q5EClrXAxjgOXQCltVC5Ejr92ImM7SzAiBpyzLgEaOt4qxPntpGVHwVW/Wv61ZNRu489apCcY+N/g=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-16d8c43e_1690790515406_0.8433986725248048"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-b24502cb":{"name":"@latticexyz/network","version":"2.0.0-main-b24502cb","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-b24502cb","@latticexyz/recs":"2.0.0-main-b24502cb","@latticexyz/schema-type":"2.0.0-main-b24502cb","@latticexyz/services":"2.0.0-main-b24502cb","@latticexyz/solecs":"2.0.0-main-b24502cb","@latticexyz/store":"2.0.0-main-b24502cb","@latticexyz/utils":"2.0.0-main-b24502cb","@latticexyz/world":"2.0.0-main-b24502cb"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-b24502cb","_integrity":"sha512-bzdH3pqoB/6newrogWemki6hqG0iGziWkyyj5/s3iFz1fjH2gl0o4NW7B2goXtPzd2klF0i/j9sP2FstBgS9IA==","_resolved":"/tmp/e7bcee30746e5095982b0036264a1edc/latticexyz-network-2.0.0-main-b24502cb.tgz","_from":"file:latticexyz-network-2.0.0-main-b24502cb.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-bzdH3pqoB/6newrogWemki6hqG0iGziWkyyj5/s3iFz1fjH2gl0o4NW7B2goXtPzd2klF0i/j9sP2FstBgS9IA==","shasum":"c75d2ccd4891b5ea2ce5ca99a91b9a9f14839ad1","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-b24502cb.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD4lc+wEacrJzMlWNYQ47AMJtqfh+pAVWWZ4pFcrKZ/sgIhAMi393uX3o2vGFq4ySoJXBgrbI3n3Bcrtnk6U42sD7d1"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-b24502cb_1690802131768_0.5760797053389468"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-9e5baf4f":{"name":"@latticexyz/network","version":"2.0.0-main-9e5baf4f","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-9e5baf4f","@latticexyz/recs":"2.0.0-main-9e5baf4f","@latticexyz/schema-type":"2.0.0-main-9e5baf4f","@latticexyz/services":"2.0.0-main-9e5baf4f","@latticexyz/solecs":"2.0.0-main-9e5baf4f","@latticexyz/store":"2.0.0-main-9e5baf4f","@latticexyz/utils":"2.0.0-main-9e5baf4f","@latticexyz/world":"2.0.0-main-9e5baf4f"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-9e5baf4f","_integrity":"sha512-dldB2Xuz6+PeE6h20vkKq5K0jHD7FuxTj8IQCj5a83vUEhTrjE+amQTdU38DzBZWUYbrei+AZBbz44XLFPfiFA==","_resolved":"/tmp/528f64b639fac1bf32612d9ff7798105/latticexyz-network-2.0.0-main-9e5baf4f.tgz","_from":"file:latticexyz-network-2.0.0-main-9e5baf4f.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-dldB2Xuz6+PeE6h20vkKq5K0jHD7FuxTj8IQCj5a83vUEhTrjE+amQTdU38DzBZWUYbrei+AZBbz44XLFPfiFA==","shasum":"925e04cd51db7d59f2263ffb51d1e8862bc8f484","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-9e5baf4f.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDyVhw0Gk0FefwWzUL9ZTHnatemV/d34Lfr/J2L7BZGbwIhAPLOcYCWdQPzETgnau4hacE/ihLhE42iWslSVtOiEC0H"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-9e5baf4f_1690805608573_0.3065245990996954"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-2f6cfef9":{"name":"@latticexyz/network","version":"2.0.0-main-2f6cfef9","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-2f6cfef9","@latticexyz/recs":"2.0.0-main-2f6cfef9","@latticexyz/schema-type":"2.0.0-main-2f6cfef9","@latticexyz/services":"2.0.0-main-2f6cfef9","@latticexyz/solecs":"2.0.0-main-2f6cfef9","@latticexyz/store":"2.0.0-main-2f6cfef9","@latticexyz/utils":"2.0.0-main-2f6cfef9","@latticexyz/world":"2.0.0-main-2f6cfef9"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-2f6cfef9","_integrity":"sha512-HbbQXjnb9RveVIpit1Ea/0vhHmpA/gYMIXxUs3CfftCY0Eb13EYn7zHqGlD6JNg82HMa4XgMPrf0d7q8DcFSiQ==","_resolved":"/tmp/f35f1eeee163ac234a438231dab2bb13/latticexyz-network-2.0.0-main-2f6cfef9.tgz","_from":"file:latticexyz-network-2.0.0-main-2f6cfef9.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-HbbQXjnb9RveVIpit1Ea/0vhHmpA/gYMIXxUs3CfftCY0Eb13EYn7zHqGlD6JNg82HMa4XgMPrf0d7q8DcFSiQ==","shasum":"77ac2e8c2dede9cfe82423cc2cc08a09773d8a88","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-2f6cfef9.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA4Z5C/V8N1lHSczPtEEpaYNIucbL8B6bBpn5kY+FiUiAiB6yZmKGACu8Ph72YIPm2mQnCL07aJbgPc8QAKMTORO7A=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-2f6cfef9_1690825421328_0.5199663029683737"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-d89431db":{"name":"@latticexyz/network","version":"2.0.0-main-d89431db","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-d89431db","@latticexyz/recs":"2.0.0-main-d89431db","@latticexyz/schema-type":"2.0.0-main-d89431db","@latticexyz/services":"2.0.0-main-d89431db","@latticexyz/solecs":"2.0.0-main-d89431db","@latticexyz/store":"2.0.0-main-d89431db","@latticexyz/utils":"2.0.0-main-d89431db","@latticexyz/world":"2.0.0-main-d89431db"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-d89431db","_integrity":"sha512-E16RgPbhPUen4vm14uxgRwhp/PZDLUE1miCtR41fj0GAtcTuRSCtr7DU3GWML/dTRUFCP6tdJMI/EDEgzy7aKg==","_resolved":"/tmp/d8a9b6789e7453f631f48779efdf8b71/latticexyz-network-2.0.0-main-d89431db.tgz","_from":"file:latticexyz-network-2.0.0-main-d89431db.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-E16RgPbhPUen4vm14uxgRwhp/PZDLUE1miCtR41fj0GAtcTuRSCtr7DU3GWML/dTRUFCP6tdJMI/EDEgzy7aKg==","shasum":"451085afc331a69b8d3393f1559faad4afc09a38","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-d89431db.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDfbd5WOHC6+a897Xlj1GqHYAnfqDwCSABs8EBCjOIz1AIhAIUDdnznKfOPYSL/IVa78vKixgh71pCUQ49NkUDc6vQE"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-d89431db_1690905974376_0.4646796948803067"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-7fb0dadf":{"name":"@latticexyz/network","version":"2.0.0-main-7fb0dadf","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-7fb0dadf","@latticexyz/recs":"2.0.0-main-7fb0dadf","@latticexyz/schema-type":"2.0.0-main-7fb0dadf","@latticexyz/services":"2.0.0-main-7fb0dadf","@latticexyz/solecs":"2.0.0-main-7fb0dadf","@latticexyz/store":"2.0.0-main-7fb0dadf","@latticexyz/utils":"2.0.0-main-7fb0dadf","@latticexyz/world":"2.0.0-main-7fb0dadf"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-7fb0dadf","_integrity":"sha512-dHNksC6ziqP2qKV0uqxCQxp4i7rQvkdsJ9B5vLi2Y2jO8Um7RCoj+WlckVCO1JJNVR1Yl146AI8+Z4HdEDFDow==","_resolved":"/tmp/a1198a2b4075f8b8c18aab8502a72d66/latticexyz-network-2.0.0-main-7fb0dadf.tgz","_from":"file:latticexyz-network-2.0.0-main-7fb0dadf.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-dHNksC6ziqP2qKV0uqxCQxp4i7rQvkdsJ9B5vLi2Y2jO8Um7RCoj+WlckVCO1JJNVR1Yl146AI8+Z4HdEDFDow==","shasum":"242b1577ef3e62f4b9583e5176f01c95a34d3161","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-7fb0dadf.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC3Gc0a7FxObbwUb5FsVilRYVYi2AlCdflAyHa6VFFPHAIgC3uq2304xftqK01+p7LCsBBLR2NOzIQNN9qQ7J8l2jM="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-7fb0dadf_1690914538318_0.5257783247528054"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-57a52608":{"name":"@latticexyz/network","version":"2.0.0-main-57a52608","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-57a52608","@latticexyz/recs":"2.0.0-main-57a52608","@latticexyz/schema-type":"2.0.0-main-57a52608","@latticexyz/services":"2.0.0-main-57a52608","@latticexyz/solecs":"2.0.0-main-57a52608","@latticexyz/store":"2.0.0-main-57a52608","@latticexyz/utils":"2.0.0-main-57a52608","@latticexyz/world":"2.0.0-main-57a52608"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-57a52608","_integrity":"sha512-EhMAHYe2CVmYtlLckQ1pX0K3a9x2SdWBCFdeln76+tCecLjCqzwnAzUqZQ0MO3TQy907izlnC+GFmw1iSAXz0Q==","_resolved":"/tmp/4cdff5b75cdc55f8c19ca08573ca32c4/latticexyz-network-2.0.0-main-57a52608.tgz","_from":"file:latticexyz-network-2.0.0-main-57a52608.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-EhMAHYe2CVmYtlLckQ1pX0K3a9x2SdWBCFdeln76+tCecLjCqzwnAzUqZQ0MO3TQy907izlnC+GFmw1iSAXz0Q==","shasum":"ac0b1f838fcd69f850b25e2bc73eb0b81138ae2b","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-57a52608.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCQtRbGnA0nka6JRH3qyocM5hZvGwuha1IJ8iozuMlj7QIhAP2MprBWUtAOjY252mYj1lCAptWiLn6l6buHiu3a7oqy"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-57a52608_1691078294236_0.8718728428865443"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-131c63e5":{"name":"@latticexyz/network","version":"2.0.0-main-131c63e5","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-131c63e5","@latticexyz/recs":"2.0.0-main-131c63e5","@latticexyz/schema-type":"2.0.0-main-131c63e5","@latticexyz/services":"2.0.0-main-131c63e5","@latticexyz/solecs":"2.0.0-main-131c63e5","@latticexyz/store":"2.0.0-main-131c63e5","@latticexyz/utils":"2.0.0-main-131c63e5","@latticexyz/world":"2.0.0-main-131c63e5"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-131c63e5","_integrity":"sha512-n29ldha6YHY4KzveOw10FyKFQnH++IOI9ZEogNe6tKW1LuY26uHJ6cuVVbzC3sF53rhWnbOMcFl0VEWXNC4m6A==","_resolved":"/tmp/d98bde5eb53c6add4b7b79e61bea2f08/latticexyz-network-2.0.0-main-131c63e5.tgz","_from":"file:latticexyz-network-2.0.0-main-131c63e5.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-n29ldha6YHY4KzveOw10FyKFQnH++IOI9ZEogNe6tKW1LuY26uHJ6cuVVbzC3sF53rhWnbOMcFl0VEWXNC4m6A==","shasum":"302f170318232299db322f303ae2aa9453008101","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-131c63e5.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDcFVG2Ddr6WtUSG0Y42F9phghMcbQmxq8UMgu5adUsRgIhAK1f1sQ6/U7u8MmkpQfI4Vj9DHpHDvlRlBmuW/YnA5mc"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-131c63e5_1691082251130_0.42643224592440965"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-c1d2249b":{"name":"@latticexyz/network","version":"2.0.0-main-c1d2249b","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-c1d2249b","@latticexyz/recs":"2.0.0-main-c1d2249b","@latticexyz/schema-type":"2.0.0-main-c1d2249b","@latticexyz/services":"2.0.0-main-c1d2249b","@latticexyz/solecs":"2.0.0-main-c1d2249b","@latticexyz/store":"2.0.0-main-c1d2249b","@latticexyz/utils":"2.0.0-main-c1d2249b","@latticexyz/world":"2.0.0-main-c1d2249b"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-c1d2249b","_integrity":"sha512-J5VJY4r/44JT1QatvcrZ1bxQ8kDrRUgydtdKzArj/r17Z3eeZKSSDXjSHhYb1Vm3AtqIxklWmO+r/6IYdm1IyQ==","_resolved":"/tmp/755e835c942be882cdc8fac65a7053d6/latticexyz-network-2.0.0-main-c1d2249b.tgz","_from":"file:latticexyz-network-2.0.0-main-c1d2249b.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-J5VJY4r/44JT1QatvcrZ1bxQ8kDrRUgydtdKzArj/r17Z3eeZKSSDXjSHhYb1Vm3AtqIxklWmO+r/6IYdm1IyQ==","shasum":"76aa1094e4b8e3dca39987691496ed08d49a9b43","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-c1d2249b.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGPIHyadEU/ZaaFXeHWTFLh16ADMrIYh9pZQGuwR1uUeAiEAkEpWSdTv/tK9qpkzMiu+wdDinVbJZ6q6fzUSmo43XdY="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-c1d2249b_1691082971408_0.4246547986946405"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-582388ba":{"name":"@latticexyz/network","version":"2.0.0-main-582388ba","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-582388ba","@latticexyz/recs":"2.0.0-main-582388ba","@latticexyz/schema-type":"2.0.0-main-582388ba","@latticexyz/services":"2.0.0-main-582388ba","@latticexyz/solecs":"2.0.0-main-582388ba","@latticexyz/store":"2.0.0-main-582388ba","@latticexyz/utils":"2.0.0-main-582388ba","@latticexyz/world":"2.0.0-main-582388ba"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-582388ba","_integrity":"sha512-r8HshD+ZRZYg8HBNg9uSgVVeKf1Isap28o556Rk1KELXazh0ptSKOLPQywcVYPtiNPcO7UlmtzC5t20T7KvPgA==","_resolved":"/tmp/ae9a2e3e354a6b2afa5d1211dd5c7057/latticexyz-network-2.0.0-main-582388ba.tgz","_from":"file:latticexyz-network-2.0.0-main-582388ba.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-r8HshD+ZRZYg8HBNg9uSgVVeKf1Isap28o556Rk1KELXazh0ptSKOLPQywcVYPtiNPcO7UlmtzC5t20T7KvPgA==","shasum":"8a3e6965d8fcb3b938a74e161502f53a8b39758b","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-582388ba.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC+qNExmB3/EtBdJTKthCcmljzlIHrzsfAdPeqy7B+lIAIgNcQ6GK9AnE/Bafe285x5spnqvnD1xULzWr2jqFK4bhA="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-582388ba_1691083859706_0.15408732374766143"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-8fcd82ed":{"name":"@latticexyz/network","version":"2.0.0-main-8fcd82ed","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-8fcd82ed","@latticexyz/recs":"2.0.0-main-8fcd82ed","@latticexyz/schema-type":"2.0.0-main-8fcd82ed","@latticexyz/services":"2.0.0-main-8fcd82ed","@latticexyz/solecs":"2.0.0-main-8fcd82ed","@latticexyz/store":"2.0.0-main-8fcd82ed","@latticexyz/utils":"2.0.0-main-8fcd82ed","@latticexyz/world":"2.0.0-main-8fcd82ed"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-8fcd82ed","_integrity":"sha512-iaoxchP4EOIuHBLQC0zoQtVpFNdr3naykIqkFH2gEDyLEzC48jql+mDAkPxsJA88ZQwRym9xkcVFnuZOLp0KtQ==","_resolved":"/tmp/234cfe4928d84e002b9dc5532b5a3b6a/latticexyz-network-2.0.0-main-8fcd82ed.tgz","_from":"file:latticexyz-network-2.0.0-main-8fcd82ed.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-iaoxchP4EOIuHBLQC0zoQtVpFNdr3naykIqkFH2gEDyLEzC48jql+mDAkPxsJA88ZQwRym9xkcVFnuZOLp0KtQ==","shasum":"c274028a30ef22a4882802f81250ac59437aa736","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-8fcd82ed.tgz","fileCount":80,"unpackedSize":496467,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCrJXBntMYOmSm0z0iveZXvqoWHWR2kBrkiZCYlCHWapwIgRQ2wv7peO9q/YYCp8G9fCewP9GnbwQr/fUmBE87PMZk="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-8fcd82ed_1691084940850_0.8798673478952055"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-5c965a91":{"name":"@latticexyz/network","version":"2.0.0-main-5c965a91","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-5c965a91","@latticexyz/recs":"2.0.0-main-5c965a91","@latticexyz/schema-type":"2.0.0-main-5c965a91","@latticexyz/services":"2.0.0-main-5c965a91","@latticexyz/solecs":"2.0.0-main-5c965a91","@latticexyz/store":"2.0.0-main-5c965a91","@latticexyz/utils":"2.0.0-main-5c965a91","@latticexyz/world":"2.0.0-main-5c965a91"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-5c965a91","_integrity":"sha512-HUuHoZtZelmdOIzqe2ipFSMMPZ+DW/y9ECy1T/P6XZBgu9wzJmnIEnD1n8IiGFN3Y/UbrljYuH+I9CZEvHI7vA==","_resolved":"/tmp/d55bb39ffcfa8d3b8e0dcc43de14bea0/latticexyz-network-2.0.0-main-5c965a91.tgz","_from":"file:latticexyz-network-2.0.0-main-5c965a91.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-HUuHoZtZelmdOIzqe2ipFSMMPZ+DW/y9ECy1T/P6XZBgu9wzJmnIEnD1n8IiGFN3Y/UbrljYuH+I9CZEvHI7vA==","shasum":"13d0a689de1057aeef05d68a2a7ca01255698f2c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-5c965a91.tgz","fileCount":80,"unpackedSize":496564,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEn7ErjwVX70vyDSocGXNUXImrIvknCxkBIuJijXx3S/AiEAnJTb5OKzjJgZxitToEen77NFUqZeS7jhBh+wvNbuEY0="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-5c965a91_1691086554600_0.9440638936613679"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-a0df37b1":{"name":"@latticexyz/network","version":"2.0.0-main-a0df37b1","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-a0df37b1","@latticexyz/recs":"2.0.0-main-a0df37b1","@latticexyz/schema-type":"2.0.0-main-a0df37b1","@latticexyz/services":"2.0.0-main-a0df37b1","@latticexyz/solecs":"2.0.0-main-a0df37b1","@latticexyz/store":"2.0.0-main-a0df37b1","@latticexyz/utils":"2.0.0-main-a0df37b1","@latticexyz/world":"2.0.0-main-a0df37b1"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-a0df37b1","_integrity":"sha512-gQJML/hL4gx39ROX7gR3NT17R8RahPppWW/Ppj3IIme/6CP3uMmONm6qz1onxlrjhwEI0jHNbOHMDbJsHoqVyQ==","_resolved":"/tmp/7a7bb2732d58fb7a478e3263b758b194/latticexyz-network-2.0.0-main-a0df37b1.tgz","_from":"file:latticexyz-network-2.0.0-main-a0df37b1.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-gQJML/hL4gx39ROX7gR3NT17R8RahPppWW/Ppj3IIme/6CP3uMmONm6qz1onxlrjhwEI0jHNbOHMDbJsHoqVyQ==","shasum":"6a21ba807d5ff080972daff602e73a0e99342c00","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-a0df37b1.tgz","fileCount":80,"unpackedSize":496564,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCVVTP6T6JpS9PkAPfWuEIIep1IFZ4U2WLm+Lefp5t/rwIgDoXWMs23I8reCTnd4xJ5ct0P4lxC4yGENGeM8rSQQ2w="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-a0df37b1_1691092406874_0.7599272485497255"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-6cc49119":{"name":"@latticexyz/network","version":"2.0.0-main-6cc49119","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-6cc49119","@latticexyz/recs":"2.0.0-main-6cc49119","@latticexyz/schema-type":"2.0.0-main-6cc49119","@latticexyz/services":"2.0.0-main-6cc49119","@latticexyz/solecs":"2.0.0-main-6cc49119","@latticexyz/store":"2.0.0-main-6cc49119","@latticexyz/utils":"2.0.0-main-6cc49119","@latticexyz/world":"2.0.0-main-6cc49119"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-6cc49119","_integrity":"sha512-UnjUQU6ac/zR02yAaJVd57pezR6r/6ZKC/UQGWZMpvxUcdVlN5/eZOG74AGgSMzof6wTHRje0NU2jNjhIe237w==","_resolved":"/tmp/47353c133d0171ad61ca314826eaa111/latticexyz-network-2.0.0-main-6cc49119.tgz","_from":"file:latticexyz-network-2.0.0-main-6cc49119.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-UnjUQU6ac/zR02yAaJVd57pezR6r/6ZKC/UQGWZMpvxUcdVlN5/eZOG74AGgSMzof6wTHRje0NU2jNjhIe237w==","shasum":"19e574eb6fd735e034d3b937d4fed505a4925e4d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-6cc49119.tgz","fileCount":80,"unpackedSize":496613,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGPD4leX/imK4NGbZg8j4fpYdjc6CbAfg68XTNMTZ2XnAiEA6J3fyqvKD6xxrZiVCZUHSBiEatWSMI+JhboLEJ9iGuw="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-6cc49119_1691094314209_0.9981088837391447"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-f741ae8c":{"name":"@latticexyz/network","version":"2.0.0-main-f741ae8c","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-f741ae8c","@latticexyz/recs":"2.0.0-main-f741ae8c","@latticexyz/schema-type":"2.0.0-main-f741ae8c","@latticexyz/services":"2.0.0-main-f741ae8c","@latticexyz/solecs":"2.0.0-main-f741ae8c","@latticexyz/store":"2.0.0-main-f741ae8c","@latticexyz/utils":"2.0.0-main-f741ae8c","@latticexyz/world":"2.0.0-main-f741ae8c"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-f741ae8c","_integrity":"sha512-0qmvtPQL5aQsvByrGuPL9bXO8Pi+ilOhZ/dLWzaehw3Z/gY/W2nmO8f/JHEUpwqyJnRTFtlf5UjpWWXAwkNIvQ==","_resolved":"/tmp/0413db2495c6d0d503e88e3a208f54b6/latticexyz-network-2.0.0-main-f741ae8c.tgz","_from":"file:latticexyz-network-2.0.0-main-f741ae8c.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-0qmvtPQL5aQsvByrGuPL9bXO8Pi+ilOhZ/dLWzaehw3Z/gY/W2nmO8f/JHEUpwqyJnRTFtlf5UjpWWXAwkNIvQ==","shasum":"1ceaa5da91b3e7b64d140eff1feb92cb9341d2ee","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-f741ae8c.tgz","fileCount":80,"unpackedSize":496613,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIANUK8cOmRXcleXoNKzArYfd2mq8EodJwhG/ar9RATWdAiEAoOC5uzup/z6FvlwSQaDCXE0GOWbvkTrRQ6kKKLKe2Ek="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-f741ae8c_1691147622399_0.943798167097986"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-081f57b3":{"name":"@latticexyz/network","version":"2.0.0-main-081f57b3","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-081f57b3","@latticexyz/recs":"2.0.0-main-081f57b3","@latticexyz/schema-type":"2.0.0-main-081f57b3","@latticexyz/services":"2.0.0-main-081f57b3","@latticexyz/solecs":"2.0.0-main-081f57b3","@latticexyz/store":"2.0.0-main-081f57b3","@latticexyz/utils":"2.0.0-main-081f57b3","@latticexyz/world":"2.0.0-main-081f57b3"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-081f57b3","_integrity":"sha512-J5DCkHuSyb5cyS+iHhxaFBhCwyfF9jdbVGbHV2gb0zltLcYp1HflUwHntnDnj9iW1Y5Zr5YSgDfly5mryUaDYg==","_resolved":"/tmp/b6ed86acea441dd0f02b2f408c18fa2a/latticexyz-network-2.0.0-main-081f57b3.tgz","_from":"file:latticexyz-network-2.0.0-main-081f57b3.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-J5DCkHuSyb5cyS+iHhxaFBhCwyfF9jdbVGbHV2gb0zltLcYp1HflUwHntnDnj9iW1Y5Zr5YSgDfly5mryUaDYg==","shasum":"13f3ffacb9e8706ed6e1d47a2fd44b8ff390b5ca","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-081f57b3.tgz","fileCount":80,"unpackedSize":496613,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCKwE+bpNV19vlfHmNK/SaDkDe4wRB93KvTKPLHnvL8kQIgMXoWHVUOBWrNNXMgyoZG8CiKQQ90hEJ8+CZIN+7sIpw="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-081f57b3_1691148239214_0.5379479507017391"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-3fb9ce28":{"name":"@latticexyz/network","version":"2.0.0-main-3fb9ce28","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-3fb9ce28","@latticexyz/recs":"2.0.0-main-3fb9ce28","@latticexyz/schema-type":"2.0.0-main-3fb9ce28","@latticexyz/services":"2.0.0-main-3fb9ce28","@latticexyz/solecs":"2.0.0-main-3fb9ce28","@latticexyz/store":"2.0.0-main-3fb9ce28","@latticexyz/utils":"2.0.0-main-3fb9ce28","@latticexyz/world":"2.0.0-main-3fb9ce28"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-3fb9ce28","_integrity":"sha512-nVGrlDwewA072No0A4yEIB1Lla0VAE8sTMkM0x68bz7SI90OUuYHE4UExFz6qtlXKH7Gqr0ZTmOhRxklHmR1qg==","_resolved":"/tmp/1aef481e225b50ee7e1cc7a29039eac7/latticexyz-network-2.0.0-main-3fb9ce28.tgz","_from":"file:latticexyz-network-2.0.0-main-3fb9ce28.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-nVGrlDwewA072No0A4yEIB1Lla0VAE8sTMkM0x68bz7SI90OUuYHE4UExFz6qtlXKH7Gqr0ZTmOhRxklHmR1qg==","shasum":"db3e9126d52454c12fe95177d6a8c05e0b2b94c5","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-3fb9ce28.tgz","fileCount":80,"unpackedSize":496710,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDyQs6y0+SvxpqZHKF5Y6LEdJrsh8WKZ2mRKj7BKEe8PwIgWQgJasyzvgr/WQlhk7I7ry3kVIWW6u0wSA+6iYUuc4s="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-3fb9ce28_1691161078138_0.01976171976546448"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-b6c8f3db":{"name":"@latticexyz/network","version":"2.0.0-main-b6c8f3db","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-b6c8f3db","@latticexyz/recs":"2.0.0-main-b6c8f3db","@latticexyz/schema-type":"2.0.0-main-b6c8f3db","@latticexyz/services":"2.0.0-main-b6c8f3db","@latticexyz/solecs":"2.0.0-main-b6c8f3db","@latticexyz/store":"2.0.0-main-b6c8f3db","@latticexyz/utils":"2.0.0-main-b6c8f3db","@latticexyz/world":"2.0.0-main-b6c8f3db"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-b6c8f3db","_integrity":"sha512-KSGOdKNsGF1a8XlFPIXl+nue/84BWalePZ+4pCxvlV3Mia7xoNqJhF7TkExH+cb4CIWe9JPuIEbTgYDB39f0gA==","_resolved":"/tmp/54eb8cf278d11247ec5a6fb5d1a5c4c8/latticexyz-network-2.0.0-main-b6c8f3db.tgz","_from":"file:latticexyz-network-2.0.0-main-b6c8f3db.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-KSGOdKNsGF1a8XlFPIXl+nue/84BWalePZ+4pCxvlV3Mia7xoNqJhF7TkExH+cb4CIWe9JPuIEbTgYDB39f0gA==","shasum":"7cef3c033b9f5a4c41cf249fdd70c2e2adeb91db","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-b6c8f3db.tgz","fileCount":80,"unpackedSize":496710,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCmHqOcPlEQKm5/qGXjoNhZmtDe6bFWp4dVeyoHbDnjDQIhANWWgxEnzb1EOet7o1y2bkCYoJ86fukyJn7n0plee13t"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-b6c8f3db_1691170779289_0.0188349887416166"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-cc2c8da0":{"name":"@latticexyz/network","version":"2.0.0-main-cc2c8da0","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-cc2c8da0","@latticexyz/recs":"2.0.0-main-cc2c8da0","@latticexyz/schema-type":"2.0.0-main-cc2c8da0","@latticexyz/services":"2.0.0-main-cc2c8da0","@latticexyz/solecs":"2.0.0-main-cc2c8da0","@latticexyz/store":"2.0.0-main-cc2c8da0","@latticexyz/utils":"2.0.0-main-cc2c8da0","@latticexyz/world":"2.0.0-main-cc2c8da0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-cc2c8da0","_integrity":"sha512-dgXprA9Vo4TSZ0C5aKBB74HMXBJyw71fE8PbqifTUkV0zMYcYscWhcUAdU9IOq+Zxue8fIWklFFl/uGrcq4Vtw==","_resolved":"/tmp/07db6150a2a75c22187fd1d517c3969e/latticexyz-network-2.0.0-main-cc2c8da0.tgz","_from":"file:latticexyz-network-2.0.0-main-cc2c8da0.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-dgXprA9Vo4TSZ0C5aKBB74HMXBJyw71fE8PbqifTUkV0zMYcYscWhcUAdU9IOq+Zxue8fIWklFFl/uGrcq4Vtw==","shasum":"900dd58453e718ee94e00c464c713790a3335eb7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-cc2c8da0.tgz","fileCount":80,"unpackedSize":496807,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDIGj7x1ikxTxsGVsPfJagT2kLE+lr2eW2tvlpjQ3gr3AiEA8DbNuZVvEkW7PTZMbrgn2+HNnY20VDpxuOfcwIKanFE="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-cc2c8da0_1691304376203_0.6059620268526837"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-1af2f495":{"name":"@latticexyz/network","version":"2.0.0-main-1af2f495","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-1af2f495","@latticexyz/recs":"2.0.0-main-1af2f495","@latticexyz/schema-type":"2.0.0-main-1af2f495","@latticexyz/services":"2.0.0-main-1af2f495","@latticexyz/solecs":"2.0.0-main-1af2f495","@latticexyz/store":"2.0.0-main-1af2f495","@latticexyz/utils":"2.0.0-main-1af2f495","@latticexyz/world":"2.0.0-main-1af2f495"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-1af2f495","_integrity":"sha512-PvpLh4YBUykiRFTlLiiRDrt73cSVjaCKApSZ2sYsF24Foh9ftKHeesS3dT0ATCVyRg7LVhhmUJg74NAwQNEwaQ==","_resolved":"/tmp/9e31c28e28e94f025b10a1342df0879f/latticexyz-network-2.0.0-main-1af2f495.tgz","_from":"file:latticexyz-network-2.0.0-main-1af2f495.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-PvpLh4YBUykiRFTlLiiRDrt73cSVjaCKApSZ2sYsF24Foh9ftKHeesS3dT0ATCVyRg7LVhhmUJg74NAwQNEwaQ==","shasum":"f2cb81d26125a5c13551f0a2f0b33d113caf8dc4","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-1af2f495.tgz","fileCount":80,"unpackedSize":496807,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBESW+1LOx3T+tc+eqRTP2j5TzW7fX3vCoz/qb8zRi1sAiAl7Gdu/apr14hUIzcLMQ5N3YhV+rXl8bAidYkRNUzNsA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-1af2f495_1691353101059_0.42642689615004925"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-8318f172":{"name":"@latticexyz/network","version":"2.0.0-main-8318f172","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-8318f172","@latticexyz/recs":"2.0.0-main-8318f172","@latticexyz/schema-type":"2.0.0-main-8318f172","@latticexyz/services":"2.0.0-main-8318f172","@latticexyz/solecs":"2.0.0-main-8318f172","@latticexyz/store":"2.0.0-main-8318f172","@latticexyz/utils":"2.0.0-main-8318f172","@latticexyz/world":"2.0.0-main-8318f172"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-8318f172","_integrity":"sha512-XuMZwkvheP/4RYbGyRWO0vjmLHX0QWA5H4eenf3M6I5bRxDccsFC4fmvaReUmgt7trqsysSK5wfNEONQfPdRdA==","_resolved":"/tmp/6818d7d5064768aa5c56986c143197ff/latticexyz-network-2.0.0-main-8318f172.tgz","_from":"file:latticexyz-network-2.0.0-main-8318f172.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-XuMZwkvheP/4RYbGyRWO0vjmLHX0QWA5H4eenf3M6I5bRxDccsFC4fmvaReUmgt7trqsysSK5wfNEONQfPdRdA==","shasum":"5dd553b37f7e9121bc5dcb2a9bcc6e83c3378a3c","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-8318f172.tgz","fileCount":80,"unpackedSize":496807,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCKY7bQjDPiCx7vHsmmsOdJCLuEspe+IZPmE9D7Z/dJNwIhAPuhdzz0VAXhLKDTmGEcDnQl8knbM0Bq/FL7PaAE6c4c"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-8318f172_1691400303512_0.10183626646458643"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-cf4dab67":{"name":"@latticexyz/network","version":"2.0.0-main-cf4dab67","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-cf4dab67","@latticexyz/recs":"2.0.0-main-cf4dab67","@latticexyz/schema-type":"2.0.0-main-cf4dab67","@latticexyz/services":"2.0.0-main-cf4dab67","@latticexyz/solecs":"2.0.0-main-cf4dab67","@latticexyz/store":"2.0.0-main-cf4dab67","@latticexyz/utils":"2.0.0-main-cf4dab67","@latticexyz/world":"2.0.0-main-cf4dab67"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-cf4dab67","_integrity":"sha512-JhengpqIZOh22SsdifGhojzcKsVNxI0fltMaiOTwdohrjSzyV0b1N0Rtx7PhKfLQ+K1xpsAYS6s+ZdN2bXakrA==","_resolved":"/tmp/0bb582caf207c865e1da296efe74eca5/latticexyz-network-2.0.0-main-cf4dab67.tgz","_from":"file:latticexyz-network-2.0.0-main-cf4dab67.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-JhengpqIZOh22SsdifGhojzcKsVNxI0fltMaiOTwdohrjSzyV0b1N0Rtx7PhKfLQ+K1xpsAYS6s+ZdN2bXakrA==","shasum":"de8b1e8f0d6b3349d3282c0df8c1deaabe8a064e","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-cf4dab67.tgz","fileCount":80,"unpackedSize":496807,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBHOwfyQt5SE/jJXQU+raZp5cP3qx6S1/2RImEG8Fp6NAiEAoDyV1QwdsvBrV1qDSmv/5OcM6JQZlz6SRofTFMR77Ss="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-cf4dab67_1691414376220_0.9914071754508056"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-d62e76d2":{"name":"@latticexyz/network","version":"2.0.0-main-d62e76d2","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-d62e76d2","@latticexyz/recs":"2.0.0-main-d62e76d2","@latticexyz/schema-type":"2.0.0-main-d62e76d2","@latticexyz/services":"2.0.0-main-d62e76d2","@latticexyz/solecs":"2.0.0-main-d62e76d2","@latticexyz/store":"2.0.0-main-d62e76d2","@latticexyz/utils":"2.0.0-main-d62e76d2","@latticexyz/world":"2.0.0-main-d62e76d2"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-d62e76d2","_integrity":"sha512-lhQanV3KGtrmhlZT8lHGa3wp4hodnyz6J6+9vBroZydNKPRE/mVscMX0afYJx9DjiQVMKCi6Xtye3/ofzF3jfg==","_resolved":"/tmp/396c916aea164b3d561c4ade5636fa0f/latticexyz-network-2.0.0-main-d62e76d2.tgz","_from":"file:latticexyz-network-2.0.0-main-d62e76d2.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-lhQanV3KGtrmhlZT8lHGa3wp4hodnyz6J6+9vBroZydNKPRE/mVscMX0afYJx9DjiQVMKCi6Xtye3/ofzF3jfg==","shasum":"90269e6623dfc773dc3397f80c9bba2deb0c1d7e","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-d62e76d2.tgz","fileCount":80,"unpackedSize":496807,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA5JVIaa2z43VgPAE6ANS43E+K5BGPT9Au05msrVqDxbAiBoyNSBSIQbs8H6ppf/lbF8mKeSN7lR+pTbA/zsHkrhtw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-d62e76d2_1691425312984_0.35246117621363227"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-8bd2a6d3":{"name":"@latticexyz/network","version":"2.0.0-main-8bd2a6d3","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-8bd2a6d3","@latticexyz/recs":"2.0.0-main-8bd2a6d3","@latticexyz/schema-type":"2.0.0-main-8bd2a6d3","@latticexyz/services":"2.0.0-main-8bd2a6d3","@latticexyz/solecs":"2.0.0-main-8bd2a6d3","@latticexyz/store":"2.0.0-main-8bd2a6d3","@latticexyz/utils":"2.0.0-main-8bd2a6d3","@latticexyz/world":"2.0.0-main-8bd2a6d3"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-8bd2a6d3","_integrity":"sha512-RvhMiiGgGVXwkJiNt1UdzkgIfUm9+2QLYEGYcVJW4VMipFfly7F1tZXWK8kdADIWRDwilAu96JI1UizgdIQxDw==","_resolved":"/tmp/1e70868184cec17f75f54d93719eb978/latticexyz-network-2.0.0-main-8bd2a6d3.tgz","_from":"file:latticexyz-network-2.0.0-main-8bd2a6d3.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-RvhMiiGgGVXwkJiNt1UdzkgIfUm9+2QLYEGYcVJW4VMipFfly7F1tZXWK8kdADIWRDwilAu96JI1UizgdIQxDw==","shasum":"e5347c5c1d09a3f0035fdb5d9d7560cdd6a25a78","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-8bd2a6d3.tgz","fileCount":80,"unpackedSize":496807,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEvG++aGrkUtDHLdUMWTONac0HH9rmHISoR5fQzs7QMAAiEA2vmHbF4UHQNNSzeb2l8owLyLj5b92f/Va/gGspuJWLI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-8bd2a6d3_1691428065965_0.8081729664527852"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-0d8cdad9":{"name":"@latticexyz/network","version":"2.0.0-main-0d8cdad9","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-0d8cdad9","@latticexyz/recs":"2.0.0-main-0d8cdad9","@latticexyz/schema-type":"2.0.0-main-0d8cdad9","@latticexyz/services":"2.0.0-main-0d8cdad9","@latticexyz/solecs":"2.0.0-main-0d8cdad9","@latticexyz/store":"2.0.0-main-0d8cdad9","@latticexyz/utils":"2.0.0-main-0d8cdad9","@latticexyz/world":"2.0.0-main-0d8cdad9"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-0d8cdad9","_integrity":"sha512-9barQEjJ6aYVNN8yOjA9Mh8nKcsIc2S1I26V4dWg+NI4wqPTEfHXySL1d8VMx0ibSlP4A7X863RPEL30ofAdwQ==","_resolved":"/tmp/59c4551e69f97639ac52e18e09dff23c/latticexyz-network-2.0.0-main-0d8cdad9.tgz","_from":"file:latticexyz-network-2.0.0-main-0d8cdad9.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-9barQEjJ6aYVNN8yOjA9Mh8nKcsIc2S1I26V4dWg+NI4wqPTEfHXySL1d8VMx0ibSlP4A7X863RPEL30ofAdwQ==","shasum":"0fc3db1aa1af085cea4e6b9125157c0ef0ef901f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-0d8cdad9.tgz","fileCount":80,"unpackedSize":496807,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDkcWijsUL09iEU+iZ+Is504VB76FMkQju1/fxB7670EwIgZptu2H7GY3d8l6BrmutQwVqj9N/TydTIG2TkXGx+FPI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-0d8cdad9_1691517053134_0.45565031487598073"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-6c673325":{"name":"@latticexyz/network","version":"2.0.0-main-6c673325","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-6c673325","@latticexyz/recs":"2.0.0-main-6c673325","@latticexyz/schema-type":"2.0.0-main-6c673325","@latticexyz/services":"2.0.0-main-6c673325","@latticexyz/solecs":"2.0.0-main-6c673325","@latticexyz/store":"2.0.0-main-6c673325","@latticexyz/utils":"2.0.0-main-6c673325","@latticexyz/world":"2.0.0-main-6c673325"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-6c673325","_integrity":"sha512-/fmrtPK+gBWJMiMPGB0cTtKig4TRyICr9qeWZjLs+B+gZ4CD2XA29e9UCdzEzkujbgcQyIcHLNtfEC6mRdSXNg==","_resolved":"/tmp/5724e4e0d3a176d3f0097f07845c007f/latticexyz-network-2.0.0-main-6c673325.tgz","_from":"file:latticexyz-network-2.0.0-main-6c673325.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-/fmrtPK+gBWJMiMPGB0cTtKig4TRyICr9qeWZjLs+B+gZ4CD2XA29e9UCdzEzkujbgcQyIcHLNtfEC6mRdSXNg==","shasum":"88b03ffcd9d3022b2ad66c664e77483abfb61be7","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-6c673325.tgz","fileCount":80,"unpackedSize":497406,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCnG4zBaULFeeRdrl4K1VBNx5Q8iyqH5sYRk7mYEZSd9wIhAM72395b7n/+3sQy2cqy0bl4lWLY0OLn4UQ8pJvxiPOH"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-6c673325_1691581931479_0.26289828692408457"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-a434d1af":{"name":"@latticexyz/network","version":"2.0.0-main-a434d1af","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-a434d1af","@latticexyz/recs":"2.0.0-main-a434d1af","@latticexyz/schema-type":"2.0.0-main-a434d1af","@latticexyz/services":"2.0.0-main-a434d1af","@latticexyz/solecs":"2.0.0-main-a434d1af","@latticexyz/store":"2.0.0-main-a434d1af","@latticexyz/utils":"2.0.0-main-a434d1af","@latticexyz/world":"2.0.0-main-a434d1af"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-a434d1af","_integrity":"sha512-d3J3EDImkg9HmS1/gXK9TPRe1LjJrbMAkNTP42SFHOt7ybpb2QMWQf6D3AH1rOxtuqDcj/C6gfBMMDeHE5ORLg==","_resolved":"/tmp/b71772bd3003d83a2a798ea7c013337d/latticexyz-network-2.0.0-main-a434d1af.tgz","_from":"file:latticexyz-network-2.0.0-main-a434d1af.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-d3J3EDImkg9HmS1/gXK9TPRe1LjJrbMAkNTP42SFHOt7ybpb2QMWQf6D3AH1rOxtuqDcj/C6gfBMMDeHE5ORLg==","shasum":"c8612734121750b5fc5cc8c320e6d76bca1acafd","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-a434d1af.tgz","fileCount":80,"unpackedSize":497406,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCLx/zB3mEtC2vIKDq1+++h2sBT8RUeXfHhMWW8OF/aJgIhAL9u48loMMvyoo4JmzYVYRvqNfXNKuHxgYZg2YZTiFZG"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-a434d1af_1691582605883_0.01882416102386464"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-512831bf":{"name":"@latticexyz/network","version":"2.0.0-main-512831bf","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-512831bf","@latticexyz/recs":"2.0.0-main-512831bf","@latticexyz/schema-type":"2.0.0-main-512831bf","@latticexyz/services":"2.0.0-main-512831bf","@latticexyz/solecs":"2.0.0-main-512831bf","@latticexyz/store":"2.0.0-main-512831bf","@latticexyz/utils":"2.0.0-main-512831bf","@latticexyz/world":"2.0.0-main-512831bf"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-512831bf","_integrity":"sha512-OrMZ0stZ7eGNSUil4NlOyO5xNj9whTF/96QTG0Cg4jD35YFX3eobf8P+PwWlSqsuQ3PXznLJQ/WDqc7TXruv2g==","_resolved":"/tmp/2a07d60bf3f23c77eb8687884d5d7080/latticexyz-network-2.0.0-main-512831bf.tgz","_from":"file:latticexyz-network-2.0.0-main-512831bf.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-OrMZ0stZ7eGNSUil4NlOyO5xNj9whTF/96QTG0Cg4jD35YFX3eobf8P+PwWlSqsuQ3PXznLJQ/WDqc7TXruv2g==","shasum":"1b33466b1f0f3e26d83345f78577c39cf7f8d22a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-512831bf.tgz","fileCount":80,"unpackedSize":497406,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDAXnXspRCiszNMjPJs+cJMcPHC8DcHBeoc9XyKNAANSgIgGtrlKxY3FEVh2GOX2HwCl7299Py7L8G163VwCrp7y7I="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-512831bf_1691582855078_0.7687205965673698"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-09464e9f":{"name":"@latticexyz/network","version":"2.0.0-main-09464e9f","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-09464e9f","@latticexyz/recs":"2.0.0-main-09464e9f","@latticexyz/schema-type":"2.0.0-main-09464e9f","@latticexyz/services":"2.0.0-main-09464e9f","@latticexyz/solecs":"2.0.0-main-09464e9f","@latticexyz/store":"2.0.0-main-09464e9f","@latticexyz/utils":"2.0.0-main-09464e9f","@latticexyz/world":"2.0.0-main-09464e9f"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-09464e9f","_integrity":"sha512-6M2PnvY2b70m/NGwsxoTkeiA6C4WbeVSVEBbmQ032jFSawNbAMPPyrl9EyVHzamFgxRnO2mb33mza8neSYiciQ==","_resolved":"/tmp/54341658e2038ff23efa9bc5d01d5078/latticexyz-network-2.0.0-main-09464e9f.tgz","_from":"file:latticexyz-network-2.0.0-main-09464e9f.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-6M2PnvY2b70m/NGwsxoTkeiA6C4WbeVSVEBbmQ032jFSawNbAMPPyrl9EyVHzamFgxRnO2mb33mza8neSYiciQ==","shasum":"60f191eadfdba41a731129dbefb83b1169ab047f","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-09464e9f.tgz","fileCount":80,"unpackedSize":497406,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEO6dwtPvBYcfB7J8h1JytV8qpLmT4Fq0dQYJvZnbdK8AiEA3BQK23yVni/IQwBBl0CNWJmIHaMeEwJQc/i4aCo1jys="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-09464e9f_1691584604520_0.4729804814127063"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-cd5abcc3":{"name":"@latticexyz/network","version":"2.0.0-main-cd5abcc3","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-cd5abcc3","@latticexyz/recs":"2.0.0-main-cd5abcc3","@latticexyz/schema-type":"2.0.0-main-cd5abcc3","@latticexyz/services":"2.0.0-main-cd5abcc3","@latticexyz/solecs":"2.0.0-main-cd5abcc3","@latticexyz/store":"2.0.0-main-cd5abcc3","@latticexyz/utils":"2.0.0-main-cd5abcc3","@latticexyz/world":"2.0.0-main-cd5abcc3"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-cd5abcc3","_integrity":"sha512-CZr05w6/w1QEo/7XWCrjgXEIFoJwd3uJQZ8qqWqlOiwHUTKRgsW5GQXkClrAX8pd4gncT5WmoswfAAUYe8XFgA==","_resolved":"/tmp/b4f75862565256c2f889f4725d6307e3/latticexyz-network-2.0.0-main-cd5abcc3.tgz","_from":"file:latticexyz-network-2.0.0-main-cd5abcc3.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-CZr05w6/w1QEo/7XWCrjgXEIFoJwd3uJQZ8qqWqlOiwHUTKRgsW5GQXkClrAX8pd4gncT5WmoswfAAUYe8XFgA==","shasum":"4d93c1cd6c0afa2a51f2bff357d7362dd99cd99a","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-cd5abcc3.tgz","fileCount":80,"unpackedSize":497503,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFcbut69Sm0R434FqNwmxCCfYRuQDLT/ZeyVs0mslbeDAiEAla3QeUkn4JSUQ4apytRfL8UpBOSpuqV69HE37ptFk9A="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-cd5abcc3_1691586331057_0.5372838980706645"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-e826a6df":{"name":"@latticexyz/network","version":"2.0.0-main-e826a6df","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-e826a6df","@latticexyz/recs":"2.0.0-main-e826a6df","@latticexyz/schema-type":"2.0.0-main-e826a6df","@latticexyz/services":"2.0.0-main-e826a6df","@latticexyz/solecs":"2.0.0-main-e826a6df","@latticexyz/store":"2.0.0-main-e826a6df","@latticexyz/utils":"2.0.0-main-e826a6df","@latticexyz/world":"2.0.0-main-e826a6df"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-e826a6df","_integrity":"sha512-ftrHXwhg05j+d3GSyUW5NjqiPebjbIW6fz5Wew46gIOWPbsGQasaVL8gS3/2zZy8MmKezaUSmpGbXTe48MsZcA==","_resolved":"/tmp/e9b0ca8694a727606f8ce388a3d5f2a2/latticexyz-network-2.0.0-main-e826a6df.tgz","_from":"file:latticexyz-network-2.0.0-main-e826a6df.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-ftrHXwhg05j+d3GSyUW5NjqiPebjbIW6fz5Wew46gIOWPbsGQasaVL8gS3/2zZy8MmKezaUSmpGbXTe48MsZcA==","shasum":"63842eb113b88538db5973950ca9a4bd578cbe6b","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-e826a6df.tgz","fileCount":80,"unpackedSize":497503,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBPI4rtLu0K16V+p8cS0caAHSDWv77zukvWG68HyXcPmAiAJVIxm+Mlil8nD25mOaKkeBSzxX4vI6N2A+u3GCxUxiw=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-e826a6df_1691587932975_0.9193221000393579"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-98909586":{"name":"@latticexyz/network","version":"2.0.0-main-98909586","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-98909586","@latticexyz/recs":"2.0.0-main-98909586","@latticexyz/schema-type":"2.0.0-main-98909586","@latticexyz/services":"2.0.0-main-98909586","@latticexyz/solecs":"2.0.0-main-98909586","@latticexyz/store":"2.0.0-main-98909586","@latticexyz/utils":"2.0.0-main-98909586","@latticexyz/world":"2.0.0-main-98909586"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-98909586","_integrity":"sha512-waELCBTstgEmjc6ghOmvOG4TBfZvD3yIXIclAzAehnnYVg+kqdi4PBaXLK91pjaziV2gLNz4UkY5IztPrZ+XWQ==","_resolved":"/tmp/0768aadb1d2f3f612fb4e5c98d60b460/latticexyz-network-2.0.0-main-98909586.tgz","_from":"file:latticexyz-network-2.0.0-main-98909586.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-waELCBTstgEmjc6ghOmvOG4TBfZvD3yIXIclAzAehnnYVg+kqdi4PBaXLK91pjaziV2gLNz4UkY5IztPrZ+XWQ==","shasum":"b210bc86779753c2a480223d1ea18d481741b021","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-98909586.tgz","fileCount":80,"unpackedSize":497503,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICChMLVjZab0ZWF1m067NfNQqcTkRJo8SgcQ5G2zoV4zAiEA82Ih5/dHcKfhLuf1gySccsh21oGqyoOon15Pin6PVe4="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-98909586_1691589976718_0.2691725066301154"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-6071163f":{"name":"@latticexyz/network","version":"2.0.0-main-6071163f","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-6071163f","@latticexyz/recs":"2.0.0-main-6071163f","@latticexyz/schema-type":"2.0.0-main-6071163f","@latticexyz/services":"2.0.0-main-6071163f","@latticexyz/solecs":"2.0.0-main-6071163f","@latticexyz/store":"2.0.0-main-6071163f","@latticexyz/utils":"2.0.0-main-6071163f","@latticexyz/world":"2.0.0-main-6071163f"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-6071163f","_integrity":"sha512-jRd34mGEqJhdSun7+d+9HiUAJgi2Fq/gHCavVs/ckUg+9yPlCiTAG9gPLooU447vEjoRC99NLo6TqMWZnVTbGw==","_resolved":"/tmp/e0be3c36b8b0f4d34a2cf52ea6577b04/latticexyz-network-2.0.0-main-6071163f.tgz","_from":"file:latticexyz-network-2.0.0-main-6071163f.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-jRd34mGEqJhdSun7+d+9HiUAJgi2Fq/gHCavVs/ckUg+9yPlCiTAG9gPLooU447vEjoRC99NLo6TqMWZnVTbGw==","shasum":"25754ad76dfc96e483ef284aa108bc72e96dfd29","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-6071163f.tgz","fileCount":80,"unpackedSize":497600,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDiaXv6NavEGa3M0vFG6Oze6j2vqi3ojzUh+IHVvDiPlQIhAOxfnKfOn6vy6HYaOXwfeir0j/YNSDn8Hn+1tZRvIym4"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-6071163f_1691591375139_0.06861523465117592"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-233d3255":{"name":"@latticexyz/network","version":"2.0.0-main-233d3255","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-233d3255","@latticexyz/recs":"2.0.0-main-233d3255","@latticexyz/schema-type":"2.0.0-main-233d3255","@latticexyz/services":"2.0.0-main-233d3255","@latticexyz/solecs":"2.0.0-main-233d3255","@latticexyz/store":"2.0.0-main-233d3255","@latticexyz/utils":"2.0.0-main-233d3255","@latticexyz/world":"2.0.0-main-233d3255"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-233d3255","_integrity":"sha512-goSdoLgPk6++ULsj1wO8H68Q2+IkxNEKTxr5dYpZ61Nsu+Y7yubpCr1UZUCIBkevm+aoiQRUYDL3PIDUqAmEJg==","_resolved":"/tmp/c8636068ad3b6fe164148124bf3c7005/latticexyz-network-2.0.0-main-233d3255.tgz","_from":"file:latticexyz-network-2.0.0-main-233d3255.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-goSdoLgPk6++ULsj1wO8H68Q2+IkxNEKTxr5dYpZ61Nsu+Y7yubpCr1UZUCIBkevm+aoiQRUYDL3PIDUqAmEJg==","shasum":"85806b1a41f1b7083edae731db23fa89df7dde02","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-233d3255.tgz","fileCount":80,"unpackedSize":497653,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE/utkhxgAhWZ9U4Wron7mIpjNg8pnn6hSJrv6HB0GEqAiEAjZbCsh5x+Gs5NzJIQTjB6+Tn8u0jzelA5S8oz5gaE20="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-233d3255_1691595068828_0.42233863967267604"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-3f8124e0":{"name":"@latticexyz/network","version":"2.0.0-main-3f8124e0","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-3f8124e0","@latticexyz/recs":"2.0.0-main-3f8124e0","@latticexyz/schema-type":"2.0.0-main-3f8124e0","@latticexyz/services":"2.0.0-main-3f8124e0","@latticexyz/solecs":"2.0.0-main-3f8124e0","@latticexyz/store":"2.0.0-main-3f8124e0","@latticexyz/utils":"2.0.0-main-3f8124e0","@latticexyz/world":"2.0.0-main-3f8124e0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-3f8124e0","_integrity":"sha512-FXswm9CZTirVlXbqJmlCF87cGHlsdon3fomaAQBa1Yw+alE8CvOIsHW6wBdZLIdzzidk0/piobxUhn+p63p6+w==","_resolved":"/tmp/e04cd2e347e3f020ae96dc39d191da72/latticexyz-network-2.0.0-main-3f8124e0.tgz","_from":"file:latticexyz-network-2.0.0-main-3f8124e0.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-FXswm9CZTirVlXbqJmlCF87cGHlsdon3fomaAQBa1Yw+alE8CvOIsHW6wBdZLIdzzidk0/piobxUhn+p63p6+w==","shasum":"445ce91646c4cf90a882318a753c481227b262f0","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-3f8124e0.tgz","fileCount":80,"unpackedSize":497653,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCShC6G65qv6/jLpouYfvAQ395UYOlsa3YFMS6dCwrfIgIgOU1UIwuSdG5ZiTdTJEWf4YZ3dAN1bBqqkUt4xT57wGU="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-3f8124e0_1691596125410_0.6926796203447141"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-9a7c9009":{"name":"@latticexyz/network","version":"2.0.0-main-9a7c9009","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-9a7c9009","@latticexyz/recs":"2.0.0-main-9a7c9009","@latticexyz/schema-type":"2.0.0-main-9a7c9009","@latticexyz/services":"2.0.0-main-9a7c9009","@latticexyz/solecs":"2.0.0-main-9a7c9009","@latticexyz/store":"2.0.0-main-9a7c9009","@latticexyz/utils":"2.0.0-main-9a7c9009","@latticexyz/world":"2.0.0-main-9a7c9009"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-9a7c9009","_integrity":"sha512-gJBkw8yxG2cUVY5jrsWIW4AsU29sXrFIe9Fz19dn7xrNmjq9tlItsGS0HtPtUb4qouI9iRfq+P51nlmMbd7+/Q==","_resolved":"/tmp/792b0f710a0a6f36d6163f4b3e0e3de3/latticexyz-network-2.0.0-main-9a7c9009.tgz","_from":"file:latticexyz-network-2.0.0-main-9a7c9009.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-gJBkw8yxG2cUVY5jrsWIW4AsU29sXrFIe9Fz19dn7xrNmjq9tlItsGS0HtPtUb4qouI9iRfq+P51nlmMbd7+/Q==","shasum":"6d336cec4a796b2ecdc778a3977ce343307e1255","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-9a7c9009.tgz","fileCount":80,"unpackedSize":497750,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDjWoJCZVW8IRbA5xMoo8GedzjGpetZ7g8gZUjzIWZKRwIgCTuaAIM0ulPbGPLsqtCb90WcnmxizHTguvqs8sh7h0U="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-9a7c9009_1691600052069_0.9530015459001984"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-35c9f33d":{"name":"@latticexyz/network","version":"2.0.0-main-35c9f33d","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-35c9f33d","@latticexyz/recs":"2.0.0-main-35c9f33d","@latticexyz/schema-type":"2.0.0-main-35c9f33d","@latticexyz/services":"2.0.0-main-35c9f33d","@latticexyz/solecs":"2.0.0-main-35c9f33d","@latticexyz/store":"2.0.0-main-35c9f33d","@latticexyz/utils":"2.0.0-main-35c9f33d","@latticexyz/world":"2.0.0-main-35c9f33d"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-35c9f33d","_integrity":"sha512-cvIOHJfahsOF/MrTzXPm700MBtEn6VHWepkE0iUWrwVbMxSnD3e8aoxVhkNUGnhsRMD7Gu59wSFiZPCbUNb3wA==","_resolved":"/tmp/f63c2462b65f67840170bcbdab6c3a5b/latticexyz-network-2.0.0-main-35c9f33d.tgz","_from":"file:latticexyz-network-2.0.0-main-35c9f33d.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-cvIOHJfahsOF/MrTzXPm700MBtEn6VHWepkE0iUWrwVbMxSnD3e8aoxVhkNUGnhsRMD7Gu59wSFiZPCbUNb3wA==","shasum":"527f5bff7898e2e6c23a3b6ea5a40ef5aa82bfa5","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-35c9f33d.tgz","fileCount":80,"unpackedSize":497847,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCLju9l0056tOt3aCsDRMEHpjsRw4DUl6qNkTesZ+GfgQIhAOjFiKO1L0/mjg1bcbrH0/8EipEzFJa5L7pIjN0Sd8Sw"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-35c9f33d_1691604799246_0.26493429096490306"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-267605a0":{"name":"@latticexyz/network","version":"2.0.0-main-267605a0","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-267605a0","@latticexyz/recs":"2.0.0-main-267605a0","@latticexyz/schema-type":"2.0.0-main-267605a0","@latticexyz/services":"2.0.0-main-267605a0","@latticexyz/solecs":"2.0.0-main-267605a0","@latticexyz/store":"2.0.0-main-267605a0","@latticexyz/utils":"2.0.0-main-267605a0","@latticexyz/world":"2.0.0-main-267605a0"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-267605a0","_integrity":"sha512-RJFUyJejlJKEYrCPWDHPfNDDpzHPhKMOovNTh7ZtSiEu1awiaT3ZuBDowe+9HEQBy9NGriNR/EkHpJJG8+eQXQ==","_resolved":"/tmp/84892a5a196e1f0f3a141f0a815a355b/latticexyz-network-2.0.0-main-267605a0.tgz","_from":"file:latticexyz-network-2.0.0-main-267605a0.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-RJFUyJejlJKEYrCPWDHPfNDDpzHPhKMOovNTh7ZtSiEu1awiaT3ZuBDowe+9HEQBy9NGriNR/EkHpJJG8+eQXQ==","shasum":"314e4538eef731e9ecdcd99763d64e6e0683b4e5","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-267605a0.tgz","fileCount":80,"unpackedSize":497847,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHo+CR0cVwABGxONejd71wxKfF+pL4uXO9edJkEkz33UAiATYY/2BGaXv4Trd8Q4AEnp/uzcD2WHR+nJtQ7PFDgKaA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-267605a0_1691614950011_0.23859376971893198"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-next.1":{"name":"@latticexyz/network","version":"2.0.0-next.1","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-next.1","@latticexyz/recs":"2.0.0-next.1","@latticexyz/schema-type":"2.0.0-next.1","@latticexyz/services":"2.0.0-next.1","@latticexyz/solecs":"2.0.0-next.1","@latticexyz/store":"2.0.0-next.1","@latticexyz/utils":"2.0.0-next.1","@latticexyz/world":"2.0.0-next.1"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-next.1","_integrity":"sha512-xq+kFgHWKQB7NNGfFle4MFLVgoaefAUky0w8e8QC5S5lopt7SwCYHRDAhpjX1mWApTCHvToovQuxJzeKjgj6hw==","_resolved":"/tmp/88e3fe872d3544fec1cd32b69011c612/latticexyz-network-2.0.0-next.1.tgz","_from":"file:latticexyz-network-2.0.0-next.1.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-xq+kFgHWKQB7NNGfFle4MFLVgoaefAUky0w8e8QC5S5lopt7SwCYHRDAhpjX1mWApTCHvToovQuxJzeKjgj6hw==","shasum":"75c5db79de76e0c1e9cb316ba5ac6bfb365eb857","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-next.1.tgz","fileCount":80,"unpackedSize":496008,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC1YlD+9PjxCDL1AS/TJWGVJi8Y00YFlpHie0huWH4pbAIgf0qgbtdC5+cNHMlr5ttNk/LDbMsFsnsxesnHkm8VZVk="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-next.1_1691615187410_0.5148405940303475"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-788de8de":{"name":"@latticexyz/network","version":"2.0.0-main-788de8de","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-788de8de","@latticexyz/recs":"2.0.0-main-788de8de","@latticexyz/schema-type":"2.0.0-main-788de8de","@latticexyz/services":"2.0.0-main-788de8de","@latticexyz/solecs":"2.0.0-main-788de8de","@latticexyz/store":"2.0.0-main-788de8de","@latticexyz/utils":"2.0.0-main-788de8de","@latticexyz/world":"2.0.0-main-788de8de"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-788de8de","_integrity":"sha512-gSitmbDO0bq6T3uAYxV3uhfybhspRqfAmLM72rw607dnAJVxUV/h/3pe0g9cfJ6BX6M8cpbonqOtQW1745+sbg==","_resolved":"/tmp/fea3ccf84bbcff5db295ab974975123f/latticexyz-network-2.0.0-main-788de8de.tgz","_from":"file:latticexyz-network-2.0.0-main-788de8de.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-gSitmbDO0bq6T3uAYxV3uhfybhspRqfAmLM72rw607dnAJVxUV/h/3pe0g9cfJ6BX6M8cpbonqOtQW1745+sbg==","shasum":"9a54bc730c2aaba0d6f60b80d34225e0c917aa33","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-788de8de.tgz","fileCount":80,"unpackedSize":499643,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDaqxSd9MSx41nmwiDOG5zeLdNSoF5f2tDrh+vEXNK9hAIgboLzbrmkyjc6OCMbhWPHFnIMzG/kHkmyOn4e/whuXMM="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-788de8de_1691615227943_0.49733040810312046"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-48c51b52":{"name":"@latticexyz/network","version":"2.0.0-main-48c51b52","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-48c51b52","@latticexyz/recs":"2.0.0-main-48c51b52","@latticexyz/schema-type":"2.0.0-main-48c51b52","@latticexyz/services":"2.0.0-main-48c51b52","@latticexyz/solecs":"2.0.0-main-48c51b52","@latticexyz/store":"2.0.0-main-48c51b52","@latticexyz/utils":"2.0.0-main-48c51b52","@latticexyz/world":"2.0.0-main-48c51b52"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-48c51b52","_integrity":"sha512-ljFrLaJ4hsnSMJAIYmBIwSySANPB7fBOtJohV4XKNykPfrFZ4xvTwjGX/7Q6G1lpIfe4/UOZDSR6dMlUvq8mtw==","_resolved":"/tmp/0ac11d8d2289a9d347fba10aa4c9b9b0/latticexyz-network-2.0.0-main-48c51b52.tgz","_from":"file:latticexyz-network-2.0.0-main-48c51b52.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-ljFrLaJ4hsnSMJAIYmBIwSySANPB7fBOtJohV4XKNykPfrFZ4xvTwjGX/7Q6G1lpIfe4/UOZDSR6dMlUvq8mtw==","shasum":"0778d7ea8dc4a5e9decc601abbb6da8a449290fe","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-48c51b52.tgz","fileCount":80,"unpackedSize":499740,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDPKD+bZP0t0l1buxmRBJ/hBKJsLfGpIPeSq8hZ0nT+yAiBOW+tmW4l20ja75LSk3XBbqG5JxUVH/q6Xsx1YF+zcZA=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-48c51b52_1691764097888_0.07930153131159523"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-a2588116":{"name":"@latticexyz/network","version":"2.0.0-main-a2588116","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-a2588116","@latticexyz/recs":"2.0.0-main-a2588116","@latticexyz/schema-type":"2.0.0-main-a2588116","@latticexyz/services":"2.0.0-main-a2588116","@latticexyz/solecs":"2.0.0-main-a2588116","@latticexyz/store":"2.0.0-main-a2588116","@latticexyz/utils":"2.0.0-main-a2588116","@latticexyz/world":"2.0.0-main-a2588116"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-a2588116","_integrity":"sha512-y0JgyEqiIayCwsk5PHjdaquy/JqqdjIkU4SxRNyO3z9tjgP21yUDiasCZVWoG8c2uF0cmHa/OwmweRH/tSfGJA==","_resolved":"/tmp/c70572a353bc75bd9bda04772fe5095e/latticexyz-network-2.0.0-main-a2588116.tgz","_from":"file:latticexyz-network-2.0.0-main-a2588116.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-y0JgyEqiIayCwsk5PHjdaquy/JqqdjIkU4SxRNyO3z9tjgP21yUDiasCZVWoG8c2uF0cmHa/OwmweRH/tSfGJA==","shasum":"73ecd65298e4a30e3a4deb0085c477b6fbd3f1a9","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-a2588116.tgz","fileCount":80,"unpackedSize":499837,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDCAvKJLwmPf3mSBQurvCTcHQheNoiEK9tn1rLFubYDMwIgRjZ8xq2AQnWAxyUweikejPI1Gr0n+Be+vcp8XGkq1zw="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-a2588116_1691782611948_0.9554526517953312"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-cca3b462":{"name":"@latticexyz/network","version":"2.0.0-main-cca3b462","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-cca3b462","@latticexyz/recs":"2.0.0-main-cca3b462","@latticexyz/schema-type":"2.0.0-main-cca3b462","@latticexyz/services":"2.0.0-main-cca3b462","@latticexyz/solecs":"2.0.0-main-cca3b462","@latticexyz/store":"2.0.0-main-cca3b462","@latticexyz/utils":"2.0.0-main-cca3b462","@latticexyz/world":"2.0.0-main-cca3b462"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-cca3b462","_integrity":"sha512-RHstM+gO5A4hye1mUMSye1VrRFSSSe20MPvWa0LlayRSSJzyskwUaSKd+coscoFDclCTlERyFe38c4lH8OJ0JQ==","_resolved":"/tmp/2d6022a964cfb14de4f4048e31034cb3/latticexyz-network-2.0.0-main-cca3b462.tgz","_from":"file:latticexyz-network-2.0.0-main-cca3b462.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-RHstM+gO5A4hye1mUMSye1VrRFSSSe20MPvWa0LlayRSSJzyskwUaSKd+coscoFDclCTlERyFe38c4lH8OJ0JQ==","shasum":"cca06942c1e829efdc3c9c14f55bd915cbf6be14","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-cca3b462.tgz","fileCount":80,"unpackedSize":499684,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE9eTe2f51G2wD/4A6U49KHGaVeuBNMebHuvtk9bTU0JAiBI+6PKuB8Vu0ZL//lbUdyWj4WtV5Vn/Aa44C73VHeVhQ=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-cca3b462_1691917729465_0.6513954211133599"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-8e753bfb":{"name":"@latticexyz/network","version":"2.0.0-main-8e753bfb","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-8e753bfb","@latticexyz/recs":"2.0.0-main-8e753bfb","@latticexyz/schema-type":"2.0.0-main-8e753bfb","@latticexyz/services":"2.0.0-main-8e753bfb","@latticexyz/solecs":"2.0.0-main-8e753bfb","@latticexyz/store":"2.0.0-main-8e753bfb","@latticexyz/utils":"2.0.0-main-8e753bfb","@latticexyz/world":"2.0.0-main-8e753bfb"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-8e753bfb","_integrity":"sha512-A3z4Q1ytdIS6V94S0slpJZydMyyMzlLDGr20F4FuMOsmS9yuELvT3wrBU35+m8xpFFyap6IyJTRsc73/J0whPQ==","_resolved":"/tmp/8c0f5d7cd59f669894bd27f09ea2d066/latticexyz-network-2.0.0-main-8e753bfb.tgz","_from":"file:latticexyz-network-2.0.0-main-8e753bfb.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-A3z4Q1ytdIS6V94S0slpJZydMyyMzlLDGr20F4FuMOsmS9yuELvT3wrBU35+m8xpFFyap6IyJTRsc73/J0whPQ==","shasum":"69299d62085a7bc65d12f052cdace954b9920d8d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-8e753bfb.tgz","fileCount":80,"unpackedSize":499684,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDh+qgnsgLKtRa8gfi+tG/TReSVvpz0mAIMsVW609gG/QIhAJ/7EKQlEAWNxMhg1pwN9sKqliJVWCgVeHxYCzBzaFu/"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-8e753bfb_1691917884799_0.7658671301244395"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-939916bc":{"name":"@latticexyz/network","version":"2.0.0-main-939916bc","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-939916bc","@latticexyz/recs":"2.0.0-main-939916bc","@latticexyz/schema-type":"2.0.0-main-939916bc","@latticexyz/services":"2.0.0-main-939916bc","@latticexyz/solecs":"2.0.0-main-939916bc","@latticexyz/store":"2.0.0-main-939916bc","@latticexyz/utils":"2.0.0-main-939916bc","@latticexyz/world":"2.0.0-main-939916bc"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-939916bc","_integrity":"sha512-uQEiPlR/rqowUW0ile95U90od4K/25K58ETCcoeK2il1KgjoJM+Oj+6Hl8L7efOkLNJMP8bz08mz+rxHZ2ueRg==","_resolved":"/tmp/3e0dc0c9c0802f2d1324e9521bf0f743/latticexyz-network-2.0.0-main-939916bc.tgz","_from":"file:latticexyz-network-2.0.0-main-939916bc.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-uQEiPlR/rqowUW0ile95U90od4K/25K58ETCcoeK2il1KgjoJM+Oj+6Hl8L7efOkLNJMP8bz08mz+rxHZ2ueRg==","shasum":"2f9b1a8b687fb11281be7b344cde23c927b14655","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-939916bc.tgz","fileCount":80,"unpackedSize":499781,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCk49ow71l4V0yftJwEzfE/TRuvCl95mGO4anpY0RGuHQIhAOh4CmcKbZBenQXbVjTHkHxYTSL+bzingXA/07dtKb+S"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-939916bc_1692020388459_0.672902420431589"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-83d9589f":{"name":"@latticexyz/network","version":"2.0.0-main-83d9589f","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-83d9589f","@latticexyz/recs":"2.0.0-main-83d9589f","@latticexyz/schema-type":"2.0.0-main-83d9589f","@latticexyz/services":"2.0.0-main-83d9589f","@latticexyz/solecs":"2.0.0-main-83d9589f","@latticexyz/store":"2.0.0-main-83d9589f","@latticexyz/utils":"2.0.0-main-83d9589f","@latticexyz/world":"2.0.0-main-83d9589f"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-83d9589f","_integrity":"sha512-fxVqEaydR/9vPgxUEI3GbXIPl/H+tfJ1lJnZ7t7BAxLzSTzE2StwSLAaG9/YY3N4jVcBRduCw2Zqt9joizpZVQ==","_resolved":"/tmp/d445a456cd920c9b906877215964fb6b/latticexyz-network-2.0.0-main-83d9589f.tgz","_from":"file:latticexyz-network-2.0.0-main-83d9589f.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-fxVqEaydR/9vPgxUEI3GbXIPl/H+tfJ1lJnZ7t7BAxLzSTzE2StwSLAaG9/YY3N4jVcBRduCw2Zqt9joizpZVQ==","shasum":"d8ea073fffbedcd320365e2f1173f0323d2026bc","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-83d9589f.tgz","fileCount":80,"unpackedSize":499781,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDnHfAcxG+SylrCyA1H1d99Ell1DJAgyOeSk6Otl8Mf5wIhAOOCkHBX620D9q7iEe7IkjfWEFNV0zBOlhslS88/3yH9"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-83d9589f_1692032342729_0.422713071437407"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-753bdce4":{"name":"@latticexyz/network","version":"2.0.0-main-753bdce4","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-753bdce4","@latticexyz/recs":"2.0.0-main-753bdce4","@latticexyz/schema-type":"2.0.0-main-753bdce4","@latticexyz/services":"2.0.0-main-753bdce4","@latticexyz/solecs":"2.0.0-main-753bdce4","@latticexyz/store":"2.0.0-main-753bdce4","@latticexyz/utils":"2.0.0-main-753bdce4","@latticexyz/world":"2.0.0-main-753bdce4"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-753bdce4","_integrity":"sha512-6WgyG6NMaS/+IKgEsn5P66TjNFemvVT5dnQMhuDRq6TNqvOJ8t8arrUMJ/af6Imakbg7DOXbh8SGVvLlG6MMhw==","_resolved":"/tmp/50420b36e88300387c7cec95900fdbb6/latticexyz-network-2.0.0-main-753bdce4.tgz","_from":"file:latticexyz-network-2.0.0-main-753bdce4.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-6WgyG6NMaS/+IKgEsn5P66TjNFemvVT5dnQMhuDRq6TNqvOJ8t8arrUMJ/af6Imakbg7DOXbh8SGVvLlG6MMhw==","shasum":"b03f337abb2ded2b99621209f5f5fec8e20ec09d","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-753bdce4.tgz","fileCount":80,"unpackedSize":499781,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCmxWdQ8ztHxKUq4BCPQzGGdesOzfeDoa2sbY1A7WvqrAIhAMEwXEquhINlKmX4vzVmd6KQKjGGqJYA7z5Epo5SuSon"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-753bdce4_1692099776507_0.3669393662613063"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-5294a7d5":{"name":"@latticexyz/network","version":"2.0.0-main-5294a7d5","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.3.1","@latticexyz/common":"2.0.0-main-5294a7d5","@latticexyz/recs":"2.0.0-main-5294a7d5","@latticexyz/schema-type":"2.0.0-main-5294a7d5","@latticexyz/services":"2.0.0-main-5294a7d5","@latticexyz/solecs":"2.0.0-main-5294a7d5","@latticexyz/store":"2.0.0-main-5294a7d5","@latticexyz/utils":"2.0.0-main-5294a7d5","@latticexyz/world":"2.0.0-main-5294a7d5"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-5294a7d5","_integrity":"sha512-NhOsVI3NnYonFqxJOg8DiqIRd6mKWhzsAqWFx+k8EdpR9wHjnzwMcS2t995+zWsMQbwHZL1v7mwpwDgmsXaxdQ==","_resolved":"/tmp/34d85b08abc9938333de90b55a4b62a2/latticexyz-network-2.0.0-main-5294a7d5.tgz","_from":"file:latticexyz-network-2.0.0-main-5294a7d5.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-NhOsVI3NnYonFqxJOg8DiqIRd6mKWhzsAqWFx+k8EdpR9wHjnzwMcS2t995+zWsMQbwHZL1v7mwpwDgmsXaxdQ==","shasum":"96178bb789272e9f187fdbaa3374358a4d8eee46","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-5294a7d5.tgz","fileCount":80,"unpackedSize":499781,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH8WNMBSfgSnhzGf7mPO1WYkmbdT90CH62kqrHj6QgOZAiBhFaBmB4NA2IA7N6Bf162QWo/c+3hIXMOurjkKV+ZyWg=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-5294a7d5_1692099890581_0.24236881982803204"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-b8a6158d":{"name":"@latticexyz/network","version":"2.0.0-main-b8a6158d","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.6.0","@latticexyz/common":"2.0.0-main-b8a6158d","@latticexyz/recs":"2.0.0-main-b8a6158d","@latticexyz/schema-type":"2.0.0-main-b8a6158d","@latticexyz/services":"2.0.0-main-b8a6158d","@latticexyz/solecs":"2.0.0-main-b8a6158d","@latticexyz/store":"2.0.0-main-b8a6158d","@latticexyz/utils":"2.0.0-main-b8a6158d","@latticexyz/world":"2.0.0-main-b8a6158d"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-b8a6158d","_integrity":"sha512-RiOBWMq/WqB3m6iedca+cc3Xp+rjaulqoW11yeg/1XE/uuJ2ldrP646tRuNsP3mvmpRHb+24MHBXpfecKDApYA==","_resolved":"/tmp/6ebdc838d040de24eeb947093aca21e9/latticexyz-network-2.0.0-main-b8a6158d.tgz","_from":"file:latticexyz-network-2.0.0-main-b8a6158d.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-RiOBWMq/WqB3m6iedca+cc3Xp+rjaulqoW11yeg/1XE/uuJ2ldrP646tRuNsP3mvmpRHb+24MHBXpfecKDApYA==","shasum":"6ab490fe4e4ba4f9b966f5e5805e4448148a8895","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-b8a6158d.tgz","fileCount":80,"unpackedSize":500191,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC4Pd24QDXWRusIxOIMUJ05qG+dXfWImYEfr6CRRQfTlwIhAIRg+M+P01rUbUordpKQ4Dwla1WglSsuAUDjv5QrNQ0V"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-b8a6158d_1692113000657_0.8779764578286418"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-b621fb97":{"name":"@latticexyz/network","version":"2.0.0-main-b621fb97","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.6.0","@latticexyz/common":"2.0.0-main-b621fb97","@latticexyz/recs":"2.0.0-main-b621fb97","@latticexyz/schema-type":"2.0.0-main-b621fb97","@latticexyz/services":"2.0.0-main-b621fb97","@latticexyz/solecs":"2.0.0-main-b621fb97","@latticexyz/store":"2.0.0-main-b621fb97","@latticexyz/utils":"2.0.0-main-b621fb97","@latticexyz/world":"2.0.0-main-b621fb97"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-b621fb97","_integrity":"sha512-Y4mza0UgLkAFGeguXIssaem5ovlHFen0XC9S4VfylYLVWjwnoexvpnACXtGSVhfGaaGaSO/C5kfvC+6scHyBwg==","_resolved":"/tmp/1e8b3f948c94bf1141a1f2eb14f8c174/latticexyz-network-2.0.0-main-b621fb97.tgz","_from":"file:latticexyz-network-2.0.0-main-b621fb97.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-Y4mza0UgLkAFGeguXIssaem5ovlHFen0XC9S4VfylYLVWjwnoexvpnACXtGSVhfGaaGaSO/C5kfvC+6scHyBwg==","shasum":"42cac9f4c22175da7297455112cafc0426653bfc","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-b621fb97.tgz","fileCount":80,"unpackedSize":500191,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEIfWdPzBjUM7FxxcQl5rzJO9yr7ySnWxZOMsUaICrTVAiAxSU8zNZ/cxq/q9H0PG36QkxSEQXCcIBYk6d1TOknQEg=="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-b621fb97_1692117951028_0.19127697917146813"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-next.2":{"name":"@latticexyz/network","version":"2.0.0-next.2","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.6.0","@latticexyz/common":"2.0.0-next.2","@latticexyz/recs":"2.0.0-next.2","@latticexyz/schema-type":"2.0.0-next.2","@latticexyz/services":"2.0.0-next.2","@latticexyz/solecs":"2.0.0-next.2","@latticexyz/store":"2.0.0-next.2","@latticexyz/utils":"2.0.0-next.2","@latticexyz/world":"2.0.0-next.2"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-next.2","_integrity":"sha512-+krlTp8wSi47oseGehyUaga6+PEN282r9maNM51SeUMKuCLqTlDAiFSBjwJ2yJhrshAGBriRzpKwkrpibo+CJQ==","_resolved":"/tmp/11785fd68668e8dfa85a2be45d3f9f05/latticexyz-network-2.0.0-next.2.tgz","_from":"file:latticexyz-network-2.0.0-next.2.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-+krlTp8wSi47oseGehyUaga6+PEN282r9maNM51SeUMKuCLqTlDAiFSBjwJ2yJhrshAGBriRzpKwkrpibo+CJQ==","shasum":"0891527d86a6b3fa8faa40f5a6d75288c90ec4bb","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-next.2.tgz","fileCount":80,"unpackedSize":496908,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE+lS19J0VxENL16UkdR09zHVel8NWf/1PuB1zq0qWz7AiEA4yAoy1zTlK4z4uSl1zEwVWiHu7PVU/SPpCS7zA0Z+mY="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-next.2_1692118357920_0.28782616707068875"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-5e744f29":{"name":"@latticexyz/network","version":"2.0.0-main-5e744f29","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.6.0","@latticexyz/common":"2.0.0-main-5e744f29","@latticexyz/recs":"2.0.0-main-5e744f29","@latticexyz/schema-type":"2.0.0-main-5e744f29","@latticexyz/services":"2.0.0-main-5e744f29","@latticexyz/solecs":"2.0.0-main-5e744f29","@latticexyz/store":"2.0.0-main-5e744f29","@latticexyz/utils":"2.0.0-main-5e744f29","@latticexyz/world":"2.0.0-main-5e744f29"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-5e744f29","_integrity":"sha512-scn3hmmRNVerz9gbo7VEARCOVIyeSrm4QKNLYiTwiSnbJt/mWTlLfh0dBDAH0G2UcDUH7q/I6Z4edTqMkssA/Q==","_resolved":"/tmp/2a8ccf29bdd69038b1cbbe8c9ac56ffb/latticexyz-network-2.0.0-main-5e744f29.tgz","_from":"file:latticexyz-network-2.0.0-main-5e744f29.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-scn3hmmRNVerz9gbo7VEARCOVIyeSrm4QKNLYiTwiSnbJt/mWTlLfh0dBDAH0G2UcDUH7q/I6Z4edTqMkssA/Q==","shasum":"ee76b974e269562e12b5e1bf856d2589b85dba77","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-5e744f29.tgz","fileCount":80,"unpackedSize":501244,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDoeq7sYQc/s+2yFRjxsFbwKoTkBB6oiEUsG0iBLb+UwQIgBPhM1Nbz4rNbjkNZkEEHKTmo/QG0hEv2q4bK99FtqtI="}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-5e744f29_1692118468710_0.2934306039573533"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-main-162ca7d3":{"name":"@latticexyz/network","version":"2.0.0-main-162ca7d3","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"license":"MIT","type":"module","exports":{".":"./dist/index.js","./dev":"./dist/dev/index.js"},"typesVersions":{"*":{"index":["./src/index.ts"],"dev":["./src/dev/index.ts"]}},"dependencies":{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","async-mutex":"^0.3.2","debug":"^4.3.4","ethers":"^5.7.2","lodash":"^4.17.21","mobx":"^6.7.0","nice-grpc-web":"^2.0.1","rxjs":"7.5.5","threads":"^1.7.0","viem":"1.6.0","@latticexyz/common":"2.0.0-main-162ca7d3","@latticexyz/recs":"2.0.0-main-162ca7d3","@latticexyz/schema-type":"2.0.0-main-162ca7d3","@latticexyz/services":"2.0.0-main-162ca7d3","@latticexyz/solecs":"2.0.0-main-162ca7d3","@latticexyz/store":"2.0.0-main-162ca7d3","@latticexyz/utils":"2.0.0-main-162ca7d3","@latticexyz/world":"2.0.0-main-162ca7d3"},"devDependencies":{"@types/debug":"^4.1.7","@types/jest":"^27.4.1","@types/lodash":"^4.14.182","@types/node":"^18.15.11","fake-indexeddb":"^4.0.0","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","ts-jest":"^29.0.5","tsup":"^6.7.0"},"gitHead":"914a1e0ae4a573d685841ca2ea921435057deb8f","scripts":{"build":"pnpm run build:js","build:js":"tsup","clean":"pnpm run clean:js","clean:js":"rimraf dist","dev":"tsup --watch","lint":"eslint . --ext .ts","test":"tsc --noEmit && jest --forceExit"},"readme":"# Network\n\nThis package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.\n\nThe general utilities can be used without MUD. For the specialized but much more powerful utilities, usage of `solecs` is required and `recs` is recommended.\n\nSee [mud.dev/network](https://mud.dev/network) for the detailed API documentation.\n\n# Example\n\nThis is a real-world example from an upcoming game built with MUD.\n\n```typescript\n// setupContracts.ts\n\nimport {\n  createNetwork,\n  createContracts,\n  Mappings,\n  createTxQueue,\n  createSyncWorker,\n  createEncoder,\n  NetworkComponentUpdate,\n  createSystemExecutor,\n} from \"@latticexyz/network\";\n\nimport { Component as SolecsComponent, World as WorldContract } from \"@latticexyz/solecs\";\nimport WorldAbi from \"@latticexyz/solecs/abi/World.sol/World.abi.json\";\nimport ComponentAbi from \"@latticexyz/solecs/abi/Component.sol/Component.json\";\n\nimport {\n  Component,\n  Components,\n  EntityIndex,\n  getComponentEntities,\n  getComponentValueStrict,\n  removeComponent,\n  Schema,\n  setComponent,\n  Type,\n  World,\n} from \"@latticexyz/recs\";\n\nimport { keccak256, stretch, toEthAddress } from \"@latticexyz/utils\";\n\nimport { defineStringComponent } from \"@latticexyz/std-client\";\n\nimport { bufferTime, filter, Observable, Subject } from \"rxjs\";\nimport { computed, IComputedValue } from \"mobx\";\nimport { Contract, ethers, Signer, Wallet } from \"ethers\";\nimport { JsonRpcProvider } from \"@ethersproject/providers\";\n\nimport { SystemTypes } from \"<contracts>/types/SystemTypes\";\nimport { SystemAbis } from \"<contracts>/types/SystemAbis.mjs\";\nimport { config } from \"./config\";\n\nexport type ContractComponents = {\n  [key: string]: Component<Schema, { contractId: string }>;\n};\n\nexport async function setupContracts<C extends ContractComponents>(world: World, components: C) {\n  const SystemsRegistry = defineStringComponent(world, {\n    id: \"SystemsRegistry\",\n    metadata: { contractId: \"world.component.systems\" },\n  });\n\n  const ComponentsRegistry = defineStringComponent(world, {\n    id: \"ComponentsRegistry\",\n    metadata: { contractId: \"world.component.components\" },\n  });\n\n  components = {\n    ...components,\n    SystemsRegistry,\n    ComponentsRegistry,\n  };\n\n  const mappings: Mappings<C> = {};\n\n  for (const key of Object.keys(components)) {\n    const { contractId } = components[key].metadata;\n    mappings[keccak256(contractId)] = key;\n  }\n\n  const network = await createNetwork(config);\n\n  const signerOrProvider = computed(() => network.signer.get() || network.providers.get().json);\n\n  const { contracts, config: contractsConfig } = await createContracts<{ World: WorldContract }>({\n    config: { World: { abi: WorldAbi, address: config.worldAddress } },\n    signerOrProvider,\n  });\n\n  const { txQueue, dispose: disposeTxQueue } = createTxQueue(contracts, network);\n\n  const systems = createSystemExecutor<SystemTypes>(world, network, SystemsRegistry, SystemAbis, {\n    devMode: config.devMode,\n  });\n\n  const { ecsEvent$, config$, dispose } = createSyncWorker<C>();\n\n  function startSync() {\n    config$.next({\n      provider: networkConfig.provider,\n      worldContract: contractsConfig.World,\n      initialBlockNumber: config.initialBlockNumber ?? 0,\n      chainId: config.chainId,\n      disableCache: false,\n      snapshotServiceUrl: networkConfig.snapshotServiceUrl,\n      streamServiceUrl: networkConfig.streamServiceUrl,\n    });\n  }\n\n  const { txReduced$ } = applyNetworkUpdates(world, components, ecsEvent$, mappings);\n\n  const encoders = createEncoders(world, ComponentsRegistry, signerOrProvider);\n\n  return { txQueue, txReduced$, encoders, network, startSync, systems };\n}\n\nasync function createEncoders(\n  world: World,\n  components: Component<{ value: Type.String }>,\n  signerOrProvider: IComputedValue<JsonRpcProvider | Signer>\n) {\n  const encoders = {} as Record<string, ReturnType<typeof createEncoder>>;\n\n  async function fetchAndCreateEncoder(entity: EntityIndex) {\n    const componentAddress = toEthAddress(world.entities[entity]);\n    const componentId = getComponentValueStrict(components, entity).value;\n    const componentContract = new Contract(\n      componentAddress,\n      ComponentAbi.abi,\n      signerOrProvider.get()\n    ) as SolecsComponent;\n    const [componentSchemaPropNames, componentSchemaTypes] = await componentContract.getSchema();\n    encoders[componentId] = createEncoder(componentSchemaPropNames, componentSchemaTypes);\n  }\n\n  // Initial setup\n  for (const entity of getComponentEntities(components)) fetchAndCreateEncoder(entity);\n\n  // Keep up to date\n  const subscription = components.update$.subscribe((update) => fetchAndCreateEncoder(update.entity));\n  world.registerDisposer(() => subscription?.unsubscribe());\n\n  return encoders;\n}\n\n/**\n * Sets up synchronization between contract components and client components\n */\nfunction applyNetworkUpdates<C extends Components>(\n  world: World,\n  components: C,\n  ecsEvent$: Observable<NetworkComponentUpdate<C>>,\n  mappings: Mappings<C>\n) {\n  const txReduced$ = new Subject<string>();\n\n  const ecsEventSub = ecsEvent$.subscribe((update) => {\n    const entityIndex = world.entityToIndex.get(update.entity) ?? world.registerEntity({ id: update.entity });\n    const componentKey = mappings[update.component];\n\n    if (update.value === undefined) {\n      // undefined value means component removed\n      removeComponent(components[componentKey] as Component<Schema>, entityIndex);\n    } else {\n      setComponent(components[componentKey] as Component<Schema>, entityIndex, update.value);\n    }\n\n    if (update.lastEventInTx) txReduced$.next(update.txHash);\n  });\n\n  return { txReduced$: txReduced$.asObservable() };\n}\n```\n","readmeFilename":"README.md","description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","bugs":{"url":"https://github.com/latticexyz/mud/issues"},"homepage":"https://github.com/latticexyz/mud#readme","_id":"@latticexyz/network@2.0.0-main-162ca7d3","_integrity":"sha512-ofSKuSiVvfnGLqUgZ0cFcoTFgppcQbDMKrTBGzDlKlWf1xTGPH9FVDASMKE367Dmie+seH15xuBMBXfyMZwiog==","_resolved":"/tmp/17d5161a2c388239d3524c753330fde9/latticexyz-network-2.0.0-main-162ca7d3.tgz","_from":"file:latticexyz-network-2.0.0-main-162ca7d3.tgz","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-ofSKuSiVvfnGLqUgZ0cFcoTFgppcQbDMKrTBGzDlKlWf1xTGPH9FVDASMKE367Dmie+seH15xuBMBXfyMZwiog==","shasum":"45af42cbafbead6194efb20576ce130e76305656","tarball":"https://registry.npmjs.org/@latticexyz/network/-/network-2.0.0-main-162ca7d3.tgz","fileCount":80,"unpackedSize":501244,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCxRO3fDl/K9L4cDZTsLPE9s5q5y6NiUPv+1nBxJ3mgeAIhAJ5EwSNKMIinGJqdi/OynhWRMFtljm6fVhjktBKd2Axa"}]},"_npmUser":{"name":"alvarius","email":"alvarius@lattice.xyz"},"directories":{},"maintainers":[{"name":"holic","email":"kingersoll@gmail.com"},{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/network_2.0.0-main-162ca7d3_1692174834134_0.03033245273912999"},"_hasShrinkwrap":false,"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."}},"time":{"created":"2022-09-13T07:38:13.018Z","0.9.0":"2022-09-13T07:38:13.684Z","modified":"2023-09-27T11:25:54.294Z","0.10.0":"2022-09-14T11:16:48.351Z","0.11.1":"2022-09-15T10:26:41.884Z","0.12.0":"2022-09-16T17:41:15.097Z","0.13.0":"2022-09-19T22:50:27.777Z","0.14.0":"2022-09-20T14:42:59.652Z","0.14.1":"2022-09-21T09:18:55.478Z","0.14.2":"2022-09-21T11:33:04.112Z","0.15.0":"2022-09-21T14:37:31.725Z","0.15.1":"2022-09-23T14:21:36.588Z","0.16.0":"2022-09-26T17:37:16.798Z","0.16.1":"2022-09-26T19:08:14.364Z","0.16.2":"2022-09-26T20:21:30.249Z","0.16.3":"2022-09-26T21:50:50.056Z","0.16.4":"2022-09-26T23:47:11.260Z","1.0.0":"2022-09-27T13:55:57.503Z","1.1.0":"2022-09-28T19:26:04.118Z","1.2.0":"2022-09-29T10:47:23.009Z","1.3.0":"2022-09-30T16:39:11.570Z","1.4.0":"2022-10-03T12:59:52.723Z","1.4.1":"2022-10-03T13:18:55.666Z","1.5.0":"2022-10-03T22:04:44.468Z","1.5.1":"2022-10-03T22:16:32.609Z","1.6.0":"2022-10-04T18:31:02.415Z","1.7.0":"2022-10-06T12:59:29.568Z","1.7.1":"2022-10-06T13:06:10.729Z","1.8.0":"2022-10-07T01:24:49.052Z","1.9.0":"2022-10-11T15:39:48.915Z","1.10.0":"2022-10-11T16:12:39.445Z","1.11.0":"2022-10-11T17:54:01.339Z","1.12.0":"2022-10-12T12:16:24.973Z","1.13.0":"2022-10-15T04:12:36.390Z","1.14.2":"2022-10-18T17:08:04.168Z","1.15.0":"2022-10-18T20:26:50.954Z","1.16.0":"2022-10-19T21:02:55.137Z","1.17.0":"2022-10-19T22:42:59.154Z","1.18.0":"2022-10-21T15:20:39.978Z","1.19.0":"2022-10-21T23:30:46.799Z","1.20.0":"2022-10-22T23:32:52.068Z","1.21.0":"2022-10-26T09:38:51.822Z","1.22.0":"2022-10-26T16:32:24.421Z","1.23.0":"2022-10-26T17:25:27.158Z","1.23.1":"2022-10-28T19:26:46.954Z","1.24.0":"2022-10-28T20:43:35.094Z","1.24.1":"2022-10-29T11:57:50.478Z","1.25.1":"2022-11-03T17:17:48.093Z","1.26.0":"2022-11-07T15:59:57.436Z","1.27.1":"2022-11-15T19:52:42.225Z","1.28.0":"2022-11-20T15:56:31.606Z","1.28.1":"2022-11-24T17:03:38.132Z","1.29.0":"2022-11-29T00:33:05.007Z","1.30.0":"2022-12-02T12:44:23.026Z","1.30.1":"2022-12-02T12:48:21.442Z","1.31.0":"2022-12-14T19:02:44.005Z","1.31.1":"2022-12-15T21:32:55.539Z","1.31.2":"2022-12-15T23:49:17.327Z","1.31.3":"2022-12-16T16:22:44.826Z","1.32.0":"2023-01-06T17:57:35.935Z","1.33.1":"2023-01-12T21:19:06.675Z","1.34.0":"2023-01-29T01:14:50.044Z","1.35.0":"2023-02-15T16:56:37.126Z","1.36.1":"2023-02-16T16:54:13.132Z","1.37.0":"2023-02-16T22:49:08.884Z","1.37.1":"2023-02-17T17:37:39.059Z","1.38.0":"2023-02-22T15:05:31.076Z","1.39.0":"2023-02-22T15:47:39.138Z","1.40.0":"2023-03-03T16:24:16.583Z","1.41.0":"2023-03-09T20:58:56.171Z","2.0.0-alpha.0":"2023-03-28T21:12:54.893Z","1.41.1-alpha.41":"2023-03-29T10:34:35.200Z","1.41.1-alpha.0":"2023-03-29T13:10:50.836Z","2.0.0-alpha.41":"2023-03-29T16:17:27.534Z","2.0.0-alpha.37":"2023-03-29T19:33:54.523Z","2.0.0-alpha.36":"2023-03-29T19:37:13.011Z","2.0.0-alpha.38":"2023-03-30T00:41:34.395Z","2.0.0-alpha.39":"2023-03-30T18:15:21.261Z","2.0.0-alpha.40":"2023-03-30T18:17:57.502Z","2.0.0-alpha.43":"2023-03-30T20:13:00.476Z","2.0.0-alpha.44":"2023-03-30T20:37:38.540Z","2.0.0-alpha.45":"2023-03-30T20:38:00.655Z","2.0.0-alpha.46":"2023-03-31T09:23:57.232Z","2.0.0-alpha.47":"2023-03-31T09:59:35.944Z","2.0.0-alpha.48":"2023-03-31T11:29:16.094Z","2.0.0-alpha.49":"2023-03-31T13:34:24.121Z","2.0.0-alpha.50":"2023-03-31T16:30:34.519Z","2.0.0-alpha.51":"2023-03-31T16:32:43.496Z","2.0.0-alpha.52":"2023-03-31T17:06:40.503Z","2.0.0-alpha.53":"2023-04-01T08:36:38.175Z","2.0.0-alpha.54":"2023-04-01T11:27:22.199Z","2.0.0-alpha.55":"2023-04-01T11:55:18.259Z","2.0.0-alpha.56":"2023-04-01T13:47:08.138Z","2.0.0-alpha.57":"2023-04-01T14:04:30.981Z","2.0.0-alpha.58":"2023-04-01T15:11:27.415Z","2.0.0-alpha.59":"2023-04-01T21:00:05.869Z","2.0.0-alpha.60":"2023-04-02T04:33:25.750Z","2.0.0-alpha.61":"2023-04-02T04:48:31.327Z","2.0.0-alpha.62":"2023-04-02T05:03:40.504Z","2.0.0-alpha.63":"2023-04-02T09:07:43.226Z","2.0.0-alpha.64":"2023-04-02T09:11:20.075Z","2.0.0-alpha.65":"2023-04-02T11:06:39.736Z","2.0.0-alpha.67":"2023-04-03T23:28:49.123Z","2.0.0-alpha.66":"2023-04-03T23:31:36.765Z","2.0.0-alpha.68":"2023-04-04T11:56:35.678Z","2.0.0-alpha.69":"2023-04-04T13:28:32.262Z","2.0.0-alpha.72":"2023-04-04T16:54:08.516Z","2.0.0-alpha.73":"2023-04-04T16:56:42.055Z","2.0.0-alpha.74":"2023-04-04T17:21:26.493Z","2.0.0-alpha.75":"2023-04-04T23:00:33.083Z","2.0.0-alpha.76":"2023-04-06T16:48:58.104Z","2.0.0-alpha.78":"2023-04-06T23:31:06.654Z","2.0.0-alpha.79":"2023-04-09T15:20:24.213Z","2.0.0-alpha.80":"2023-04-11T14:44:56.023Z","2.0.0-alpha.81":"2023-04-11T14:48:27.650Z","2.0.0-alpha.83":"2023-04-11T14:59:58.001Z","2.0.0-alpha.84":"2023-04-11T15:28:50.782Z","2.0.0-alpha.85":"2023-04-11T16:18:40.232Z","2.0.0-alpha.86":"2023-04-11T17:13:58.976Z","2.0.0-alpha.87":"2023-04-11T19:59:28.506Z","2.0.0-alpha.88":"2023-04-12T18:19:03.481Z","2.0.0-alpha.89":"2023-04-12T19:33:51.944Z","2.0.0-alpha.90":"2023-04-12T20:07:56.647Z","2.0.0-alpha.91":"2023-04-12T20:20:54.748Z","2.0.0-alpha.92":"2023-04-12T21:20:06.912Z","2.0.0-alpha.93":"2023-04-12T21:23:40.745Z","2.0.0-alpha.94":"2023-04-13T17:52:51.252Z","1.42.0":"2023-04-13T18:33:22.005Z","2.0.0-alpha.1":"2023-04-13T19:20:20.116Z","2.0.0-alpha.2":"2023-04-13T20:20:50.950Z","2.0.0-alpha.3":"2023-04-13T22:07:47.404Z","2.0.0-alpha.4":"2023-04-14T18:36:19.443Z","2.0.0-alpha.5":"2023-04-14T21:01:44.957Z","2.0.0-alpha.6":"2023-04-17T01:15:13.215Z","2.0.0-alpha.7":"2023-04-17T01:25:23.312Z","2.0.0-alpha.8":"2023-04-17T01:59:05.273Z","2.0.0-alpha.9":"2023-04-17T10:10:04.356Z","2.0.0-alpha.1.10":"2023-04-18T13:55:35.139Z","2.0.0-alpha.1.11":"2023-04-18T14:01:51.454Z","2.0.0-alpha.1.12":"2023-04-18T17:35:58.605Z","2.0.0-alpha.1.13":"2023-04-19T08:02:21.773Z","2.0.0-alpha.1.21":"2023-04-21T17:23:53.529Z","2.0.0-alpha.1.22":"2023-04-21T17:38:37.045Z","1.43.0":"2023-04-23T19:06:36.347Z","2.0.0-alpha.1.23":"2023-04-24T17:54:46.758Z","2.0.0-alpha.1.26":"2023-04-24T21:02:26.886Z","2.0.0-alpha.1.27":"2023-04-24T21:20:06.952Z","2.0.0-alpha.1.28":"2023-04-24T22:06:55.263Z","2.0.0-alpha.1.29":"2023-04-25T17:58:08.113Z","2.0.0-alpha.1.30":"2023-04-25T20:10:33.336Z","2.0.0-alpha.1.31":"2023-04-26T15:50:27.471Z","2.0.0-alpha.1.32":"2023-04-26T18:42:23.721Z","2.0.0-alpha.1.33":"2023-04-27T19:37:11.993Z","2.0.0-alpha.1.35":"2023-05-01T15:54:24.313Z","2.0.0-alpha.1.36":"2023-05-01T15:55:41.748Z","2.0.0-alpha.1.38":"2023-05-01T15:56:05.607Z","2.0.0-alpha.1.37":"2023-05-01T15:56:10.549Z","2.0.0-alpha.1.34":"2023-05-01T15:57:09.858Z","2.0.0-alpha.1.39":"2023-05-02T14:38:15.454Z","2.0.0-alpha.1.41":"2023-05-02T21:32:09.926Z","2.0.0-alpha.1.42":"2023-05-03T14:07:52.751Z","2.0.0-alpha.1.43":"2023-05-03T16:12:41.377Z","2.0.0-alpha.1.44":"2023-05-04T15:05:28.449Z","2.0.0-alpha.1.45":"2023-05-04T17:17:01.026Z","2.0.0-alpha.1.46":"2023-05-04T18:38:53.520Z","2.0.0-alpha.1.47":"2023-05-04T19:52:22.631Z","2.0.0-alpha.1.48":"2023-05-08T13:31:23.565Z","2.0.0-alpha.1.49":"2023-05-08T13:41:23.905Z","2.0.0-alpha.1.50":"2023-05-08T14:00:47.938Z","2.0.0-alpha.1.51":"2023-05-08T14:47:33.207Z","2.0.0-alpha.1.52":"2023-05-08T14:54:39.252Z","2.0.0-alpha.1.53":"2023-05-09T08:54:29.852Z","2.0.0-alpha.1.54":"2023-05-09T13:57:23.959Z","2.0.0-alpha.1.55":"2023-05-09T13:59:20.980Z","2.0.0-alpha.1.56":"2023-05-09T14:01:59.009Z","2.0.0-alpha.1.57":"2023-05-09T14:03:16.410Z","2.0.0-alpha.1.58":"2023-05-09T14:18:41.277Z","2.0.0-alpha.1.59":"2023-05-09T17:25:59.273Z","2.0.0-alpha.1.60":"2023-05-09T21:37:34.219Z","2.0.0-alpha.1.61":"2023-05-10T16:01:19.355Z","2.0.0-alpha.1.62":"2023-05-10T16:45:57.604Z","2.0.0-alpha.1.63":"2023-05-10T17:03:16.316Z","2.0.0-alpha.1.64":"2023-05-10T17:16:00.563Z","2.0.0-alpha.1.65":"2023-05-10T17:48:42.782Z","2.0.0-alpha.1.66":"2023-05-10T19:50:16.586Z","2.0.0-alpha.1.67":"2023-05-10T20:24:14.495Z","2.0.0-alpha.1.68":"2023-05-11T08:40:52.416Z","2.0.0-alpha.1.69":"2023-05-11T08:53:10.850Z","2.0.0-alpha.1.70":"2023-05-11T09:12:20.355Z","2.0.0-alpha.1.71":"2023-05-11T09:36:27.510Z","2.0.0-alpha.1.72":"2023-05-11T10:13:39.586Z","2.0.0-alpha.1.73":"2023-05-11T10:14:39.303Z","2.0.0-alpha.1.74":"2023-05-11T10:32:54.480Z","2.0.0-alpha.1.75":"2023-05-11T10:34:02.991Z","2.0.0-alpha.1.76":"2023-05-11T10:39:38.558Z","2.0.0-alpha.1.77":"2023-05-11T10:44:59.864Z","2.0.0-alpha.1.78":"2023-05-11T11:00:08.517Z","2.0.0-alpha.1.79":"2023-05-11T12:32:44.845Z","2.0.0-alpha.1.80":"2023-05-11T14:05:47.890Z","2.0.0-alpha.1.81":"2023-05-11T15:00:54.471Z","2.0.0-alpha.1.82":"2023-05-11T16:02:13.255Z","2.0.0-alpha.1.83":"2023-05-11T23:28:42.066Z","2.0.0-alpha.1.84":"2023-05-12T03:13:44.808Z","2.0.0-alpha.1.85":"2023-05-12T10:17:16.040Z","2.0.0-alpha.1.86":"2023-05-12T10:29:35.582Z","2.0.0-alpha.1.87":"2023-05-12T10:30:12.890Z","2.0.0-alpha.1.88":"2023-05-12T14:22:08.609Z","2.0.0-alpha.1.89":"2023-05-12T15:17:39.244Z","2.0.0-alpha.1.90":"2023-05-12T15:22:31.365Z","2.0.0-alpha.1.91":"2023-05-12T15:39:05.607Z","2.0.0-alpha.1.92":"2023-05-12T22:10:56.186Z","2.0.0-alpha.1.93":"2023-05-14T01:01:48.698Z","2.0.0-alpha.1.94":"2023-05-15T08:25:38.780Z","2.0.0-alpha.1.95":"2023-05-15T08:31:32.032Z","2.0.0-alpha.1.96":"2023-05-15T08:32:29.444Z","2.0.0-alpha.1.97":"2023-05-15T08:35:17.609Z","2.0.0-alpha.1.98":"2023-05-15T08:35:23.500Z","2.0.0-alpha.1.100":"2023-05-15T14:36:15.551Z","2.0.0-alpha.1.101":"2023-05-15T15:09:44.128Z","2.0.0-alpha.1.102":"2023-05-15T16:35:17.634Z","2.0.0-alpha.1.103":"2023-05-15T19:02:25.704Z","2.0.0-alpha.1.104":"2023-05-15T20:54:28.290Z","2.0.0-alpha.1.105":"2023-05-15T21:27:08.161Z","2.0.0-alpha.1.106":"2023-05-16T09:27:15.063Z","2.0.0-alpha.1.107":"2023-05-16T11:10:33.698Z","2.0.0-alpha.1.108":"2023-05-16T12:54:34.543Z","2.0.0-alpha.1.109":"2023-05-16T13:49:59.351Z","2.0.0-alpha.1.110":"2023-05-16T14:06:34.995Z","2.0.0-alpha.1.111":"2023-05-16T14:37:45.959Z","2.0.0-alpha.1.112":"2023-05-16T14:42:21.756Z","2.0.0-alpha.1.113":"2023-05-16T14:44:32.989Z","2.0.0-alpha.1.114":"2023-05-16T16:01:13.072Z","2.0.0-alpha.1.115":"2023-05-16T19:27:07.439Z","2.0.0-alpha.1.116":"2023-05-16T20:36:50.441Z","2.0.0-alpha.1.117":"2023-05-16T22:07:08.435Z","2.0.0-alpha.1.118":"2023-05-16T22:34:37.995Z","2.0.0-alpha.1.120":"2023-05-16T23:40:54.331Z","2.0.0-alpha.1.119":"2023-05-16T23:40:59.168Z","2.0.0-alpha.1.121":"2023-05-17T00:10:41.365Z","2.0.0-alpha.1.122":"2023-05-17T00:13:21.847Z","2.0.0-alpha.1.125":"2023-05-17T07:50:55.008Z","2.0.0-alpha.1.126":"2023-05-17T10:38:49.866Z","2.0.0-alpha.1.127":"2023-05-17T10:39:38.872Z","2.0.0-alpha.1.128":"2023-05-17T10:42:59.357Z","2.0.0-alpha.1.129":"2023-05-17T10:53:15.172Z","2.0.0-alpha.1.130":"2023-05-17T14:18:47.568Z","2.0.0-alpha.1.131":"2023-05-17T15:13:58.485Z","2.0.0-alpha.1.132":"2023-05-17T16:24:19.171Z","2.0.0-alpha.1.133":"2023-05-17T16:56:14.294Z","2.0.0-alpha.1.134":"2023-05-17T17:02:56.932Z","2.0.0-alpha.1.135":"2023-05-17T17:31:01.088Z","2.0.0-alpha.1.136":"2023-05-17T18:00:28.644Z","2.0.0-alpha.1.137":"2023-05-17T18:11:02.652Z","2.0.0-alpha.1.138":"2023-05-17T19:40:21.512Z","2.0.0-alpha.1.139":"2023-05-17T21:38:07.081Z","2.0.0-alpha.1.140":"2023-05-17T22:35:13.236Z","2.0.0-alpha.1.141":"2023-05-17T22:37:09.864Z","2.0.0-alpha.1.142":"2023-05-17T22:50:59.838Z","2.0.0-alpha.1.143":"2023-05-18T01:09:17.899Z","2.0.0-alpha.1.144":"2023-05-18T01:10:35.021Z","2.0.0-alpha.1.145":"2023-05-18T01:15:30.812Z","2.0.0-alpha.1.146":"2023-05-18T01:15:51.738Z","2.0.0-alpha.1.147":"2023-05-18T01:18:23.257Z","2.0.0-alpha.1.148":"2023-05-18T02:58:00.951Z","2.0.0-alpha.1.149":"2023-05-18T12:54:32.494Z","2.0.0-alpha.1.150":"2023-05-18T13:58:44.225Z","2.0.0-alpha.1.151":"2023-05-18T14:39:34.979Z","2.0.0-alpha.1.152":"2023-05-18T15:14:11.473Z","2.0.0-alpha.1.153":"2023-05-18T15:41:03.159Z","2.0.0-alpha.1.154":"2023-05-18T15:55:22.113Z","2.0.0-alpha.1.155":"2023-05-18T16:36:58.410Z","2.0.0-alpha.1.156":"2023-05-18T17:10:43.422Z","2.0.0-alpha.1.157":"2023-05-18T17:22:50.867Z","2.0.0-alpha.1.158":"2023-05-18T17:30:41.443Z","2.0.0-alpha.1.159":"2023-05-18T17:54:52.159Z","2.0.0-alpha.1.160":"2023-05-18T18:24:59.382Z","2.0.0-alpha.1.161":"2023-05-18T18:50:37.611Z","2.0.0-alpha.1.162":"2023-05-18T18:51:27.199Z","2.0.0-alpha.1.163":"2023-05-18T19:15:25.459Z","2.0.0-alpha.1.164":"2023-05-18T20:28:54.001Z","2.0.0-alpha.1.165":"2023-05-18T21:23:35.958Z","2.0.0-alpha.1.166":"2023-05-18T22:15:25.920Z","2.0.0-alpha.1.167":"2023-05-18T23:15:41.969Z","2.0.0-alpha.1.168":"2023-05-18T23:17:20.852Z","2.0.0-alpha.1.169":"2023-05-18T23:26:44.107Z","2.0.0-alpha.1.170":"2023-05-19T05:27:31.444Z","2.0.0-alpha.1.171":"2023-05-19T14:50:18.858Z","2.0.0-alpha.1.172":"2023-05-19T14:51:47.934Z","2.0.0-alpha.1.173":"2023-05-19T15:37:44.098Z","2.0.0-alpha.1.174":"2023-05-19T18:18:31.190Z","2.0.0-alpha.1.175":"2023-05-19T19:21:24.476Z","2.0.0-alpha.1.176":"2023-05-20T01:01:39.247Z","2.0.0-alpha.1.177":"2023-05-20T07:24:11.732Z","2.0.0-alpha.1.178":"2023-05-20T15:06:35.178Z","2.0.0-alpha.1.179":"2023-05-20T15:43:23.940Z","2.0.0-alpha.1.180":"2023-05-20T18:42:41.726Z","2.0.0-alpha.1.181":"2023-05-20T20:02:05.927Z","2.0.0-alpha.1.182":"2023-05-20T22:07:48.829Z","2.0.0-alpha.1.183":"2023-05-20T23:02:32.817Z","2.0.0-alpha.1.184":"2023-05-22T16:53:21.803Z","2.0.0-alpha.1.185":"2023-05-22T17:15:05.360Z","2.0.0-alpha.1.186":"2023-05-22T17:27:33.583Z","2.0.0-alpha.1.187":"2023-05-22T17:30:13.838Z","2.0.0-alpha.1.188":"2023-05-22T17:48:54.117Z","2.0.0-alpha.1.189":"2023-05-22T17:53:18.216Z","2.0.0-alpha.1.190":"2023-05-22T19:24:56.446Z","2.0.0-alpha.1.191":"2023-05-22T21:55:07.658Z","2.0.0-alpha.1.192":"2023-05-23T08:48:50.910Z","2.0.0-alpha.1.193":"2023-05-23T09:12:44.648Z","2.0.0-alpha.1.194":"2023-05-23T09:48:35.774Z","2.0.0-alpha.1.195":"2023-05-23T11:12:35.097Z","2.0.0-alpha.1.196":"2023-05-23T15:33:06.220Z","2.0.0-alpha.1.197":"2023-05-23T21:28:53.553Z","2.0.0-alpha.1.198":"2023-05-31T07:31:49.875Z","2.0.0-alpha.1.199":"2023-06-01T13:55:37.322Z","2.0.0-alpha.1.200":"2023-06-01T21:02:40.377Z","2.0.0-alpha.1.201":"2023-06-01T21:09:50.220Z","2.0.0-alpha.1.202":"2023-06-01T23:26:50.060Z","2.0.0-alpha.1.203":"2023-06-05T15:53:18.563Z","2.0.0-alpha.1.204":"2023-06-07T14:42:49.209Z","2.0.0-alpha.1.206":"2023-06-07T22:30:41.563Z","2.0.0-alpha.1.205":"2023-06-07T22:30:54.685Z","2.0.0-alpha.1.207":"2023-06-08T10:30:17.819Z","2.0.0-alpha.1.208":"2023-06-08T16:23:11.306Z","2.0.0-alpha.1.209":"2023-06-08T16:43:55.154Z","2.0.0-alpha.1.210":"2023-06-08T17:40:34.207Z","2.0.0-alpha.1.211":"2023-06-08T18:28:04.342Z","2.0.0-alpha.1.212":"2023-06-08T22:00:26.514Z","2.0.0-alpha.1.213":"2023-06-12T17:08:48.425Z","2.0.0-alpha.1.214":"2023-06-12T17:44:25.250Z","2.0.0-alpha.1.215":"2023-06-12T17:57:00.059Z","2.0.0-alpha.1.216":"2023-06-12T19:11:49.979Z","2.0.0-alpha.1.217":"2023-06-13T15:53:19.026Z","2.0.0-alpha.1.218":"2023-06-13T16:59:24.633Z","2.0.0-alpha.1.221":"2023-06-13T17:58:03.067Z","2.0.0-alpha.1.222":"2023-06-13T18:56:39.320Z","2.0.0-alpha.1.223":"2023-06-15T05:15:58.263Z","2.0.0-alpha.1.224":"2023-06-15T15:47:55.849Z","2.0.0-alpha.1.225":"2023-06-15T16:02:45.023Z","2.0.0-alpha.1.226":"2023-06-16T11:06:37.882Z","2.0.0-alpha.1.227":"2023-06-16T11:07:46.318Z","2.0.0-alpha.1.228":"2023-06-16T11:30:19.926Z","2.0.0-alpha.1.229":"2023-06-16T11:58:11.146Z","2.0.0-alpha.1.230":"2023-06-16T12:42:02.941Z","2.0.0-alpha.1.231":"2023-06-16T14:01:12.218Z","2.0.0-alpha.1.232":"2023-06-16T14:11:54.704Z","2.0.0-alpha.1.233":"2023-06-16T14:35:14.811Z","2.0.0-alpha.1.234":"2023-06-16T16:44:36.014Z","2.0.0-alpha.1.235":"2023-06-16T16:51:34.719Z","2.0.0-alpha.1.236":"2023-06-16T16:59:05.539Z","2.0.0-alpha.1.237":"2023-06-16T17:01:32.938Z","2.0.0-alpha.1.238":"2023-06-16T17:01:44.790Z","2.0.0-alpha.1.239":"2023-06-16T19:39:13.956Z","2.0.0-alpha.1.242":"2023-06-16T22:00:22.340Z","2.0.0-alpha.1.243":"2023-06-16T22:16:06.202Z","2.0.0-alpha.1.244":"2023-06-20T12:01:46.297Z","2.0.0-alpha.1.247":"2023-06-20T17:32:26.662Z","2.0.0-alpha.1.248":"2023-06-23T09:38:21.218Z","2.0.0-alpha.1.249":"2023-06-23T11:06:28.972Z","2.0.0-alpha.1.250":"2023-06-23T11:53:02.151Z","2.0.0-alpha.1.251":"2023-06-24T16:14:50.424Z","2.0.0-alpha.1.252":"2023-06-26T10:10:37.992Z","2.0.0-alpha.1.253":"2023-06-26T11:10:45.830Z","2.0.0-alpha.1.254":"2023-06-26T13:45:50.738Z","2.0.0-alpha.1.255":"2023-06-26T15:24:04.763Z","2.0.0-alpha.1.256":"2023-06-26T17:04:44.233Z","2.0.0-alpha.1.257":"2023-06-26T17:51:42.094Z","2.0.0-alpha.1.258":"2023-06-28T15:47:31.345Z","2.0.0-alpha.1.259":"2023-06-29T09:39:23.277Z","2.0.0-alpha.1.260":"2023-06-29T11:32:59.474Z","2.0.0-alpha.1.261":"2023-07-03T09:43:47.552Z","2.0.0-alpha.1.262":"2023-07-03T10:09:59.311Z","2.0.0-alpha.1.263":"2023-07-03T12:11:39.473Z","2.0.0-alpha.1.264":"2023-07-03T12:12:05.561Z","2.0.0-alpha.1.265":"2023-07-03T12:13:09.783Z","2.0.0-alpha.1.266":"2023-07-03T17:45:17.550Z","2.0.0-alpha.1.267":"2023-07-03T19:32:38.385Z","2.0.0-alpha.1.268":"2023-07-04T07:16:39.657Z","0.0.0-main-20230704121617":"2023-07-04T12:17:17.442Z","0.0.0-main-20230705095946":"2023-07-05T10:00:47.458Z","0.0.0-main-20230705152036":"2023-07-05T15:21:52.510Z","0.0.0-main-20230705224651":"2023-07-05T22:47:48.388Z","0.0.0-main-20230705225731":"2023-07-05T22:58:30.539Z","0.0.0-main-20230705230250":"2023-07-05T23:04:02.961Z","0.0.0-main-20230706101146":"2023-07-06T10:12:48.164Z","0.0.0-main-20230706110436":"2023-07-06T11:05:42.399Z","0.0.0-main-20230706111131":"2023-07-06T11:12:34.821Z","0.0.0-main-20230706134710":"2023-07-06T13:48:25.611Z","0.0.0-indexing-20230707130424":"2023-07-07T13:05:53.405Z","0.0.0-main-20230711112802":"2023-07-11T11:29:06.960Z","0.0.0-main-20230712123334":"2023-07-12T12:34:40.573Z","0.0.0-main-20230712164118":"2023-07-12T16:42:36.651Z","0.0.0-main-20230713085937":"2023-07-13T09:00:42.737Z","0.0.0-main-20230713090002":"2023-07-13T09:01:07.207Z","0.0.0-main-20230713104632":"2023-07-13T10:47:34.187Z","2.0.0-main-0d434816":"2023-07-13T14:49:55.324Z","2.0.0-indexing-7e4f029f":"2023-07-13T15:26:22.121Z","2.0.0-main-8d51a034":"2023-07-13T15:50:41.556Z","2.0.0-main-db19ea39":"2023-07-13T16:30:09.006Z","2.0.0-main-184d5b52":"2023-07-13T17:53:58.252Z","2.0.0-main-c36ffd13":"2023-07-13T18:39:33.083Z","2.0.0-main-de2245b6":"2023-07-14T10:51:12.964Z","2.0.0-main-78b3b1de":"2023-07-14T10:53:26.513Z","2.0.0-main-e9258dae":"2023-07-14T10:54:27.684Z","2.0.0-main-a7b30c79":"2023-07-18T10:32:25.456Z","2.0.0-main-1e2ad78e":"2023-07-18T10:34:08.554Z","2.0.0-main-48909d15":"2023-07-18T10:34:51.457Z","2.0.0-main-4e4a3415":"2023-07-18T10:49:35.170Z","2.0.0-main-708122b7":"2023-07-18T11:04:04.924Z","2.0.0-main-b0a1a727":"2023-07-18T13:33:13.370Z","2.0.0-main-b38f2df1":"2023-07-18T14:00:50.849Z","2.0.0-main-9cdcd02e":"2023-07-18T14:13:23.706Z","2.0.0-main-f03531d9":"2023-07-18T17:57:39.190Z","2.0.0-main-4bb7e8cb":"2023-07-19T08:04:29.660Z","2.0.0-main-df85e0c0":"2023-07-19T08:47:40.745Z","2.0.0-indexing-1d07fea9":"2023-07-19T13:17:02.797Z","2.0.0-main-53522998":"2023-07-19T15:11:12.808Z","2.0.0-main-0c4f9fea":"2023-07-19T15:12:38.626Z","2.0.0-main-eeb15cc0":"2023-07-19T16:24:56.769Z","2.0.0-main-353b9aa2":"2023-07-20T14:57:01.578Z","2.0.0-main-6de86f16":"2023-07-21T07:35:30.324Z","2.0.0-main-69a96f10":"2023-07-21T09:53:22.481Z","2.0.0-next.0":"2023-07-21T14:47:37.908Z","2.0.0-indexing-3b1f31fc":"2023-07-25T13:47:48.972Z","2.0.0-indexing-3fee14a7":"2023-07-26T18:05:13.502Z","2.0.0-main-70e4d8eb":"2023-07-27T18:11:35.521Z","2.0.0-main-e259ef79":"2023-07-28T09:57:09.652Z","2.0.0-main-5e9eb5a7":"2023-07-28T10:18:24.652Z","2.0.0-main-8dc847d4":"2023-07-28T10:24:49.126Z","2.0.0-main-c963b46c":"2023-07-28T14:35:03.179Z","2.0.0-main-168a4cb4":"2023-07-28T14:47:27.767Z","2.0.0-main-16d8c43e":"2023-07-31T08:01:55.608Z","2.0.0-main-b24502cb":"2023-07-31T11:15:31.917Z","2.0.0-main-9e5baf4f":"2023-07-31T12:13:28.778Z","2.0.0-main-2f6cfef9":"2023-07-31T17:43:41.757Z","2.0.0-main-d89431db":"2023-08-01T16:06:14.540Z","2.0.0-main-7fb0dadf":"2023-08-01T18:28:58.509Z","2.0.0-main-57a52608":"2023-08-03T15:58:14.599Z","2.0.0-main-131c63e5":"2023-08-03T17:04:11.277Z","2.0.0-main-c1d2249b":"2023-08-03T17:16:11.600Z","2.0.0-main-582388ba":"2023-08-03T17:30:59.859Z","2.0.0-main-8fcd82ed":"2023-08-03T17:49:01.081Z","2.0.0-main-5c965a91":"2023-08-03T18:15:54.802Z","2.0.0-main-a0df37b1":"2023-08-03T19:53:27.182Z","2.0.0-main-6cc49119":"2023-08-03T20:25:14.474Z","2.0.0-main-f741ae8c":"2023-08-04T11:13:42.567Z","2.0.0-main-081f57b3":"2023-08-04T11:23:59.518Z","2.0.0-main-3fb9ce28":"2023-08-04T14:57:58.381Z","2.0.0-main-b6c8f3db":"2023-08-04T17:39:39.501Z","2.0.0-main-cc2c8da0":"2023-08-06T06:46:16.340Z","2.0.0-main-1af2f495":"2023-08-06T20:18:21.263Z","2.0.0-main-8318f172":"2023-08-07T09:25:03.679Z","2.0.0-main-cf4dab67":"2023-08-07T13:19:36.393Z","2.0.0-main-d62e76d2":"2023-08-07T16:21:53.266Z","2.0.0-main-8bd2a6d3":"2023-08-07T17:07:46.123Z","2.0.0-main-0d8cdad9":"2023-08-08T17:50:53.324Z","2.0.0-main-6c673325":"2023-08-09T11:52:11.682Z","2.0.0-main-a434d1af":"2023-08-09T12:03:26.089Z","2.0.0-main-512831bf":"2023-08-09T12:07:35.282Z","2.0.0-main-09464e9f":"2023-08-09T12:36:44.736Z","2.0.0-main-cd5abcc3":"2023-08-09T13:05:31.220Z","2.0.0-main-e826a6df":"2023-08-09T13:32:13.140Z","2.0.0-main-98909586":"2023-08-09T14:06:16.979Z","2.0.0-main-6071163f":"2023-08-09T14:29:35.322Z","2.0.0-main-233d3255":"2023-08-09T15:31:09.144Z","2.0.0-main-3f8124e0":"2023-08-09T15:48:45.570Z","2.0.0-main-9a7c9009":"2023-08-09T16:54:12.278Z","2.0.0-main-35c9f33d":"2023-08-09T18:13:19.491Z","2.0.0-main-267605a0":"2023-08-09T21:02:30.168Z","2.0.0-next.1":"2023-08-09T21:06:27.797Z","2.0.0-main-788de8de":"2023-08-09T21:07:08.106Z","2.0.0-main-48c51b52":"2023-08-11T14:28:18.109Z","2.0.0-main-a2588116":"2023-08-11T19:36:52.151Z","2.0.0-main-cca3b462":"2023-08-13T09:08:49.640Z","2.0.0-main-8e753bfb":"2023-08-13T09:11:24.991Z","2.0.0-main-939916bc":"2023-08-14T13:39:48.630Z","2.0.0-main-83d9589f":"2023-08-14T16:59:02.965Z","2.0.0-main-753bdce4":"2023-08-15T11:42:56.689Z","2.0.0-main-5294a7d5":"2023-08-15T11:44:50.778Z","2.0.0-main-b8a6158d":"2023-08-15T15:23:20.884Z","2.0.0-main-b621fb97":"2023-08-15T16:45:51.207Z","2.0.0-next.2":"2023-08-15T16:52:38.089Z","2.0.0-main-5e744f29":"2023-08-15T16:54:28.884Z","2.0.0-main-162ca7d3":"2023-08-16T08:33:54.324Z"},"maintainers":[{"name":"alvarius","email":"alvarius@lattice.xyz"},{"name":"andriidski","email":"andriidski@gmail.com"},{"name":"holic","email":"kingersoll@gmail.com"},{"name":"l_udens","email":"ludens@0xparc.org"}],"description":"This package includes general low level utilities to interact with Ethereum contracts, as well as specialized MUD contract/client sync utilities.","homepage":"https://github.com/latticexyz/mud#readme","repository":{"type":"git","url":"git+https://github.com/latticexyz/mud.git","directory":"packages/network"},"bugs":{"url":"https://github.com/latticexyz/mud/issues"},"license":"MIT","readme":"","readmeFilename":""}