Releases: latticexyz/mud
@latticexyz/[email protected]
@latticexyz/[email protected]
@latticexyz/[email protected]
@latticexyz/[email protected]
Patch Changes
- Updated dependencies [
92de5998
]:- @latticexyz/[email protected]
- @latticexyz/[email protected]
@latticexyz/[email protected]
Patch Changes
- Updated dependencies [
aea67c58
,07dd6f32
,90e4161b
,331dbfdc
,f9f9609e
,759514d8
,d5094a24
,de151fec
,ae340b2b
,211be2a1
,0f3e2e02
,d0878928
,83583a50
,5e723b90
,6573e38e
,44a5432a
,6e66c5b7
,65c9546c
,672d05ca
,63831a26
,92de5998
,22ee4470
,be313068
,ac508bf1
,bfcb293d
,1890f1a0
,9b43029c
,55ab88a6
,af639a26
,5e723b90
,99ab9cd6
,c049c23f
,80dd6992
,24a6cd53
,708b49c5
,22ba7b67
,cea754dd
]:- @latticexyz/[email protected]
- @latticexyz/[email protected]
@latticexyz/[email protected]
Major Changes
-
#1482
07dd6f32
Thanks @alvrs! - Renamed all occurrences ofschema
where it is used as "value schema" tovalueSchema
to clearly distinguish it from "key schema".
The only breaking change for users is the change fromschema
tovalueSchema
inmud.config.ts
.// mud.config.ts export default mudConfig({ tables: { CounterTable: { keySchema: {}, - schema: { + valueSchema: { value: "uint32", }, }, } }
-
#1354
331dbfdc
Thanks @dk1a! -readHex
was moved from@latticexyz/protocol-parser
to@latticexyz/common
Minor Changes
-
#1336
de151fec
Thanks @dk1a! - - AddFieldLayout
, which is abytes32
user-type similar toSchema
.Both
FieldLayout
andSchema
have the same kind of data in the first 4 bytes.- 2 bytes for total length of all static fields
- 1 byte for number of static size fields
- 1 byte for number of dynamic size fields
But whereas
Schema
hasSchemaType
enum in each of the other 28 bytes,FieldLayout
has static byte lengths in each of the other 28 bytes.-
Replace
Schema valueSchema
withFieldLayout fieldLayout
in Store and World contracts.FieldLayout
is more gas-efficient because it already has lengths, andSchema
has types which need to be converted to lengths. -
Add
getFieldLayout
toIStore
interface.There is no
FieldLayout
for keys, only for values, because key byte lengths aren't usually relevant on-chain. You can still usegetKeySchema
if you need key types. -
Add
fieldLayoutToHex
utility toprotocol-parser
package. -
Add
constants.sol
for constants shared betweenFieldLayout
,Schema
andPackedCounter
.
-
#1476
9ff4dd95
Thanks @holic! - AddsvalueSchemaToFieldLayoutHex
helper
Patch Changes
@latticexyz/[email protected]
Patch Changes
- Updated dependencies []:
- @latticexyz/[email protected]
@latticexyz/[email protected]
@latticexyz/[email protected]
@latticexyz/[email protected]
Minor Changes
-
#1517
9940fdb3
Thanks @holic! - New package to run your own faucet service. We'll use this soon for our testnet in place of@latticexyz/services
.To run the faucet server:
- Add the package with
pnpm add @latticexyz/faucet
- Add a
.env
file that has aRPC_HTTP_URL
andFAUCET_PRIVATE_KEY
(or pass the environment variables into the next command) - Run
pnpm faucet-server
to start the server
You can also adjust the server's
HOST
(defaults to0.0.0.0
) andPORT
(defaults to3002
). The tRPC routes are accessible under/trpc
.To connect a tRPC client, add the package with
pnpm add @latticexyz/faucet
and then usecreateClient
:import { createClient } from "@latticexyz/faucet"; const faucet = createClient({ url: "http://localhost:3002/trpc" }); await faucet.mutate.drip({ address: burnerAccount.address });
- Add the package with
Patch Changes
@latticexyz/[email protected]
Major Changes
-
#1354
331dbfdc
Thanks @dk1a! - We've updated Store events to be "schemaless", meaning there is enough information in each event to only need to operate on the bytes of each record to make an update to that record without having to first decode the record by its schema. This enables new kinds of indexers and sync strategies.As such, we've replaced
blockStorageOperations# @latticexyz/dev-tools with
storedBlockLogs# @latticexyz/dev-tools, a stream of simplified Store event logs after they've been synced to the configured storage adapter. These logs may not reflect exactly the events that are on chain when e.g. hydrating from an indexer, but they will still allow the client to "catch up" to the on-chain state of your tables.
Minor Changes
- #1497
24a0dd44
Thanks @y77cao! - Improved rendering of transactions that make calls via World'scall
andcallFrom
methods
Patch Changes
-
#1505
e0193e57
Thanks @holic! - Updates store eventkey
reference tokeyTuple
-
#1502
e0377761
Thanks @holic! - Updatestable
reference totableId
-
#1558
bfcb293d
Thanks @alvrs! - What used to be known asephemeral
table is now calledoffchain
table.
The previousephemeral
tables only supported anemitEphemeral
method, which emitted aStoreSetEphemeralRecord
event.Now
offchain
tables support all regular table methods, except partial operations on dynamic fields (push
,pop
,update
).
Unlike regular tables they don't store data on-chain but emit the same events as regular tables (StoreSetRecord
,StoreSpliceStaticData
,StoreDeleteRecord
), so their data can be indexed by offchain indexers/clients.- EphemeralTable.emitEphemeral(value); + OffchainTable.set(value);
-
#1577
af639a26
Thanks @alvrs! -Store
events have been renamed for consistency and readability.
If you're parsingStore
events manually, you need to update your ABI.
If you're using the MUD sync stack, the new events are already integrated and no further changes are necessary.- event StoreSetRecord( + event Store_SetRecord( ResourceId indexed tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData ); - event StoreSpliceStaticData( + event Store_SpliceStaticData( ResourceId indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data ); - event StoreSpliceDynamicData( + event Store_SpliceDynamicData( ResourceId indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths ); - event StoreDeleteRecord( + event Store_DeleteRecord( ResourceId indexed tableId, bytes32[] keyTuple );
-
#1581
cea754dd
Thanks @alvrs! - - The externalsetRecord
anddeleteRecord
methods ofIStore
no longer accept aFieldLayout
as input, but load it from storage instead.
This is to prevent invalidFieldLayout
values being passed, which could cause the onchain state to diverge from the indexer state.
However, the internalStoreCore
library still exposes asetRecord
anddeleteRecord
method that allows aFieldLayout
to be passed.
This is becauseStoreCore
can only be used internally, so theFieldLayout
value can be trusted and we can save the gas for accessing storage.interface IStore { function setRecord( ResourceId tableId, bytes32[] calldata keyTuple, bytes calldata staticData, PackedCounter encodedLengths, bytes calldata dynamicData, - FieldLayout fieldLayout ) external; function deleteRecord( ResourceId tableId, bytes32[] memory keyTuple, - FieldLayout fieldLayout ) external; }
-
The
spliceStaticData
method andStore_SpliceStaticData
event ofIStore
andStoreCore
no longer includedeleteCount
in their signature.
This is because when splicing static data, the data afterstart
is always overwritten withdata
instead of being shifted, sodeleteCount
is always the length of the data to be written.event Store_SpliceStaticData( ResourceId indexed tableId, bytes32[] keyTuple, uint48 start, - uint40 deleteCount, bytes data ); interface IStore { function spliceStaticData( ResourceId tableId, bytes32[] calldata keyTuple, uint48 start, - uint40 deleteCount, bytes calldata data ) external; }
-
The
updateInField
method has been removed fromIStore
, as it's almost identical to the more generalspliceDynamicData
.
If you're manually callingupdateInField
, here is how to upgrade tospliceDynamicData
:- store.updateInField(tableId, keyTuple, fieldIndex, startByteIndex, dataToSet, fieldLayout); + uint8 dynamicFieldIndex = fieldIndex - fieldLayout.numStaticFields(); + store.spliceDynamicData(tableId, keyTuple, dynamicFieldIndex, uint40(startByteIndex), uint40(dataToSet.length), dataToSet);
-
All other methods that are only valid for dynamic fields (
pushToField
,popFromField
,getFieldSlice
)
have been renamed to make this more explicit (pushToDynamicField
,popFromDynamicField
,getDynamicFieldSlice
).Their
fieldIndex
parameter has been replaced by adynamicFieldIndex
parameter, which is the index relative to the first dynamic field (i.e.dynamicFieldIndex
=fieldIndex
-numStaticFields
).
TheFieldLayout
parameter has been removed, as it was only used to calculate thedynamicFieldIndex
in the method.interface IStore { - function pushToField( + function pushToDynamicField( ResourceId tableId, bytes32[] calldata keyTuple, - uint8 fieldIndex, + uint8 dynamicFieldIndex, bytes calldata dataToPush, - FieldLayout fieldLayout ) external; - function popFromField( + function popFromDynamicField( ResourceId tableId, bytes32[] calldata keyTuple, - uint8 fieldIndex, + uint8 dynamicFieldIndex, uint256 byteLengthToPop, - FieldLayout fieldLayout ) external; - function getFieldSlice( + function getDynamicFieldSlice( ResourceId tableId, bytes32[] memory keyTuple, - uint8 fieldIndex, + uint8 dynamicFieldIndex, - FieldLayout fieldLayout, uint256 start, uint256 end ) external view returns (bytes memory data); }
-
IStore
has a newgetDynamicFieldLength
length method, which returns the byte length of the given dynamic field and doesn't require theFieldLayout
.IStore { + function getDynamicFieldLength( + ResourceId tableId, + bytes32[] memory keyTuple, + uint8 dynamicFieldIndex + ) external view returns (uint256); }
-
IStore
now has additional overloads forgetRecord
,getField
,getFieldLength
andsetField
that don't require aFieldLength
to be passed, but instead load it from storage. -
IStore
now exposessetStaticField
andsetDynamicField
to save gas by avoiding the dynamic inference of whether the field is static or dynamic. -
The
getDynamicFieldSlice
method no longer accepts reading outside the bounds of the dynamic field.
This is to avoid returning invalid data, as the data of a dynamic field is not deleted when the record is deleted, but only its length is set to zero.
-
-
Updated dependencies [
77dce993
,748f4588
,aea67c58
,07dd6f32
,c07fa021
,90e4161b
,65c9546c
,331dbfdc
, [f9f9609e
](https://github.com/lat...