Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(store): add foundation for v2 data model (#352)
Browse files Browse the repository at this point in the history
* feat(solecs): wip prototype for new data model core library

* feat(solecs): wip data model - add getData and split

* feat(solecs): wip data model - add StoreSwitch lib

* feat(solecs): wip data model - add Vec2Table and tests

* feat(solecs): wip data model - improve gas for slice/get

* feat(solecs): wip data model - add SystemTable and tests

* feat(solecs): wip data model - add World and end-to-end tests

* refactor(solecs): wip data model - rename schemas and tables

* refactor(solecs): wip data model - convert bytes without copying

* feat(solecs): wip data model - add more efficient packing methods

* refactor(solecs): wip data model - change function names and schema representation

* feat(solecs): wip data model - add logic to set partial word

* feat(solecs): wip data model - add low level buffer library

* feat(solecs): wip data model - add low level storage library

* refactor(solecs): wip data model - use Storage lib in StoreCore

* refactor(solecs): wip data model - change schema encoding and naming

* feat(solecs): wip data model - add logic and tests to set and get dynamic data length

* feat(solecs): wip data model - add logic and tests to read and write dynamic data

* feat(solecs): wip data model - add logic and test to set and get individual fields

* test(solecs): wip data model - add fuzzy test for Storage lib

* test(solecs): wip data model - add fuzzy tests for Buffer and Bytes

* feat(solecs): wip data model - add validity checks for registering schemas

* feat(solecs): wip data model - move schema and packed counter to own library/types

* refactor(solecs): wip data model - add different events for setting record, field and delete

* refactor(solecs): wip data model - make encoded dynamic lengths part of the bytes blob

* test(solecs): wip data model - add mixed table with dynamic data schema

* feat(cli): add gas report command

* test(solecs): wip data model - refactor buffer and bytes tests to use mud gas report

* test(solecs): wip data model - add test for gas cost of custom encoding vs abi encode

* feat(solecs): wip data model - add CallbackArray schema and tests, refactor typed lib definitions

* feat(solecs): wip data model - add indexer functionality

* feat(solecs): wip data model - add registerOnUpdateHook to interface

* feat(store): move store core source into own package outside of solecs

* build(store): add -rf to dist command to override existing files

* test(store): generate gasreport

* build(store): fix CI, add gas report action

* build(store): update gas report action name

* refactor(store): use setRecord instead of setStaticData

* build(store): add mud cli as dev dependency

* build(store): update forge-std and ds-test dependencies

* chore(store): use forge-std Test, remove ds-test dependency, fix gas-report command

* build(store): bring back ds-test bc forge-std actually needs it

* build: use local mud cli in gasreport action

* build: gas report action - install cli dependencies before building

* build: gas report action - move cli linking action after general building

* build: gas report action - force gh to use local cli

* fix(store): remove sneaked in temp test file

* build(store): fix push for gas report action

* feat(store): add onDelete hook, rename IOnUpdateHooks to IStoreHooks, make naming consistent

* build(store): add explicit commit author for gas report action

* refactor(store): prefix store events with Mud

* build: fix gasreport detached head

* refactor(store): rename IStoreHooks to IStoreHook

* refactor(store): rename Schema_ to SchemaLib, PackedCounter_ to PackedCounterLib

* build(store): different way to solve gas report action detached head issue

* refactor(store): more consistency for error naming

* build: fix gas report action

* refactor: rename gas report action

* refactor: hopefully actually fix gas report action

* refactor(store): move StoreCore internal functions to StoreCoreInternal

* refactor(store): rename write to store and read to load in Storage and Memory

* build: another attempt at fixing the gas report action

* test: update gas report

* refactor(store): move test out of src

* test: update gas report

* refactor(store): use named params for Storage and Memory lib calls, reorder params

* test: update gas report

* refactor(store): use abi.encodePacked for fixed length types instead of bytes.concat

* test: update gas report

* refactor(core): change argument name of registerHook

* fix(cli): support gas-report with lines including quotes

* chore: remove unnecessary conversion methods for primitive types

* chore(store): remove unused code

* refactor: use uint256 in PackedCounter accumulator

* chore: change setting of schema length bytes

* fix: don't reset dynamic data when deleting storage value but only length

* chore: update comments

* chore: move _getStaticData into the correct section

* chore: remove misleading comment

* chore: remove comment

* chore: remove comment

* test: update gas report

---------

Co-authored-by: alvrs <[email protected]>
alvrs and alvrs authored Feb 7, 2023
1 parent 09b77a7 commit 9ed6f2a
Showing 60 changed files with 9,183 additions and 0 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/gasreport.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# .github/workflows/gasreport.yml
name: Gas report

on:
pull_request:
paths:
- packages/store/**

jobs:
gas-report:
runs-on: ubuntu-22.04
name: Generate gas report
steps:
- uses: actions/setup-node@v3
with:
node-version: 16

- name: git-checkout
uses: actions/checkout@v3

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Install dependencies
run: yarn install --network-concurrency 1

- name: Install local CLI
run: cd packages/cli && yarn build && npm link && cd ../..

- name: Run gas report
run: yarn workspace @latticexyz/store run gasreport

- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: "test: update gas report"
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
"packages": [
"packages/utils",
"packages/solecs",
"packages/store",
"packages/cli",
"packages/recs",
"packages/react",
10 changes: 10 additions & 0 deletions packages/store/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cache
abi
out
types/ethers-contracts
docs
_docs
DOCS.md
artifacts
yarn-error.log
API
7 changes: 7 additions & 0 deletions packages/store/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*

!abi/**
!src/**
!types/**
!package.json
!README.md
1 change: 1 addition & 0 deletions packages/store/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
17
7 changes: 7 additions & 0 deletions packages/store/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"printWidth": 120,
"semi": true,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true
}
8 changes: 8 additions & 0 deletions packages/store/.solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "solhint:recommended",
"rules": {
"compiler-version": ["error", ">=0.8.0"],
"avoid-low-level-calls": "off",
"func-visibility": ["warn", { "ignoreConstructors": true }]
}
}
4 changes: 4 additions & 0 deletions packages/store/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Change Log

All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
1 change: 1 addition & 0 deletions packages/store/CHANGELOG.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
label: Changelog
1 change: 1 addition & 0 deletions packages/store/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Store
9 changes: 9 additions & 0 deletions packages/store/foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[profile.default]
ffi = false
fuzz_runs = 256
optimizer = true
optimizer_runs = 1000000
verbosity = 1
libs = ["../../node_modules"]
src = "src"
out = "out"
112 changes: 112 additions & 0 deletions packages/store/gas-report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
(test/Buffer.t.sol) | allocate a buffer [Buffer buf = Buffer_.allocate(32)]: 73
(test/Buffer.t.sol) | get buffer length [buf.length()]: 87
(test/Buffer.t.sol) | get buffer pointer [buf.ptr()]: 33
(test/Buffer.t.sol) | get buffer capacity [buf.capacity()]: 7
(test/Buffer.t.sol) | append unchecked bytes memory (8) to buffer [buf.appendUnchecked(data1)]: 478
(test/Buffer.t.sol) | append bytes memory (8) to buffer [buf.append(data2)]: 773
(test/Buffer.t.sol) | append unchecked bytes8 of bytes32 to buffer [buf.appendUnchecked(data1, 8)]: 351
(test/Buffer.t.sol) | append bytes8 of bytes32 to buffer [buf.append(data2, 8)]: 645
(test/Buffer.t.sol) | concat 3 bytes memory (32) using buffer [Buffer buf = Buffer_.concat(data1, data2, data3)]: 2638
(test/Buffer.t.sol) | concat 3 bytes memory (32) using bytes.concat [bytes memory concat = bytes.concat(data1, data2, data3)]: 641
(test/Buffer.t.sol) | concat 3 bytes memory (32) using abi.encodePacked [bytes memory concat2 = abi.encodePacked(data1, data2, data3)]: 641
(test/Buffer.t.sol) | create a buffer from 8 bytes [Buffer buf = Buffer_.fromBytes(data)]: 40
(test/Buffer.t.sol) | read bytes32 from buffer [bytes32 value = buf.read32(4)]: 102
(test/Buffer.t.sol) | read bytes8 with offset 3 from buffer [bytes8 value2 = buf.read8(3)]: 151
(test/Buffer.t.sol) | read bytes1 with offset 7 from buffer [bytes1 value3 = buf.read1(7)]: 151
(test/Buffer.t.sol) | set buffer length unchecked [buf._setLengthUnchecked(8)]: 86
(test/Buffer.t.sol) | set buffer length [buf._setLength(16)]: 192
(test/Buffer.t.sol) | slice 4 bytes from buffer with offset 4 [bytes memory slice = buf.slice(4, 4)]: 635
(test/Buffer.t.sol) | convert array pointer to uint256[] [uint256[] memory arr = Cast.toUint256Array(arrayPtr)]: 10
(test/Buffer.t.sol) | buffer toArray with element length 4 [uint256 arrayPtr = buf.toArray(4)]: 745
(test/Buffer.t.sol) | convert array pointer to uint32[] [uint32[] memory arr = Cast.toUint32Array(arrayPtr)]: 10
(test/Buffer.t.sol) | buffer (32 bytes) to bytes memory [bytes memory bufferData = buf.toBytes()]: 90
(test/Bytes.t.sol) | compare equal bytes [bool equals = Bytes.equals(a, b)]: 202
(test/Bytes.t.sol) | compare unequal bytes [bool equals = Bytes.equals(a, b)]: 202
(test/Bytes.t.sol) | create uint32 array from bytes memory [uint32[] memory output = Bytes.toUint32Array(tight)]: 835
(test/Bytes.t.sol) | create bytes from bytes array [bytes memory output = Bytes.from(input)]: 1290
(test/Bytes.t.sol) | create bytes from uint16 array [bytes memory output = Bytes.from(input)]: 791
(test/Bytes.t.sol) | create bytes from uint32 array [bytes memory output = Bytes.from(input)]: 695
(test/Bytes.t.sol) | create bytes from uint8 array [bytes memory output = Bytes.from(input)]: 695
(test/Bytes.t.sol) | set bytes1 in bytes32 [Bytes.setBytes1(input, 8, 0xff)]: 7
(test/Bytes.t.sol) | set bytes2 in bytes32 [Bytes.setBytes2(input, 8, 0xffff)]: 7
(test/Bytes.t.sol) | set bytes4 in bytes32 [Bytes.setBytes4(input, 8, 0xffffffff)]: 7
(test/Bytes.t.sol) | slice bytes (with copying) with offset 1 and length 3 [bytes memory b = Bytes.slice(a, 1, 3)]: 516
(test/Bytes.t.sol) | slice bytes3 with offset 1 [bytes3 b = Bytes.slice3(a, 1)]: 77
(test/Bytes.t.sol) | slice bytes32 with offset 10 [bytes32 output = Bytes.slice32(input, 10)]: 74
(test/Bytes.t.sol) | tightly pack bytes24 array into bytes array [bytes memory tight = Bytes.from(input)]: 477
(test/Bytes.t.sol) | create uint32 array from bytes memory [bytes24[] memory output = Bytes.toBytes24Array(tight)]: 614
(test/Bytes.t.sol) | create bytes32 from bytes memory with offset 0 [bytes32 output = Bytes.toBytes32(input, 0)]: 22
(test/Bytes.t.sol) | create bytes32 array from bytes memory [bytes32[] memory output = Bytes.toBytes32Array(input)]: 1110
(test/Bytes.t.sol) | create bytes32 array from bytes memory with uneven length [bytes32[] memory output = Bytes.toBytes32Array(input)]: 1425
(test/Bytes.t.sol) | create bytes32 from bytes memory with offset 16 [bytes32 output = Bytes.toBytes32(input, 16)]: 22
(test/Gas.t.sol) | abi encode [bytes memory abiEncoded = abi.encode(mixed)]: 930
(test/Gas.t.sol) | abi decode [Mixed memory abiDecoded = abi.decode(abiEncoded, (Mixed))]: 1713
(test/Gas.t.sol) | custom encode [bytes memory customEncoded = customEncode(mixed)]: 1393
(test/Gas.t.sol) | custom decode [Mixed memory customDecoded = customDecode(customEncoded)]: 2772
(test/Gas.t.sol) | pass abi encoded bytes to external contract [someContract.doSomethingWithBytes(abiEncoded)]: 6537
(test/Gas.t.sol) | pass custom encoded bytes to external contract [someContract.doSomethingWithBytes(customEncoded)]: 1342
(test/MixedTable.t.sol) | store Mixed struct in storage (native solidity) [testMixed = mixed]: 92016
(test/MixedTable.t.sol) | register MixedTable schema [MixedTable.registerSchema()]: 32496
(test/MixedTable.t.sol) | set record in MixedTable [MixedTable.set({ key: key, u32: 1, u128: 2, a32: a32, s: s })]: 114455
(test/MixedTable.t.sol) | get record from MixedTable [Mixed memory mixed = MixedTable.get(key)]: 20471
(test/PackedCounter.t.sol) | get value at index of PackedCounter [packedCounter.atIndex(3)]: 272
(test/PackedCounter.t.sol) | set value at index of PackedCounter [packedCounter = packedCounter.setAtIndex(2, 5)]: 830
(test/PackedCounter.t.sol) | pack uint16 array into PackedCounter [PackedCounter packedCounter = PackedCounterLib.pack(counters)]: 2148
(test/PackedCounter.t.sol) | get total of PackedCounter [packedCounter.total()]: 33
(test/RouteTable.t.sol) | register RouteTable schema [RouteTable.registerSchema()]: 30440
(test/RouteTable.t.sol) | set RouteTable record [RouteTable.set(key, addr, selector, executionMode)]: 35240
(test/RouteTable.t.sol) | get RouteTable record [Route memory systemEntry = RouteTable.get(key)]: 6554
(test/Schema.t.sol) | encode schema with 6 entries [SchemaLib.encode]: 6172
(test/Schema.t.sol) | get schema type at index [SchemaType schemaType1 = schema.atIndex(0)]: 200
(test/Schema.t.sol) | get number of dynamic fields from schema [uint256 num = schema.numDynamicFields()]: 80
(test/Schema.t.sol) | get number of static fields from schema [uint256 num = schema.numStaticFields()]: 91
(test/Schema.t.sol) | get static data length from schema [uint256 length = schema.staticDataLength()]: 39
(test/Schema.t.sol) | check if schema is empty (non-empty schema) [bool empty = encodedSchema.isEmpty()]: 13
(test/Schema.t.sol) | check if schema is empty (empty schema) [bool empty = encodedSchema.isEmpty()]: 13
(test/Schema.t.sol) | validate schema [encodedSchema.validate()]: 22716
(test/Storage.t.sol) | store 1 storage slot [Storage.store({ storagePointer: storagePointer, data: originalDataFirstSlot })]: 23449
(test/Storage.t.sol) | store 34 bytes over 3 storage slots (with offset and safeTrail)) [Storage.store({ storagePointer: storagePointer, offset: 31, data: data1 })]: 25604
(test/Storage.t.sol) | load 34 bytes over 3 storage slots (with offset and safeTrail)) [bytes memory data = Storage.load({ storagePointer: storagePointer, length: 34, offset: 31 })]: 4131
(test/StoreCore.t.sol) | access non-existing record [bytes memory data1 = StoreCore.getRecord(table, key)]: 10090
(test/StoreCore.t.sol) | access static field of non-existing record [bytes memory data2 = StoreCore.getField(table, key, 0)]: 4505
(test/StoreCore.t.sol) | access dynamic field of non-existing record [bytes memory data3 = StoreCore.getField(table, key, 1)]: 3940
(test/StoreCore.t.sol) | delete record (complex data, 3 slots) [StoreCore.deleteRecord(table, key)]: 10970
(test/StoreCore.t.sol) | Check for existence of table (existent) [StoreCore.hasTable(table)]: 992
(test/StoreCore.t.sol) | check for existence of table (non-existent) [StoreCore.hasTable(table2)]: 2993
(test/StoreCore.t.sol) | register subscriber [StoreCore.registerHook(table, subscriber)]: 70323
(test/StoreCore.t.sol) | set record on table with subscriber [StoreCore.setRecord(table, key, data)]: 72168
(test/StoreCore.t.sol) | set static field on table with subscriber [StoreCore.setField(table, key, 0, data)]: 34254
(test/StoreCore.t.sol) | delete record on table with subscriber [StoreCore.deleteRecord(table, key)]: 24678
(test/StoreCore.t.sol) | register subscriber [StoreCore.registerHook(table, subscriber)]: 70323
(test/StoreCore.t.sol) | set (dynamic) record on table with subscriber [StoreCore.setRecord(table, key, data)]: 174918
(test/StoreCore.t.sol) | set (dynamic) field on table with subscriber [StoreCore.setField(table, key, 1, arrayDataBytes)]: 37025
(test/StoreCore.t.sol) | delete (dynamic) record on table with subscriber [StoreCore.deleteRecord(table, key)]: 30425
(test/StoreCore.t.sol) | StoreCore: register schema [StoreCore.registerSchema(table, schema)]: 26419
(test/StoreCore.t.sol) | StoreCore: get schema (warm) [Schema loadedSchema = StoreCore.getSchema(table)]: 937
(test/StoreCore.t.sol) | set complex record with dynamic data (4 slots) [StoreCore.setRecord(table, key, data)]: 110652
(test/StoreCore.t.sol) | get complex record with dynamic data (4 slots) [bytes memory loadedData = StoreCore.getRecord(table, key)]: 12755
(test/StoreCore.t.sol) | compare: Set complex record with dynamic data using native solidity [testStruct = _testStruct]: 116815
(test/StoreCore.t.sol) | compare: Set complex record with dynamic data using abi.encode [testMapping[1234] = abi.encode(_testStruct)]: 267529
(test/StoreCore.t.sol) | set dynamic length of dynamic index 0 [StoreCoreInternal._setDynamicDataLengthAtIndex(table, key, 0, 10)]: 23676
(test/StoreCore.t.sol) | set dynamic length of dynamic index 1 [StoreCoreInternal._setDynamicDataLengthAtIndex(table, key, 1, 99)]: 1777
(test/StoreCore.t.sol) | reduce dynamic length of dynamic index 0 [StoreCoreInternal._setDynamicDataLengthAtIndex(table, key, 0, 5)]: 1768
(test/StoreCore.t.sol) | set static field (1 slot) [StoreCore.setField(table, key, 0, abi.encodePacked(firstDataBytes))]: 38105
(test/StoreCore.t.sol) | get static field (1 slot) [bytes memory loadedData = StoreCore.getField(table, key, 0)]: 4592
(test/StoreCore.t.sol) | set static field (overlap 2 slot) [StoreCore.setField(table, key, 1, abi.encodePacked(secondDataBytes))]: 33895
(test/StoreCore.t.sol) | get static field (overlap 2 slot) [loadedData = StoreCore.getField(table, key, 1)]: 6375
(test/StoreCore.t.sol) | set dynamic field (1 slot, first dynamic field) [StoreCore.setField(table, key, 2, thirdDataBytes)]: 57377
(test/StoreCore.t.sol) | get dynamic field (1 slot, first dynamic field) [loadedData = StoreCore.getField(table, key, 2)]: 5357
(test/StoreCore.t.sol) | set dynamic field (1 slot, second dynamic field) [StoreCore.setField(table, key, 3, fourthDataBytes)]: 35511
(test/StoreCore.t.sol) | get dynamic field (1 slot, second dynamic field) [loadedData = StoreCore.getField(table, key, 3)]: 5372
(test/StoreCore.t.sol) | set static record (1 slot) [StoreCore.setRecord(table, key, data)]: 34136
(test/StoreCore.t.sol) | get static record (1 slot) [bytes memory loadedData = StoreCore.getRecord(table, key, schema)]: 4102
(test/StoreCore.t.sol) | set static record (2 slots) [StoreCore.setRecord(table, key, data)]: 56691
(test/StoreCore.t.sol) | get static record (2 slots) [bytes memory loadedData = StoreCore.getRecord(table, key, schema)]: 4991
(test/StoreSwitch.t.sol) | check if delegatecall [isDelegate = StoreSwitch.isDelegateCall()]: 671
(test/StoreSwitch.t.sol) | check if delegatecall [isDelegate = StoreSwitch.isDelegateCall()]: 627
(test/System.t.sol) | extract msg.sender from calldata [address sender = _msgSender()]: 24
(test/Vector2Table.t.sol) | register Vector2Table schema [Vector2Table.registerSchema()]: 28673
(test/Vector2Table.t.sol) | set Vector2Table record [Vector2Table.set({ key: key, x: 1, y: 2 })]: 35206
(test/Vector2Table.t.sol) | get Vector2Table record [Vector2 memory vector = Vector2Table.get(key)]: 6440
(test/World.t.sol) | call autonomous system via World contract [WorldWithWorldTestSystem(address(world)).WorldTestSystem_move(entity, 1, 2)]: 45511
(test/World.t.sol) | call delegate system via World contract [WorldWithWorldTestSystem(address(world)).WorldTestSystem_move(entity, 1, 2)]: 43376
5 changes: 5 additions & 0 deletions packages/store/git-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#! usr/bin/bash
giturl=https://github.com/$1.git
head=$(git ls-remote $giturl HEAD | head -n1 | awk '{print $1;}')
yarn add $giturl#$head
echo "Installed $giturl#$head"
23 changes: 23 additions & 0 deletions packages/store/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { HardhatUserConfig } from "hardhat/config";
import "./tasks/compile";
import "solidity-docgen";

const config: HardhatUserConfig = {
paths: {
sources: "./src",
},
solidity: {
version: "0.8.13",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
docgen: {
outputDir: "API",
},
};

export default config;
1 change: 1 addition & 0 deletions packages/store/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
2 changes: 2 additions & 0 deletions packages/store/index.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
label: store
order: 50
48 changes: 48 additions & 0 deletions packages/store/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "@latticexyz/store",
"license": "MIT",
"version": "1.33.1",
"description": "Store",
"types": "./types/ethers-contracts/",
"repository": {
"type": "git",
"url": "https://github.com/latticexyz/mud.git",
"directory": "packages/store"
},
"scripts": {
"prepare": "yarn build && chmod u+x git-install.sh",
"git:install": "bash git-install.sh",
"test": "forge test",
"build": "rimraf out && forge build --out out && yarn dist && yarn types",
"dist": "rimraf abi && mkdir abi && cp -rf out/*.sol/*.json abi/ && yarn rimraf abi/*.metadata.json",
"types": "rimraf types && typechain --target=ethers-v5 abi/*.json",
"prettier": "prettier --write 'src/**/*.sol'",
"solhint": "solhint --config ./.solhint.json 'src/**/*.sol'",
"lint": "yarn prettier && yarn solhint",
"link": "yarn link",
"docs": "rimraf API && hardhat docgen && echo 'label: API\norder: 50' > API/index.yml",
"release": "npm publish || echo 'version already published'",
"gasreport": " ../cli/dist/index.js gas-report --path test/** --save gas-report.txt"
},
"devDependencies": {
"@typechain/ethers-v5": "^9.0.0",
"@types/mocha": "^9.1.1",
"ds-test": "https://github.com/dapphub/ds-test.git#c9ce3f25bde29fc5eb9901842bf02850dfd2d084",
"forge-std": "https://github.com/foundry-rs/forge-std.git#f36dab24d63d1c1945a05ed375ce341d3c1a49ed",
"hardhat": "^2.10.1",
"prettier": "^2.6.2",
"prettier-plugin-solidity": "^1.0.0-beta.19",
"rimraf": "^3.0.2",
"solhint": "^3.3.7",
"solidity-docgen": "^0.6.0-beta.22",
"ts-node": "10.7",
"typechain": "^8.1.1",
"typedoc": "^0.23.10",
"@latticexyz/cli": "^1.34.0"
},
"peerDependencies": {
"ds-test": "https://github.com/dapphub/ds-test.git#c9ce3f25bde29fc5eb9901842bf02850dfd2d084",
"forge-std": "https://github.com/foundry-rs/forge-std.git#f36dab24d63d1c1945a05ed375ce341d3c1a49ed"
},
"gitHead": "218f56893d268b0c5157a3e4c603b859e287a343"
}
2 changes: 2 additions & 0 deletions packages/store/remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ds-test/=../../node_modules/ds-test/src/
forge-std/=../../node_modules/forge-std/src/
Loading

0 comments on commit 9ed6f2a

Please sign in to comment.