Skip to content

Commit

Permalink
feat(store): add getRecord and getStaticDataLocation helpers (#3430)
Browse files Browse the repository at this point in the history
  • Loading branch information
holic authored Jan 8, 2025
1 parent 2d2aa08 commit 1b477d4
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/sharp-lions-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@latticexyz/store": patch
---

Added internal `getRecord` and `getStaticDataLocation` helpers.
2 changes: 1 addition & 1 deletion packages/protocol-parser/src/getKeyTuple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ type PartialTable = Pick<Table, "schema" | "key">;

export type getKeyTuple<table extends PartialTable, key extends readonly unknown[] = table["key"]> = {
[i in keyof key]: Hex;
};
} & unknown;

export function getKeyTuple<const table extends PartialTable>(
table: table,
Expand Down
2 changes: 2 additions & 0 deletions packages/store/ts/exports/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ export * from "../common";
export * from "../getStoreLogs";
export * from "../flattenStoreLogs";
export * from "../logToRecord";
export * from "../getRecord";
export * from "../getStaticDataLocation";

export * from "../config/v2/codegen";
export * from "../config/v2/defaults";
Expand Down
78 changes: 78 additions & 0 deletions packages/store/ts/getRecord.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Address, Client, Hex } from "viem";
import { Table } from "@latticexyz/config";
import {
decodeValueArgs,
getKeySchema,
getKeyTuple,
getSchemaPrimitives,
getSchemaTypes,
getValueSchema,
} from "@latticexyz/protocol-parser/internal";
import { readContract } from "viem/actions";
import { getAction } from "viem/utils";

export type GetRecordOptions<table extends Table> = {
address: Address;
table: table;
key: getSchemaPrimitives<getKeySchema<table>>;
blockTag?: "latest" | "pending";
};

export async function getRecord<table extends Table>(
client: Client,
{ address, table, key, blockTag }: GetRecordOptions<table>,
): Promise<getSchemaPrimitives<table["schema"]>> {
const [staticData, encodedLengths, dynamicData] = await getAction(
client,
readContract,
"readContract",
)({
address,
abi,
functionName: "getRecord",
args: [table.tableId, getKeyTuple(table, key) as readonly Hex[]],
blockTag,
});

return {
...key,
...decodeValueArgs(getSchemaTypes(getValueSchema(table)), { staticData, encodedLengths, dynamicData }),
};
}

const abi = [
{
type: "function",
name: "getRecord",
inputs: [
{
name: "tableId",
type: "bytes32",
internalType: "ResourceId",
},
{
name: "keyTuple",
type: "bytes32[]",
internalType: "bytes32[]",
},
],
outputs: [
{
name: "staticData",
type: "bytes",
internalType: "bytes",
},
{
name: "encodedLengths",
type: "bytes32",
internalType: "EncodedLengths",
},
{
name: "dynamicData",
type: "bytes",
internalType: "bytes",
},
],
stateMutability: "view",
},
] as const;
10 changes: 10 additions & 0 deletions packages/store/ts/getStaticDataLocation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Hex, concatHex, hexToBigInt, keccak256, numberToHex, toBytes } from "viem";

// TODO: move to protocol-parser?
// equivalent of StoreCore._getStaticDataLocation

const SLOT = hexToBigInt(keccak256(toBytes("mud.store")));

export function getStaticDataLocation(tableId: Hex, keyTuple: readonly Hex[]): Hex {
return numberToHex(SLOT ^ hexToBigInt(keccak256(concatHex([tableId, ...keyTuple]))), { size: 32 });
}

0 comments on commit 1b477d4

Please sign in to comment.