diff --git a/src/internal/client.ts b/src/internal/client.ts index 4b9f267..4188de0 100644 --- a/src/internal/client.ts +++ b/src/internal/client.ts @@ -40,12 +40,36 @@ import { type GolemBaseExtend, type AccountData, } from ".." + +export interface EntitySortOption { + field: 'annotationValue' + annotationKey: string + direction: 'asc' | 'desc' + nulls?: 'first' | 'last' +} + +export interface EntityFilter { + sort?: EntitySortOption[] + limit?: number +} import { SmartAccount } from 'viem/_types/account-abstraction/accounts/types'; export { checksumAddress, toHex, TransactionReceipt } export const storageAddress = '0x0000000000000000000000000000000060138453' +function getAnnotationValue(metadata: EntityMetaData, key: string): string | number | null { + for (const annotation of metadata.stringAnnotations || []) { + if (annotation.key === key) return annotation.value + } + + for (const annotation of metadata.numericAnnotations || []) { + if (annotation.key === key) return annotation.value + } + + return null +} + type GolemGetStorageValueInputParams = Hex type GolemGetStorageValueReturnType = string type GolemGetStorageValueSchema = { @@ -108,7 +132,7 @@ export type GolemBaseActions = { */ getEntitiesToExpireAtBlock(blockNumber: bigint): Promise getEntityCount(): Promise - getAllEntityKeys(): Promise + getAllEntityKeys(filter?: EntityFilter): Promise getEntitiesOfOwner(args: GolemGetEntitiesOfOwnerInputParams): Promise queryEntities(args: GolemQueryEntitiesInputParams): Promise<{ key: Hex, value: Uint8Array, }[]> } @@ -228,11 +252,48 @@ function mkHttpClient(rpcUrl: string, chain: Chain): Client< params: [] }) }, - async getAllEntityKeys(): Promise { - return await client.request({ + async getAllEntityKeys(filter?: EntityFilter): Promise { + const entityKeys = await client.request({ method: 'golembase_getAllEntityKeys', params: [] }) + + if (filter?.sort?.length) { + try { + const entitiesWithMetadata = await Promise.all( + entityKeys.map(async (key: Hex) => ({ + key, + metadata: await this.getEntityMetaData(key) + })) + ) + + const sorted = entitiesWithMetadata.sort((a, b) => { + const sort = filter.sort![0] + const aValue = getAnnotationValue(a.metadata, sort.annotationKey) + const bValue = getAnnotationValue(b.metadata, sort.annotationKey) + + const nulls = sort.nulls ?? 'last' + if (aValue === null && bValue === null) return 0 + if (aValue === null) return nulls === 'first' ? -1 : 1 + if (bValue === null) return nulls === 'first' ? 1 : -1 + + const result = aValue < bValue ? -1 : aValue > bValue ? 1 : 0 + return sort.direction === 'asc' ? result : -result + }) + + let result = sorted.map(e => e.key) + + if (filter.limit) { + result = result.slice(0, filter.limit) + } + + return result + } catch (error) { + return entityKeys + } + } + + return entityKeys }, async getEntitiesOfOwner(args: GolemGetEntitiesOfOwnerInputParams): Promise { return client.request({