@latticexyz/world-modules 2.0.12-main-ecc8f658 → 2.0.12-type-resolutions-effc7ab1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cache/solidity-files-cache.json +1 -0
- package/dist/mud.config.d.ts +0 -2
- package/package.json +9 -9
- package/src/index.sol +0 -25
- package/src/interfaces/IBaseWorld.sol +0 -16
- package/src/interfaces/IERC20System.sol +0 -33
- package/src/interfaces/IERC721System.sol +0 -43
- package/src/interfaces/IPuppetFactorySystem.sol +0 -15
- package/src/interfaces/IUniqueEntitySystem.sol +0 -13
- package/src/interfaces/IUnstable_CallWithSignatureSystem.sol +0 -20
- package/src/modules/callwithsignature/ECDSA.sol +0 -174
- package/src/modules/callwithsignature/IERC1271.sol +0 -17
- package/src/modules/callwithsignature/IUnstable_CallWithSignatureErrors.sol +0 -9
- package/src/modules/callwithsignature/SignatureChecker.sol +0 -50
- package/src/modules/callwithsignature/Unstable_CallWithSignatureModule.sol +0 -48
- package/src/modules/callwithsignature/Unstable_CallWithSignatureSystem.sol +0 -36
- package/src/modules/callwithsignature/constants.sol +0 -10
- package/src/modules/callwithsignature/getSignedMessageHash.sol +0 -54
- package/src/modules/callwithsignature/tables/CallWithSignatureNonces.sol +0 -199
- package/src/modules/callwithsignature/validateCallWithSignature.sol +0 -31
- package/src/modules/erc20-puppet/ERC20Module.sol +0 -88
- package/src/modules/erc20-puppet/ERC20System.sol +0 -286
- package/src/modules/erc20-puppet/IERC20.sol +0 -94
- package/src/modules/erc20-puppet/IERC20Errors.sol +0 -49
- package/src/modules/erc20-puppet/IERC20Events.sol +0 -18
- package/src/modules/erc20-puppet/IERC20Mintable.sol +0 -25
- package/src/modules/erc20-puppet/constants.sol +0 -20
- package/src/modules/erc20-puppet/registerERC20.sol +0 -35
- package/src/modules/erc20-puppet/tables/Allowances.sol +0 -208
- package/src/modules/erc20-puppet/tables/ERC20Metadata.sol +0 -604
- package/src/modules/erc20-puppet/tables/ERC20Registry.sol +0 -199
- package/src/modules/erc20-puppet/tables/TotalSupply.sol +0 -184
- package/src/modules/erc20-puppet/utils.sol +0 -30
- package/src/modules/erc721-puppet/ERC721Module.sol +0 -95
- package/src/modules/erc721-puppet/ERC721System.sol +0 -531
- package/src/modules/erc721-puppet/IERC721.sol +0 -120
- package/src/modules/erc721-puppet/IERC721Errors.sol +0 -61
- package/src/modules/erc721-puppet/IERC721Events.sol +0 -23
- package/src/modules/erc721-puppet/IERC721Metadata.sol +0 -27
- package/src/modules/erc721-puppet/IERC721Mintable.sol +0 -53
- package/src/modules/erc721-puppet/IERC721Receiver.sol +0 -28
- package/src/modules/erc721-puppet/constants.sol +0 -23
- package/src/modules/erc721-puppet/libraries/LibString.sol +0 -77
- package/src/modules/erc721-puppet/registerERC721.sol +0 -37
- package/src/modules/erc721-puppet/tables/ERC721Metadata.sol +0 -703
- package/src/modules/erc721-puppet/tables/ERC721Registry.sol +0 -199
- package/src/modules/erc721-puppet/tables/OperatorApproval.sol +0 -220
- package/src/modules/erc721-puppet/tables/Owners.sol +0 -196
- package/src/modules/erc721-puppet/tables/TokenApproval.sol +0 -196
- package/src/modules/erc721-puppet/tables/TokenURI.sol +0 -450
- package/src/modules/erc721-puppet/utils.sol +0 -38
- package/src/modules/keysintable/KeysInTableHook.sol +0 -141
- package/src/modules/keysintable/KeysInTableModule.sol +0 -110
- package/src/modules/keysintable/constants.sol +0 -7
- package/src/modules/keysintable/getKeysInTable.sol +0 -81
- package/src/modules/keysintable/hasKey.sol +0 -28
- package/src/modules/keysintable/query.sol +0 -200
- package/src/modules/keysintable/tables/KeysInTable.sol +0 -1638
- package/src/modules/keysintable/tables/UsedKeysIndex.sol +0 -414
- package/src/modules/keyswithvalue/KeysWithValueHook.sol +0 -158
- package/src/modules/keyswithvalue/KeysWithValueModule.sol +0 -103
- package/src/modules/keyswithvalue/constants.sol +0 -7
- package/src/modules/keyswithvalue/getKeysWithValue.sol +0 -58
- package/src/modules/keyswithvalue/getTargetTableId.sol +0 -32
- package/src/modules/keyswithvalue/tables/KeysWithValue.sol +0 -668
- package/src/modules/puppet/Puppet.sol +0 -80
- package/src/modules/puppet/PuppetDelegationControl.sol +0 -17
- package/src/modules/puppet/PuppetFactorySystem.sol +0 -25
- package/src/modules/puppet/PuppetMaster.sol +0 -19
- package/src/modules/puppet/PuppetModule.sol +0 -64
- package/src/modules/puppet/constants.sol +0 -23
- package/src/modules/puppet/createPuppet.sol +0 -24
- package/src/modules/puppet/tables/PuppetRegistry.sol +0 -199
- package/src/modules/puppet/utils.sol +0 -10
- package/src/modules/std-delegations/CallboundDelegationControl.sol +0 -64
- package/src/modules/std-delegations/StandardDelegationsModule.sol +0 -55
- package/src/modules/std-delegations/SystemboundDelegationControl.sol +0 -54
- package/src/modules/std-delegations/TimeboundDelegationControl.sol +0 -27
- package/src/modules/std-delegations/constants.sol +0 -21
- package/src/modules/std-delegations/tables/CallboundDelegations.sol +0 -287
- package/src/modules/std-delegations/tables/SystemboundDelegations.sol +0 -256
- package/src/modules/std-delegations/tables/TimeboundDelegations.sol +0 -211
- package/src/modules/tokens/tables/Balances.sol +0 -196
- package/src/modules/uniqueentity/UniqueEntityModule.sol +0 -73
- package/src/modules/uniqueentity/UniqueEntitySystem.sol +0 -18
- package/src/modules/uniqueentity/constants.sol +0 -13
- package/src/modules/uniqueentity/getUniqueEntity.sol +0 -26
- package/src/modules/uniqueentity/tables/UniqueEntity.sol +0 -238
- package/src/modules/utils/ArrayLib.sol +0 -55
- package/src/utils/AccessControlLib.sol +0 -55
- package/src/utils/SystemSwitch.sol +0 -80
@@ -1,141 +0,0 @@
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
2
|
-
pragma solidity >=0.8.24;
|
3
|
-
|
4
|
-
import { EncodedLengths } from "@latticexyz/store/src/EncodedLengths.sol";
|
5
|
-
import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol";
|
6
|
-
import { StoreHook } from "@latticexyz/store/src/StoreHook.sol";
|
7
|
-
import { ResourceId } from "@latticexyz/store/src/ResourceId.sol";
|
8
|
-
|
9
|
-
import { KeysInTable } from "./tables/KeysInTable.sol";
|
10
|
-
import { UsedKeysIndex } from "./tables/UsedKeysIndex.sol";
|
11
|
-
|
12
|
-
/**
|
13
|
-
* Note: if a table with composite keys is used, only the first five keys of the tuple are indexed
|
14
|
-
*/
|
15
|
-
contract KeysInTableHook is StoreHook {
|
16
|
-
function handleSet(ResourceId tableId, bytes32[] memory keyTuple) internal {
|
17
|
-
bytes32 keysHash = keccak256(abi.encode(keyTuple));
|
18
|
-
|
19
|
-
// If the keyTuple has not yet been set in the table...
|
20
|
-
if (!UsedKeysIndex.getHas(tableId, keysHash)) {
|
21
|
-
uint40 length = uint40(KeysInTable.lengthKeys0(tableId));
|
22
|
-
|
23
|
-
// Push the keyTuple to the list of keys in this table
|
24
|
-
if (keyTuple.length > 0) {
|
25
|
-
KeysInTable.pushKeys0(tableId, keyTuple[0]);
|
26
|
-
if (keyTuple.length > 1) {
|
27
|
-
KeysInTable.pushKeys1(tableId, keyTuple[1]);
|
28
|
-
if (keyTuple.length > 2) {
|
29
|
-
KeysInTable.pushKeys2(tableId, keyTuple[2]);
|
30
|
-
if (keyTuple.length > 3) {
|
31
|
-
KeysInTable.pushKeys3(tableId, keyTuple[3]);
|
32
|
-
if (keyTuple.length > 4) {
|
33
|
-
KeysInTable.pushKeys4(tableId, keyTuple[4]);
|
34
|
-
}
|
35
|
-
}
|
36
|
-
}
|
37
|
-
}
|
38
|
-
}
|
39
|
-
|
40
|
-
// Update the index to avoid duplicating this keyTuple in the array
|
41
|
-
UsedKeysIndex.set(tableId, keysHash, true, length);
|
42
|
-
}
|
43
|
-
}
|
44
|
-
|
45
|
-
function onBeforeSetRecord(
|
46
|
-
ResourceId tableId,
|
47
|
-
bytes32[] memory keyTuple,
|
48
|
-
bytes memory,
|
49
|
-
EncodedLengths,
|
50
|
-
bytes memory,
|
51
|
-
FieldLayout
|
52
|
-
) public override {
|
53
|
-
handleSet(tableId, keyTuple);
|
54
|
-
}
|
55
|
-
|
56
|
-
function onAfterSpliceStaticData(
|
57
|
-
ResourceId tableId,
|
58
|
-
bytes32[] memory keyTuple,
|
59
|
-
uint48,
|
60
|
-
bytes memory
|
61
|
-
) public override {
|
62
|
-
handleSet(tableId, keyTuple);
|
63
|
-
}
|
64
|
-
|
65
|
-
function onAfterSpliceDynamicData(
|
66
|
-
ResourceId tableId,
|
67
|
-
bytes32[] memory keyTuple,
|
68
|
-
uint8,
|
69
|
-
uint40,
|
70
|
-
uint40,
|
71
|
-
EncodedLengths,
|
72
|
-
bytes memory
|
73
|
-
) public override {
|
74
|
-
handleSet(tableId, keyTuple);
|
75
|
-
}
|
76
|
-
|
77
|
-
function onBeforeDeleteRecord(ResourceId tableId, bytes32[] memory keyTuple, FieldLayout) public override {
|
78
|
-
bytes32 keysHash = keccak256(abi.encode(keyTuple));
|
79
|
-
(bool has, uint40 index) = UsedKeysIndex.get(tableId, keysHash);
|
80
|
-
|
81
|
-
// If the keyTuple was part of the table...
|
82
|
-
if (has) {
|
83
|
-
// Delete the index as the keyTuple is not in the table anymore
|
84
|
-
UsedKeysIndex.deleteRecord(tableId, keysHash);
|
85
|
-
|
86
|
-
uint40 length = uint40(KeysInTable.lengthKeys0(tableId));
|
87
|
-
|
88
|
-
if (length == 1) {
|
89
|
-
// Delete the list of keys in this table
|
90
|
-
KeysInTable.deleteRecord(tableId);
|
91
|
-
} else {
|
92
|
-
if (keyTuple.length > 0) {
|
93
|
-
bytes32[] memory lastKeyTuple = new bytes32[](keyTuple.length);
|
94
|
-
|
95
|
-
bytes32 lastKey = KeysInTable.getItemKeys0(tableId, length - 1);
|
96
|
-
lastKeyTuple[0] = lastKey;
|
97
|
-
|
98
|
-
// Remove the keyTuple from the list of keys in this table
|
99
|
-
KeysInTable.updateKeys0(tableId, index, lastKey);
|
100
|
-
KeysInTable.popKeys0(tableId);
|
101
|
-
|
102
|
-
if (keyTuple.length > 1) {
|
103
|
-
lastKey = KeysInTable.getItemKeys1(tableId, length - 1);
|
104
|
-
lastKeyTuple[1] = lastKey;
|
105
|
-
|
106
|
-
KeysInTable.updateKeys1(tableId, index, lastKey);
|
107
|
-
KeysInTable.popKeys1(tableId);
|
108
|
-
|
109
|
-
if (keyTuple.length > 2) {
|
110
|
-
lastKey = KeysInTable.getItemKeys2(tableId, length - 1);
|
111
|
-
lastKeyTuple[2] = lastKey;
|
112
|
-
|
113
|
-
KeysInTable.updateKeys2(tableId, index, lastKey);
|
114
|
-
KeysInTable.popKeys2(tableId);
|
115
|
-
|
116
|
-
if (keyTuple.length > 3) {
|
117
|
-
lastKey = KeysInTable.getItemKeys3(tableId, length - 1);
|
118
|
-
lastKeyTuple[3] = lastKey;
|
119
|
-
|
120
|
-
KeysInTable.updateKeys3(tableId, index, lastKey);
|
121
|
-
KeysInTable.popKeys3(tableId);
|
122
|
-
|
123
|
-
if (keyTuple.length > 4) {
|
124
|
-
lastKey = KeysInTable.getItemKeys4(tableId, length - 1);
|
125
|
-
lastKeyTuple[4] = lastKey;
|
126
|
-
|
127
|
-
KeysInTable.updateKeys4(tableId, index, lastKey);
|
128
|
-
KeysInTable.popKeys4(tableId);
|
129
|
-
}
|
130
|
-
}
|
131
|
-
}
|
132
|
-
}
|
133
|
-
|
134
|
-
// Update the index of lastKeyTuple after swapping it with the deleted keyTuple
|
135
|
-
bytes32 lastKeyHash = keccak256(abi.encode(lastKeyTuple));
|
136
|
-
UsedKeysIndex.setIndex(tableId, lastKeyHash, index);
|
137
|
-
}
|
138
|
-
}
|
139
|
-
}
|
140
|
-
}
|
141
|
-
}
|
@@ -1,110 +0,0 @@
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
2
|
-
pragma solidity >=0.8.24;
|
3
|
-
|
4
|
-
import { BEFORE_SET_RECORD, AFTER_SPLICE_STATIC_DATA, AFTER_SPLICE_DYNAMIC_DATA, BEFORE_DELETE_RECORD } from "@latticexyz/store/src/storeHookTypes.sol";
|
5
|
-
import { ResourceIds } from "@latticexyz/store/src/codegen/tables/ResourceIds.sol";
|
6
|
-
|
7
|
-
import { Module } from "@latticexyz/world/src/Module.sol";
|
8
|
-
|
9
|
-
import { IBaseWorld } from "@latticexyz/world/src/codegen/interfaces/IBaseWorld.sol";
|
10
|
-
import { InstalledModules } from "@latticexyz/world/src/codegen/index.sol";
|
11
|
-
|
12
|
-
import { ResourceId, WorldResourceIdInstance } from "@latticexyz/world/src/WorldResourceId.sol";
|
13
|
-
import { revertWithBytes } from "@latticexyz/world/src/revertWithBytes.sol";
|
14
|
-
|
15
|
-
import { KeysInTableHook } from "./KeysInTableHook.sol";
|
16
|
-
import { KeysInTable } from "./tables/KeysInTable.sol";
|
17
|
-
import { UsedKeysIndex } from "./tables/UsedKeysIndex.sol";
|
18
|
-
|
19
|
-
/**
|
20
|
-
* This module deploys a hook that is called when a value is set in the `sourceTableId`
|
21
|
-
* provided in the install methods arguments. The hook keeps track of the keys that are in a given table.
|
22
|
-
* This mapping is stored in a global table that is registered when the module is first installed.
|
23
|
-
*
|
24
|
-
* Note: if a table with composite keys is used, only the first key is indexed
|
25
|
-
*
|
26
|
-
* Note: this module currently only supports `installRoot` (via `World.installRootModule`).
|
27
|
-
* TODO: add support for `install` (via `World.installModule`) by using `callFrom` with the `msgSender()`
|
28
|
-
*/
|
29
|
-
contract KeysInTableModule is Module {
|
30
|
-
using WorldResourceIdInstance for ResourceId;
|
31
|
-
|
32
|
-
// The KeysInTableHook is deployed once and infers the target table id
|
33
|
-
// from the source table id (passed as argument to the hook methods)
|
34
|
-
KeysInTableHook private immutable hook = new KeysInTableHook();
|
35
|
-
|
36
|
-
function installRoot(bytes memory encodedArgs) public override {
|
37
|
-
// Naive check to ensure this is only installed once
|
38
|
-
// TODO: only revert if there's nothing to do
|
39
|
-
requireNotInstalled(__self, encodedArgs);
|
40
|
-
|
41
|
-
// Extract source table id from args
|
42
|
-
ResourceId sourceTableId = ResourceId.wrap(abi.decode(encodedArgs, (bytes32)));
|
43
|
-
|
44
|
-
IBaseWorld world = IBaseWorld(_world());
|
45
|
-
|
46
|
-
// Initialize variable to reuse in low level calls
|
47
|
-
bool success;
|
48
|
-
bytes memory returnData;
|
49
|
-
|
50
|
-
if (!ResourceIds._getExists(KeysInTable._tableId)) {
|
51
|
-
// Register the tables
|
52
|
-
(success, returnData) = address(world).delegatecall(
|
53
|
-
abi.encodeCall(
|
54
|
-
world.registerTable,
|
55
|
-
(
|
56
|
-
KeysInTable._tableId,
|
57
|
-
KeysInTable._fieldLayout,
|
58
|
-
KeysInTable._keySchema,
|
59
|
-
KeysInTable._valueSchema,
|
60
|
-
KeysInTable.getKeyNames(),
|
61
|
-
KeysInTable.getFieldNames()
|
62
|
-
)
|
63
|
-
)
|
64
|
-
);
|
65
|
-
if (!success) revertWithBytes(returnData);
|
66
|
-
|
67
|
-
(success, returnData) = address(world).delegatecall(
|
68
|
-
abi.encodeCall(
|
69
|
-
world.registerTable,
|
70
|
-
(
|
71
|
-
UsedKeysIndex._tableId,
|
72
|
-
UsedKeysIndex._fieldLayout,
|
73
|
-
UsedKeysIndex._keySchema,
|
74
|
-
UsedKeysIndex._valueSchema,
|
75
|
-
UsedKeysIndex.getKeyNames(),
|
76
|
-
UsedKeysIndex.getFieldNames()
|
77
|
-
)
|
78
|
-
)
|
79
|
-
);
|
80
|
-
if (!success) revertWithBytes(returnData);
|
81
|
-
|
82
|
-
// Grant the hook access to the tables
|
83
|
-
(success, returnData) = address(world).delegatecall(
|
84
|
-
abi.encodeCall(world.grantAccess, (KeysInTable._tableId, address(hook)))
|
85
|
-
);
|
86
|
-
if (!success) revertWithBytes(returnData);
|
87
|
-
|
88
|
-
(success, returnData) = address(world).delegatecall(
|
89
|
-
abi.encodeCall(world.grantAccess, (UsedKeysIndex._tableId, address(hook)))
|
90
|
-
);
|
91
|
-
if (!success) revertWithBytes(returnData);
|
92
|
-
}
|
93
|
-
|
94
|
-
// Register a hook that is called when a value is set in the source table
|
95
|
-
(success, returnData) = address(world).delegatecall(
|
96
|
-
abi.encodeCall(
|
97
|
-
world.registerStoreHook,
|
98
|
-
(
|
99
|
-
sourceTableId,
|
100
|
-
hook,
|
101
|
-
BEFORE_SET_RECORD | AFTER_SPLICE_STATIC_DATA | AFTER_SPLICE_DYNAMIC_DATA | BEFORE_DELETE_RECORD
|
102
|
-
)
|
103
|
-
)
|
104
|
-
);
|
105
|
-
}
|
106
|
-
|
107
|
-
function install(bytes memory) public pure {
|
108
|
-
revert Module_NonRootInstallNotSupported();
|
109
|
-
}
|
110
|
-
}
|
@@ -1,7 +0,0 @@
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
2
|
-
pragma solidity >=0.8.24;
|
3
|
-
|
4
|
-
// Limiting the module namespace to 8 bytes so the last 8 bytes
|
5
|
-
// can be used for an identifier of the source table namespace to avoid
|
6
|
-
// collisions between tables with the same name in different namespaces
|
7
|
-
bytes8 constant MODULE_NAMESPACE = "keystab";
|
@@ -1,81 +0,0 @@
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
2
|
-
pragma solidity >=0.8.24;
|
3
|
-
|
4
|
-
import { IStore } from "@latticexyz/store/src/IStore.sol";
|
5
|
-
import { Schema } from "@latticexyz/store/src/Schema.sol";
|
6
|
-
import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol";
|
7
|
-
import { ResourceId } from "@latticexyz/store/src/ResourceId.sol";
|
8
|
-
|
9
|
-
import { KeysInTable } from "./tables/KeysInTable.sol";
|
10
|
-
|
11
|
-
/**
|
12
|
-
* Get a list of keys in the given table.
|
13
|
-
*
|
14
|
-
* Note: this util can only be called within the context of a Store (e.g. from a System or Module).
|
15
|
-
* For usage outside of a Store, use the overload that takes an explicit store argument.
|
16
|
-
*/
|
17
|
-
function getKeysInTable(ResourceId tableId) view returns (bytes32[][] memory keyTuples) {
|
18
|
-
/**
|
19
|
-
* Note: this module only supports up to 5 composite keys.
|
20
|
-
*/
|
21
|
-
|
22
|
-
Schema keySchema = StoreSwitch.getKeySchema(tableId);
|
23
|
-
uint256 numFields = keySchema.numFields();
|
24
|
-
uint256 length = KeysInTable.lengthKeys0(tableId);
|
25
|
-
keyTuples = new bytes32[][](length);
|
26
|
-
|
27
|
-
for (uint256 i; i < length; i++) {
|
28
|
-
keyTuples[i] = new bytes32[](numFields); // the length of the key tuple depends on the key schema
|
29
|
-
|
30
|
-
if (numFields > 0) {
|
31
|
-
keyTuples[i][0] = KeysInTable.getItemKeys0(tableId, i);
|
32
|
-
if (numFields > 1) {
|
33
|
-
keyTuples[i][1] = KeysInTable.getItemKeys1(tableId, i);
|
34
|
-
if (numFields > 2) {
|
35
|
-
keyTuples[i][2] = KeysInTable.getItemKeys2(tableId, i);
|
36
|
-
if (numFields > 3) {
|
37
|
-
keyTuples[i][3] = KeysInTable.getItemKeys3(tableId, i);
|
38
|
-
if (numFields > 4) {
|
39
|
-
keyTuples[i][4] = KeysInTable.getItemKeys4(tableId, i);
|
40
|
-
}
|
41
|
-
}
|
42
|
-
}
|
43
|
-
}
|
44
|
-
}
|
45
|
-
}
|
46
|
-
}
|
47
|
-
|
48
|
-
/**
|
49
|
-
* Get a list of keys in the given table for the given store.
|
50
|
-
*/
|
51
|
-
function getKeysInTable(IStore store, ResourceId tableId) view returns (bytes32[][] memory keyTuples) {
|
52
|
-
/**
|
53
|
-
* Note: this module only supports up to 5 composite keys.
|
54
|
-
*/
|
55
|
-
|
56
|
-
Schema keySchema = store.getKeySchema(tableId);
|
57
|
-
|
58
|
-
uint256 numFields = keySchema.numFields();
|
59
|
-
uint256 length = KeysInTable.lengthKeys0(store, tableId);
|
60
|
-
keyTuples = new bytes32[][](length);
|
61
|
-
|
62
|
-
for (uint256 i; i < length; i++) {
|
63
|
-
keyTuples[i] = new bytes32[](numFields); // the length of the key tuple depends on the key schema
|
64
|
-
|
65
|
-
if (numFields > 0) {
|
66
|
-
keyTuples[i][0] = KeysInTable.getItemKeys0(store, tableId, i);
|
67
|
-
if (numFields > 1) {
|
68
|
-
keyTuples[i][1] = KeysInTable.getItemKeys1(store, tableId, i);
|
69
|
-
if (numFields > 2) {
|
70
|
-
keyTuples[i][2] = KeysInTable.getItemKeys2(store, tableId, i);
|
71
|
-
if (numFields > 3) {
|
72
|
-
keyTuples[i][3] = KeysInTable.getItemKeys3(store, tableId, i);
|
73
|
-
if (numFields > 4) {
|
74
|
-
keyTuples[i][4] = KeysInTable.getItemKeys4(store, tableId, i);
|
75
|
-
}
|
76
|
-
}
|
77
|
-
}
|
78
|
-
}
|
79
|
-
}
|
80
|
-
}
|
81
|
-
}
|
@@ -1,28 +0,0 @@
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
2
|
-
pragma solidity >=0.8.24;
|
3
|
-
|
4
|
-
import { IStore } from "@latticexyz/store/src/IStore.sol";
|
5
|
-
import { ResourceId } from "@latticexyz/store/src/ResourceId.sol";
|
6
|
-
|
7
|
-
import { UsedKeysIndex } from "./tables/UsedKeysIndex.sol";
|
8
|
-
|
9
|
-
/**
|
10
|
-
* Get whether the keyTuple is in the given table.
|
11
|
-
*
|
12
|
-
* Note: this util can only be called within the context of a Store (e.g. from a System or Module).
|
13
|
-
* For usage outside of a Store, use the overload that takes an explicit store argument.
|
14
|
-
*/
|
15
|
-
function hasKey(ResourceId tableId, bytes32[] memory keyTuple) view returns (bool) {
|
16
|
-
bytes32 keysHash = keccak256(abi.encode(keyTuple));
|
17
|
-
|
18
|
-
return UsedKeysIndex.getHas(tableId, keysHash);
|
19
|
-
}
|
20
|
-
|
21
|
-
/**
|
22
|
-
* Get whether the keyTuple is in the given table for the given store.
|
23
|
-
*/
|
24
|
-
function hasKey(IStore store, ResourceId tableId, bytes32[] memory keyTuple) view returns (bool) {
|
25
|
-
bytes32 keysHash = keccak256(abi.encode(keyTuple));
|
26
|
-
|
27
|
-
return UsedKeysIndex.getHas(store, tableId, keysHash);
|
28
|
-
}
|
@@ -1,200 +0,0 @@
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
2
|
-
pragma solidity >=0.8.24;
|
3
|
-
|
4
|
-
import { IStore } from "@latticexyz/store/src/IStore.sol";
|
5
|
-
import { EncodedLengths } from "@latticexyz/store/src/EncodedLengths.sol";
|
6
|
-
import { ResourceId } from "@latticexyz/store/src/ResourceId.sol";
|
7
|
-
|
8
|
-
import { getKeysInTable } from "./getKeysInTable.sol";
|
9
|
-
import { getKeysWithValue } from "../keyswithvalue/getKeysWithValue.sol";
|
10
|
-
import { ArrayLib } from "../utils/ArrayLib.sol";
|
11
|
-
|
12
|
-
enum QueryType {
|
13
|
-
Has,
|
14
|
-
Not,
|
15
|
-
HasValue,
|
16
|
-
NotValue
|
17
|
-
}
|
18
|
-
|
19
|
-
struct QueryFragment {
|
20
|
-
QueryType queryType;
|
21
|
-
ResourceId tableId;
|
22
|
-
bytes value;
|
23
|
-
}
|
24
|
-
|
25
|
-
function valuesToTuples(bytes32[] memory flatArr) pure returns (bytes32[][] memory arr) {
|
26
|
-
arr = new bytes32[][](flatArr.length);
|
27
|
-
for (uint256 i; i < flatArr.length; i++) {
|
28
|
-
arr[i] = new bytes32[](1);
|
29
|
-
arr[i][0] = flatArr[i];
|
30
|
-
}
|
31
|
-
}
|
32
|
-
|
33
|
-
/**
|
34
|
-
* Helper function to check whether a given key passes a given query fragment.
|
35
|
-
*
|
36
|
-
* Note: this util can only be called within the context of a Store (e.g. from a System or Module).
|
37
|
-
* For usage outside of a Store, use the overload that takes an explicit store argument.
|
38
|
-
*
|
39
|
-
* @param keyTuple Key to check.
|
40
|
-
* @param fragment Query fragment to check.
|
41
|
-
*/
|
42
|
-
function passesQueryFragment(bytes32[] memory keyTuple, QueryFragment memory fragment) view returns (bool) {
|
43
|
-
if (fragment.queryType == QueryType.Has) {
|
44
|
-
// Key must be in given table
|
45
|
-
return ArrayLib.includes(getKeysInTable(fragment.tableId), keyTuple);
|
46
|
-
}
|
47
|
-
|
48
|
-
if (fragment.queryType == QueryType.HasValue) {
|
49
|
-
// Key must have the given value
|
50
|
-
return
|
51
|
-
ArrayLib.includes(
|
52
|
-
valuesToTuples(
|
53
|
-
getKeysWithValue(fragment.tableId, fragment.value, EncodedLengths.wrap(bytes32(0)), new bytes(0))
|
54
|
-
),
|
55
|
-
keyTuple
|
56
|
-
);
|
57
|
-
}
|
58
|
-
|
59
|
-
if (fragment.queryType == QueryType.Not) {
|
60
|
-
// Key must not be in given table
|
61
|
-
return !ArrayLib.includes(getKeysInTable(fragment.tableId), keyTuple);
|
62
|
-
}
|
63
|
-
|
64
|
-
if (fragment.queryType == QueryType.NotValue) {
|
65
|
-
// Key must not have the given value
|
66
|
-
return
|
67
|
-
!ArrayLib.includes(
|
68
|
-
valuesToTuples(
|
69
|
-
getKeysWithValue(fragment.tableId, fragment.value, EncodedLengths.wrap(bytes32(0)), new bytes(0))
|
70
|
-
),
|
71
|
-
keyTuple
|
72
|
-
);
|
73
|
-
}
|
74
|
-
|
75
|
-
return false;
|
76
|
-
}
|
77
|
-
|
78
|
-
/**
|
79
|
-
* Helper function to check whether a given key passes a given query fragment.
|
80
|
-
* @param keyTuple Key to check.
|
81
|
-
* @param fragment Query fragment to check.
|
82
|
-
*/
|
83
|
-
function passesQueryFragment(
|
84
|
-
IStore store,
|
85
|
-
bytes32[] memory keyTuple,
|
86
|
-
QueryFragment memory fragment
|
87
|
-
) view returns (bool) {
|
88
|
-
if (fragment.queryType == QueryType.Has) {
|
89
|
-
// Key must be in given table
|
90
|
-
return ArrayLib.includes(getKeysInTable(store, fragment.tableId), keyTuple);
|
91
|
-
}
|
92
|
-
|
93
|
-
if (fragment.queryType == QueryType.HasValue) {
|
94
|
-
// Key must be have the given value
|
95
|
-
return
|
96
|
-
ArrayLib.includes(
|
97
|
-
valuesToTuples(
|
98
|
-
getKeysWithValue(store, fragment.tableId, fragment.value, EncodedLengths.wrap(bytes32(0)), new bytes(0))
|
99
|
-
),
|
100
|
-
keyTuple
|
101
|
-
);
|
102
|
-
}
|
103
|
-
|
104
|
-
if (fragment.queryType == QueryType.Not) {
|
105
|
-
// Key must not be in given table
|
106
|
-
return !ArrayLib.includes(getKeysInTable(store, fragment.tableId), keyTuple);
|
107
|
-
}
|
108
|
-
|
109
|
-
if (fragment.queryType == QueryType.NotValue) {
|
110
|
-
// Key must not have the given value
|
111
|
-
return
|
112
|
-
!ArrayLib.includes(
|
113
|
-
valuesToTuples(
|
114
|
-
getKeysWithValue(store, fragment.tableId, fragment.value, EncodedLengths.wrap(bytes32(0)), new bytes(0))
|
115
|
-
),
|
116
|
-
keyTuple
|
117
|
-
);
|
118
|
-
}
|
119
|
-
|
120
|
-
return false;
|
121
|
-
}
|
122
|
-
|
123
|
-
/**
|
124
|
-
* Execute the given query and return a list of keys
|
125
|
-
* The first fragment should be Has or HasValue
|
126
|
-
*
|
127
|
-
* Note: this util can only be called within the context of a Store (e.g. from a System or Module).
|
128
|
-
* For usage outside of a Store, use the overload that takes an explicit store argument.
|
129
|
-
*
|
130
|
-
* @param fragments List of query fragments to execute
|
131
|
-
* @return keyTuples List of keys matching the query
|
132
|
-
*/
|
133
|
-
function query(QueryFragment[] memory fragments) view returns (bytes32[][] memory keyTuples) {
|
134
|
-
// Create the first interim result
|
135
|
-
keyTuples = fragments[0].queryType == QueryType.Has
|
136
|
-
? getKeysInTable(fragments[0].tableId)
|
137
|
-
: valuesToTuples(
|
138
|
-
getKeysWithValue(fragments[0].tableId, fragments[0].value, EncodedLengths.wrap(bytes32(0)), new bytes(0))
|
139
|
-
);
|
140
|
-
|
141
|
-
for (uint256 i = 1; i < fragments.length; i++) {
|
142
|
-
bytes32[][] memory result = new bytes32[][](0);
|
143
|
-
|
144
|
-
for (uint256 j; j < keyTuples.length; j++) {
|
145
|
-
bool passes = passesQueryFragment(keyTuples[j], fragments[i]);
|
146
|
-
if (passes) {
|
147
|
-
// Increase the length of result array and add the new key
|
148
|
-
uint256 length = result.length;
|
149
|
-
|
150
|
-
bytes32[][] memory newResult = new bytes32[][](length + 1);
|
151
|
-
for (uint256 k; k < length; k++) {
|
152
|
-
newResult[k] = result[k];
|
153
|
-
}
|
154
|
-
result = newResult;
|
155
|
-
|
156
|
-
result[length] = keyTuples[j];
|
157
|
-
}
|
158
|
-
}
|
159
|
-
|
160
|
-
keyTuples = result;
|
161
|
-
}
|
162
|
-
}
|
163
|
-
|
164
|
-
/**
|
165
|
-
* Execute the given query and return a list of keys
|
166
|
-
* The first fragment should be Has or HasValue
|
167
|
-
* @param fragments List of query fragments to execute
|
168
|
-
* @return keyTuples List of keys matching the query
|
169
|
-
*/
|
170
|
-
function query(IStore store, QueryFragment[] memory fragments) view returns (bytes32[][] memory keyTuples) {
|
171
|
-
// Create the first interim result
|
172
|
-
keyTuples = fragments[0].queryType == QueryType.Has
|
173
|
-
? getKeysInTable(store, fragments[0].tableId)
|
174
|
-
: valuesToTuples(
|
175
|
-
getKeysWithValue(store, fragments[0].tableId, fragments[0].value, EncodedLengths.wrap(bytes32(0)), new bytes(0))
|
176
|
-
);
|
177
|
-
|
178
|
-
for (uint256 i = 1; i < fragments.length; i++) {
|
179
|
-
bytes32[][] memory result = new bytes32[][](0);
|
180
|
-
|
181
|
-
for (uint256 j; j < keyTuples.length; j++) {
|
182
|
-
bool passes = passesQueryFragment(store, keyTuples[j], fragments[i]);
|
183
|
-
if (passes) {
|
184
|
-
// Increase the length of result array
|
185
|
-
uint256 length = result.length;
|
186
|
-
|
187
|
-
bytes32[][] memory newResult = new bytes32[][](length + 1);
|
188
|
-
for (uint256 k; k < length; k++) {
|
189
|
-
newResult[k] = result[k];
|
190
|
-
}
|
191
|
-
result = newResult;
|
192
|
-
|
193
|
-
// Append the new key
|
194
|
-
result[length] = keyTuples[j];
|
195
|
-
}
|
196
|
-
}
|
197
|
-
|
198
|
-
keyTuples = result;
|
199
|
-
}
|
200
|
-
}
|