-
Notifications
You must be signed in to change notification settings - Fork 193
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(cli): register labels as tags (#3063)
- Loading branch information
Showing
10 changed files
with
276 additions
and
147 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { Hex, Client, Transport, Chain, Account, stringToHex, BaseError } from "viem"; | ||
import { WorldDeploy } from "./common"; | ||
import { debug } from "./debug"; | ||
import { hexToResource, writeContract } from "@latticexyz/common"; | ||
import { identity, isDefined } from "@latticexyz/common/utils"; | ||
import metadataConfig from "@latticexyz/world-module-metadata/mud.config"; | ||
import metadataAbi from "@latticexyz/world-module-metadata/out/IMetadataSystem.sol/IMetadataSystem.abi.json" assert { type: "json" }; | ||
import { getRecord } from "./getRecord"; | ||
|
||
export type ResourceTag<value> = { | ||
resourceId: Hex; | ||
tag: string; | ||
value: value; | ||
}; | ||
|
||
export async function ensureResourceTags<const value>({ | ||
client, | ||
worldDeploy, | ||
tags, | ||
valueToHex = identity, | ||
}: { | ||
readonly client: Client<Transport, Chain | undefined, Account>; | ||
readonly worldDeploy: WorldDeploy; | ||
readonly tags: readonly ResourceTag<value>[]; | ||
} & (value extends Hex | ||
? { readonly valueToHex?: (value: value) => Hex } | ||
: { readonly valueToHex: (value: value) => Hex })): Promise<readonly Hex[]> { | ||
const pendingTags = ( | ||
await Promise.all( | ||
tags.map(async (tag) => { | ||
const { value } = await getRecord({ | ||
client, | ||
worldDeploy, | ||
table: metadataConfig.tables.metadata__ResourceTag, | ||
key: { resource: tag.resourceId, tag: stringToHex(tag.tag, { size: 32 }) }, | ||
}); | ||
if (value === valueToHex(tag.value)) return; | ||
return tag; | ||
}), | ||
) | ||
).filter(isDefined); | ||
|
||
if (pendingTags.length === 0) return []; | ||
|
||
debug("setting", pendingTags.length, "resource tags"); | ||
return ( | ||
await Promise.all( | ||
pendingTags.map(async (tag) => { | ||
const resource = hexToResource(tag.resourceId); | ||
// TODO: move to resourceToDebugString | ||
const resourceString = `${resource.type}:${resource.namespace}:${resource.name}`; | ||
debug(`tagging ${resourceString} with ${tag.tag}: ${JSON.stringify(tag.value)}`); | ||
try { | ||
return await writeContract(client, { | ||
chain: client.chain ?? null, | ||
address: worldDeploy.address, | ||
abi: metadataAbi, | ||
// TODO: replace with batchCall (https://github.com/latticexyz/mud/issues/1645) | ||
functionName: "metadata__setResourceTag", | ||
args: [tag.resourceId, stringToHex(tag.tag, { size: 32 }), valueToHex(tag.value)], | ||
}); | ||
} catch (error) { | ||
debug( | ||
`failed to set resource tag for ${resourceString}, skipping\n ${error instanceof BaseError ? error.shortMessage : error}`, | ||
); | ||
} | ||
}), | ||
) | ||
).filter(isDefined); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { | ||
decodeValueArgs, | ||
getKeySchema, | ||
getKeyTuple, | ||
getSchemaPrimitives, | ||
getSchemaTypes, | ||
getValueSchema, | ||
} from "@latticexyz/protocol-parser/internal"; | ||
import { WorldDeploy, worldAbi } from "./common"; | ||
import { Client, Hex } from "viem"; | ||
import { readContract } from "viem/actions"; | ||
import { Table } from "@latticexyz/config"; | ||
import { mapObject } from "@latticexyz/common/utils"; | ||
import { show } from "@ark/util"; | ||
|
||
export async function getRecord<table extends Table>({ | ||
client, | ||
worldDeploy, | ||
table, | ||
key, | ||
}: { | ||
readonly client: Client; | ||
readonly worldDeploy: WorldDeploy; | ||
readonly table: table; | ||
readonly key: getSchemaPrimitives<getKeySchema<table>>; | ||
}): Promise<show<getSchemaPrimitives<table["schema"]>>> { | ||
const [staticData, encodedLengths, dynamicData] = (await readContract(client, { | ||
blockNumber: worldDeploy.stateBlock, | ||
address: worldDeploy.address, | ||
abi: worldAbi, | ||
functionName: "getRecord", | ||
args: [table.tableId, getKeyTuple(table, key)], | ||
// TODO: remove cast once https://github.com/wevm/viem/issues/2125 is resolved | ||
// has something to do function overloads and TS having a hard time inferring which args to use | ||
})) as [Hex, Hex, Hex]; | ||
const record = { | ||
...key, | ||
...decodeValueArgs(getSchemaTypes(getValueSchema(table)), { | ||
staticData, | ||
encodedLengths, | ||
dynamicData, | ||
}), | ||
}; | ||
// return in schema order | ||
return mapObject(table.schema, (value, key) => record[key as never]) as never; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { describe, expect, it } from "vitest"; | ||
import { getKeyTuple } from "./getKeyTuple"; | ||
import { Table } from "@latticexyz/config"; | ||
|
||
type PartialTable = Pick<Table, "schema" | "key">; | ||
|
||
describe("getKeyTuple", () => { | ||
it("can encode bool key tuple", () => { | ||
const table = { | ||
schema: { id: { type: "bool", internalType: "bool" } }, | ||
key: ["id"], | ||
} as const satisfies PartialTable; | ||
|
||
expect(getKeyTuple(table, { id: false })).toStrictEqual([ | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
]); | ||
expect(getKeyTuple(table, { id: true })).toStrictEqual([ | ||
"0x0000000000000000000000000000000000000000000000000000000000000001", | ||
]); | ||
}); | ||
|
||
it("can encode complex key tuple", () => { | ||
const table = { | ||
schema: { | ||
a: { type: "uint256", internalType: "uint256" }, | ||
b: { type: "int32", internalType: "int32" }, | ||
c: { type: "bytes16", internalType: "bytes16" }, | ||
d: { type: "address", internalType: "address" }, | ||
e: { type: "bool", internalType: "bool" }, | ||
f: { type: "int8", internalType: "int8" }, | ||
}, | ||
key: ["a", "b", "c", "d", "e", "f"], | ||
} as const satisfies PartialTable; | ||
|
||
expect( | ||
getKeyTuple(table, { | ||
a: 42n, | ||
b: -42, | ||
c: "0x12340000000000000000000000000000", | ||
d: "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", | ||
e: true, | ||
f: 3, | ||
}), | ||
).toStrictEqual([ | ||
"0x000000000000000000000000000000000000000000000000000000000000002a", | ||
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd6", | ||
"0x1234000000000000000000000000000000000000000000000000000000000000", | ||
"0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff", | ||
"0x0000000000000000000000000000000000000000000000000000000000000001", | ||
"0x0000000000000000000000000000000000000000000000000000000000000003", | ||
]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Hex, encodeAbiParameters } from "viem"; | ||
import { getSchemaPrimitives } from "./getSchemaPrimitives"; | ||
import { getKeySchema } from "./getKeySchema"; | ||
import { Table } from "@latticexyz/config"; | ||
|
||
type PartialTable = Pick<Table, "schema" | "key">; | ||
|
||
export type getKeyTuple<table extends PartialTable, key extends readonly unknown[] = table["key"]> = { | ||
[i in keyof key]: Hex; | ||
}; | ||
|
||
export function getKeyTuple<const table extends PartialTable>( | ||
table: table, | ||
key: getSchemaPrimitives<getKeySchema<table>>, | ||
): getKeyTuple<table> { | ||
return table.key.map((fieldName) => | ||
encodeAbiParameters([table.schema[fieldName]], [key[fieldName as never]]), | ||
) as never; | ||
} |
Oops, something went wrong.