@arkiv-network/sdk 0.8.0-dev.3 → 0.8.0-dev.4

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.
Files changed (39) hide show
  1. package/README.md +6 -6
  2. package/dist/chains/index.cjs +3 -3
  3. package/dist/chains/index.d.cts +21 -21
  4. package/dist/chains/index.d.cts.map +1 -1
  5. package/dist/chains/index.d.ts +21 -21
  6. package/dist/chains/index.d.ts.map +1 -1
  7. package/dist/chains/index.js +2 -2
  8. package/dist/{chains-Du8tql7I.js → chains-DmrgfF3p.js} +25 -25
  9. package/dist/chains-DmrgfF3p.js.map +1 -0
  10. package/dist/{chains-BfNQliHU.cjs → chains-Etgm64UM.cjs} +27 -27
  11. package/dist/index-CIcHPx2j.d.cts.map +1 -1
  12. package/dist/{index-BKB875Um.d.ts → index-CmEefH8_.d.ts} +3 -3
  13. package/dist/{index-BKB875Um.d.ts.map → index-CmEefH8_.d.ts.map} +1 -1
  14. package/dist/{index-rINthNuU.d.cts → index-DsM7EXu6.d.cts} +3 -3
  15. package/dist/{index-rINthNuU.d.cts.map → index-DsM7EXu6.d.cts.map} +1 -1
  16. package/dist/index.cjs +8 -8
  17. package/dist/index.d.cts +29 -29
  18. package/dist/index.d.ts +29 -29
  19. package/dist/index.js +8 -8
  20. package/dist/index.js.map +1 -1
  21. package/dist/query/index.cjs +1 -1
  22. package/dist/query/index.d.cts +1 -1
  23. package/dist/query/index.d.ts +1 -1
  24. package/dist/query/index.js +1 -1
  25. package/dist/{queryBuilder-DaLxNgeI.cjs → queryBuilder-BmRTaoJ8.cjs} +2 -2
  26. package/dist/{queryBuilder-COWt6aIF.js → queryBuilder-MubNEvA4.js} +3 -3
  27. package/dist/{queryBuilder-COWt6aIF.js.map → queryBuilder-MubNEvA4.js.map} +1 -1
  28. package/package.json +1 -1
  29. package/src/actions/public/watchEntityEvents.ts +2 -2
  30. package/src/chains/index.ts +1 -1
  31. package/src/chains/tiramisu.ts +22 -0
  32. package/src/clients/createPublicClient.ts +2 -2
  33. package/src/clients/createWalletClient.ts +2 -2
  34. package/src/clients/decorators/arkivPublic.ts +14 -14
  35. package/src/clients/decorators/arkivWallet.ts +10 -10
  36. package/src/query/queryBuilder.ts +2 -2
  37. package/src/utils/chains.test.ts +14 -14
  38. package/dist/chains-Du8tql7I.js.map +0 -1
  39. package/src/chains/cheesecake.ts +0 -22
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["logger","logger","query","logger","context: EntityEventContext","event: EntityEvent","key","logger","EXECUTE_ABI","EXECUTE_FUNCTION_ABI","operations: Operation[]","txHash: Hex | undefined","createdEntityKeys: Hex[]","createdExpiries: bigint[]","extendedExpiries: bigint[]","logger","logger","logger","logger","logger","chains","key"],"sources":["../src/actions/public/getBlockTiming.ts","../src/actions/public/getEntity.ts","../src/actions/public/getEntityCount.ts","../src/entity/operations.ts","../src/actions/public/getEntityNonce.ts","../src/actions/public/predictEntityKeys.ts","../src/actions/public/query.ts","../src/actions/public/watchEntityEvents.ts","../src/clients/decorators/arkivPublic.ts","../src/clients/createPublicClient.ts","../src/utils/revert.ts","../src/utils/arkivTransactions.ts","../src/actions/wallet/changeOwnership.ts","../src/actions/wallet/createEntity.ts","../src/actions/wallet/deleteEntity.ts","../src/actions/wallet/executeBatch.ts","../src/actions/wallet/extendEntity.ts","../src/actions/wallet/patchEntity.ts","../src/clients/decorators/arkivWallet.ts","../src/clients/createWalletClient.ts","../src/utils/chains.ts"],"sourcesContent":["import type { ArkivClient } from \"../../clients/baseClient\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:public:get-block-timing\")\n\nexport type GetBlockTimingReturnType = {\n currentBlock: bigint\n currentBlockTime: number\n blockDuration: number\n}\n\nexport async function getBlockTiming(client: ArkivClient) {\n const blockTiming = await client.request({\n method: \"arkiv_getBlockTiming\",\n params: [],\n })\n logger(\"Block timing %o\", blockTiming)\n return {\n currentBlock: BigInt(blockTiming.current_block),\n currentBlockTime: blockTiming.current_block_time,\n blockDuration: blockTiming.duration,\n }\n}\n","import type { Hex } from \"viem\"\nimport { key } from \"../../attr\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport { NoEntityFoundError } from \"../../errors\"\nimport { runQuery } from \"../../query/engine\"\nimport { eq } from \"../../query/expression\"\nimport { type FullEntity, toRpcSelect } from \"../../query/selection\"\nimport type { Entity } from \"../../types/entity\"\n\n/**\n * Reads one entity by key, with every field selected.\n *\n * Returns a {@link FullEntity} rather than an {@link Entity}: the selection is fixed at `\"*\"`, so\n * every field is populated and none of them needs a `?` at the call site. The bare `Entity` type\n * has every field optional because a `select()` result carries only what it asked for.\n *\n * @throws {InvalidValueError} If the key is not 32 bytes.\n * @throws {NoEntityFoundError} If no live entity has that key — it never existed, or it was\n * deleted or has expired.\n */\nexport async function getEntity(client: ArkivClient, entityKey: Hex): Promise<FullEntity> {\n const { entities } = await runQuery(client, {\n query: eq(\"$key\", key(entityKey)).toString(),\n select: toRpcSelect(\"*\"),\n limit: 1,\n })\n\n const entity = entities[0]\n if (entity === undefined) {\n throw new NoEntityFoundError(entityKey)\n }\n // Every field was selected, so the runtime Entity carries them all; the cast is the same\n // narrowing `client.select(\"*\")` gets from its own inference.\n return entity as unknown as FullEntity\n}\n","import type { ArkivClient } from \"../../clients/baseClient\"\n\nexport async function getEntityCount(client: ArkivClient) {\n const count = await client.request({\n method: \"arkiv_getEntityCount\",\n params: [],\n })\n\n return count\n}\n","import { type Address, encodeAbiParameters, type Hex, parseAbi, parseAbiParameters } from \"viem\"\nimport type { AbiAttribute } from \"../attr/codec\"\nimport type { EncodedExpiry } from \"./expiry\"\nimport type { predictEntityKey } from \"./key\"\nimport { OperationType } from \"./params\"\n\n/**\n * The one external entry point. A transaction is an ordered, **atomic** batch of entity operations:\n * all of them apply or none do, operation *n+1* observes operation *n*'s effects, and each applied\n * operation emits one event.\n */\nexport const EXECUTE_ABI = parseAbi([\n \"function execute((uint8 operation, bytes operationData)[] ops) external returns (bytes32[] keys)\",\n])\n\n/**\n * The engine's one read-only view: an owner's entity-minting nonce, which is the input\n * {@link predictEntityKey} needs and the only part of the derivation the caller cannot know.\n *\n * It is a `view` on the same address `execute` is called on, so it answers over `eth_call` without\n * a transaction.\n */\nexport const ENTITY_NONCE_ABI = parseAbi([\n \"function entityNonce(address owner) external view returns (uint64)\",\n])\n\n/**\n * The shared attribute shape, used by `create` (attributes) and `patch` (mutations). Written out\n * once and reused by every payload that carries attributes.\n */\nconst ATTRIBUTE_TUPLE = \"(bytes32 name, uint8 typeId, bytes value)[]\"\n\n/**\n * The payload struct for each operation tag. `operationData` is `abi.encode` of the struct the tag\n * selects — a tagged union, so a new operation is additive rather than a change to `execute`.\n */\nconst PAYLOAD_PARAMS = {\n [OperationType.Create]: parseAbiParameters(\n `(uint128 salt, uint64 expiresAt, uint64 minLifetime, uint8 creationFlags, ${ATTRIBUTE_TUPLE} attributes)`,\n ),\n [OperationType.Patch]: parseAbiParameters(`(bytes32 entityKey, ${ATTRIBUTE_TUPLE} mutations)`),\n [OperationType.ExtendExpiry]: parseAbiParameters(\n \"(bytes32 entityKey, uint64 expiresAt, uint64 minLifetime)\",\n ),\n [OperationType.TransferOwnership]: parseAbiParameters(\"(bytes32 entityKey, address newOwner)\"),\n [OperationType.Delete]: parseAbiParameters(\"(bytes32 entityKey)\"),\n} as const\n\n/** One entry of the `execute` batch: the operation tag and its ABI-encoded payload. */\nexport type Operation = {\n operation: number\n operationData: Hex\n}\n\n/** Creates an entity. The key is derived by the engine; predict it with `predictEntityKey`. */\nexport function createOperation({\n salt,\n expiry,\n creationFlags,\n attributes,\n}: {\n salt: bigint\n expiry: EncodedExpiry\n creationFlags: number\n attributes: AbiAttribute[]\n}): Operation {\n return {\n operation: OperationType.Create,\n operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.Create], [\n {\n salt,\n expiresAt: expiry.expiresAt,\n minLifetime: expiry.minLifetime,\n creationFlags,\n attributes,\n },\n ]),\n }\n}\n\n/** Applies a set of mutations to an existing entity. Tombstones unset attributes. */\nexport function patchOperation({\n entityKey,\n mutations,\n}: {\n entityKey: Hex\n mutations: AbiAttribute[]\n}): Operation {\n return {\n operation: OperationType.Patch,\n operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.Patch], [\n { entityKey, mutations },\n ]),\n }\n}\n\n/** Pushes an entity's expiry further out. Extending is allowed; shortening reverts. */\nexport function extendExpiryOperation({\n entityKey,\n expiry,\n}: {\n entityKey: Hex\n expiry: EncodedExpiry\n}): Operation {\n return {\n operation: OperationType.ExtendExpiry,\n operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.ExtendExpiry], [\n { entityKey, expiresAt: expiry.expiresAt, minLifetime: expiry.minLifetime },\n ]),\n }\n}\n\n/** Hands an entity to a new owner. */\nexport function transferOwnershipOperation({\n entityKey,\n newOwner,\n}: {\n entityKey: Hex\n newOwner: Address\n}): Operation {\n return {\n operation: OperationType.TransferOwnership,\n operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.TransferOwnership], [\n { entityKey, newOwner },\n ]),\n }\n}\n\n/** Deletes an entity before its expiry. */\nexport function deleteOperation({ entityKey }: { entityKey: Hex }): Operation {\n return {\n operation: OperationType.Delete,\n operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.Delete], [{ entityKey }]),\n }\n}\n","import type { Address } from \"viem\"\nimport { readContract } from \"viem/actions\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport { ARKIV_ADDRESS } from \"../../consts\"\nimport { ENTITY_NONCE_ABI } from \"../../entity/operations\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:public:get-entity-nonce\")\n\n/**\n * Reads an owner's entity-minting nonce — how many entities that account has created.\n *\n * This is not the account's transaction nonce. The engine keeps a separate counter per creator and\n * mixes it into every key it mints, which is what makes two identical creates from one account land\n * on different keys.\n *\n * @param owner - The account whose nonce to read.\n * @returns The number of entities `owner` has created so far, which is the nonce its next create\n * will use.\n */\nexport async function getEntityNonce(client: ArkivClient, owner: Address): Promise<bigint> {\n const nonce = await readContract(client, {\n address: ARKIV_ADDRESS,\n abi: ENTITY_NONCE_ABI,\n functionName: \"entityNonce\",\n args: [owner],\n })\n logger(\"entity nonce of %s is %s\", owner, nonce)\n return nonce\n}\n","import type { Address, Hex } from \"viem\"\nimport { getChainId } from \"viem/actions\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport {\n NO_SALT,\n predictEntityKey,\n randomSalt,\n resolveSalt,\n type SaltInput,\n} from \"../../entity/key\"\nimport { getEntityNonce } from \"./getEntityNonce\"\n\n/**\n * A key a create will be given, together with the salt that mints it.\n *\n * The two travel as a pair because neither is any use alone: a create defaults to a *random* salt,\n * so the key only comes out as predicted if that same create carries this salt.\n */\nexport type PredictedEntityKey = {\n /** The key the create will be given. */\n key: Hex\n /**\n * The salt the create must carry for its key to come out as {@link PredictedEntityKey.key}.\n * Always a plain `uint128` — a requested {@link NO_SALT} comes back as the `0n` it resolves to,\n * which a create accepts just the same.\n */\n salt: bigint\n}\n\n/** Parameters for `client.predictEntityKeys`. */\nexport type PredictEntityKeysParameters<\n TCount extends number = number,\n TSalts extends readonly SaltInput[] | undefined = readonly SaltInput[] | undefined,\n> = {\n /** The account that will sign the creates. Its nonce is what the keys are derived from. */\n owner: Address\n /**\n * How many creates the batch will carry. Ignored when `salts` is given, which already says how\n * many there are.\n *\n * A literal count comes back as a fixed-length tuple, so `count: 2` destructures into two named\n * pairs without a cast.\n */\n count?: TCount | undefined\n /**\n * The salt each create will carry, in batch order. Defaults to `count` fresh random salts —\n * either way each key comes back paired with the salt that mints it. Pass {@link NO_SALT} in a\n * slot whose create opts out of salting.\n */\n salts?: TSalts\n}\n\n/**\n * The keys a batch would mint, in batch order, each paired with its salt.\n *\n * The length follows the request whenever it is known statically: a literal `count`, or a `salts`\n * tuple, gives a fixed-length tuple; a count computed at runtime gives a plain array.\n *\n * `TSalts` is wrapped in a tuple to stop the conditional distributing over it. Left naked, the\n * `readonly SaltInput[] | undefined` default would take both branches and union a tuple with an\n * array, which widens the length straight back to `number`.\n */\nexport type PredictEntityKeysReturnType<\n TCount extends number = number,\n TSalts extends readonly SaltInput[] | undefined = readonly SaltInput[] | undefined,\n> = [TSalts] extends [readonly SaltInput[]]\n ? { -readonly [Index in keyof TSalts]: PredictedEntityKey }\n : Repeat<PredictedEntityKey, TCount>\n\n/**\n * A tuple of `TLength` × `T`, or a plain array when the length is only known at runtime.\n *\n * Written tail-recursively so TypeScript can build the batch sizes anyone would actually send.\n */\ntype Repeat<T, TLength extends number, TAcc extends T[] = []> = number extends TLength\n ? T[]\n : TAcc[\"length\"] extends TLength\n ? TAcc\n : Repeat<T, TLength, [...TAcc, T]>\n\n/**\n * Works out the keys an account's next creates will be given, before sending them.\n *\n * A key is `keccak256(chainId ++ registry ++ owner ++ nonce ++ salt)`. Everything but the nonce is\n * known to the caller, and the nonce is read here — so a batch can reference a key it is about to\n * mint, storing it as a `key` attribute on a sibling entity created in the same transaction.\n *\n * Each key arrives paired with its salt, and the create must be given that salt: a create left to\n * pick its own salt picks a random one, which mints a different key.\n *\n * The prediction is valid only while nothing else from this owner is in flight. Every create that\n * lands first takes the nonce with it and moves these keys. For a key you can rely on\n * unconditionally, read it back from the create instead — `createEntity` and `executeBatch`\n * report the keys the engine actually minted.\n *\n * @param parameters - Owner, and either a count or the salts. {@link PredictEntityKeysParameters}\n * @returns One `{ key, salt }` pair per create, in batch order. {@link PredictEntityKeysReturnType}\n *\n * @example A batch whose second entity points at its first.\n * import { key } from \"@arkiv-network/sdk/attr\"\n *\n * const [parent, child] = await client.predictEntityKeys({ owner: account.address, count: 2 })\n * await client.executeBatch({\n * creates: [\n * { payload, contentType, expires, salt: parent.salt },\n * {\n * payload,\n * contentType,\n * expires,\n * salt: child.salt,\n * attributes: { parent: key(parent.key) },\n * },\n * ],\n * })\n */\nexport async function predictEntityKeys<\n const TCount extends number = number,\n const TSalts extends readonly SaltInput[] | undefined = undefined,\n>(\n client: ArkivClient,\n { owner, count, salts }: PredictEntityKeysParameters<TCount, TSalts>,\n): Promise<PredictEntityKeysReturnType<TCount, TSalts>> {\n const resolvedSalts = resolveSalts(count, salts)\n\n const chainId = client.chain?.id ?? (await getChainId(client))\n const nonce = await getEntityNonce(client, owner)\n\n return resolvedSalts.map((salt, index) => ({\n key: predictEntityKey({ owner, nonce: nonce + BigInt(index), salt, chainId }),\n salt,\n })) as PredictEntityKeysReturnType<TCount, TSalts>\n}\n\n/** The salts to derive from: the ones given, or `count` fresh random ones. */\nfunction resolveSalts(\n count: number | undefined,\n salts: readonly SaltInput[] | undefined,\n): bigint[] {\n if (salts !== undefined) {\n if (salts.length === 0) {\n throw new Error(\"predictEntityKeys: `salts` is empty — there is nothing to predict\")\n }\n return salts.map(resolveSalt)\n }\n if (count === undefined) {\n throw new Error(\"predictEntityKeys: pass either `count` or `salts`\")\n }\n if (!Number.isInteger(count) || count <= 0) {\n throw new Error(`predictEntityKeys: \\`count\\` must be a positive whole number, got ${count}`)\n }\n return Array.from({ length: count }, () => randomSalt())\n}\n","import type { ArkivClient } from \"../../clients/baseClient\"\nimport { runQuery } from \"../../query/engine\"\nimport type { Expression } from \"../../query/expression\"\nimport { type SelectArg, toRpcSelect } from \"../../query/selection\"\nimport type { Entity } from \"../../types/entity\"\n\nexport type QueryOptions = {\n /** What to return. Defaults to everything. */\n select?: SelectArg | undefined\n /** Block height to read at. Defaults to the head. */\n atBlock?: bigint | undefined\n /** Page size, up to the node maximum of 200. */\n limit?: number | undefined\n /** Cursor from a previous page. */\n cursor?: string | undefined\n}\n\nexport type QueryReturnType = {\n entities: Entity[]\n /** The cursor for the next page, or `undefined` when no pages remain. */\n cursor: string | undefined\n /** The block the page was read at. */\n blockNumber: bigint\n}\n\n/**\n * Runs a single query and returns one page, with no builder in between.\n *\n * Takes either an {@link Expression} or a raw query string. The string form is an escape hatch for\n * a query built elsewhere — it goes to the node exactly as written, with none of the name, type or\n * operator checks the expression combinators apply.\n *\n * @throws {QueryError} If the node rejects the query.\n */\nexport function query(\n client: ArkivClient,\n query: Expression | string,\n options: QueryOptions = {},\n): Promise<QueryReturnType> {\n return runQuery(client, {\n query: query.toString(),\n select: toRpcSelect(options.select),\n limit: options.limit,\n cursor: options.cursor,\n atBlock: options.atBlock,\n })\n}\n","import { decodeEventLog, type Hex } from \"viem\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { PublicArkivClient } from \"../../clients/createPublicClient\"\nimport { ARKIV_ADDRESS, BLOCK_TIME } from \"../../consts\"\nimport { ENTITY_EVENTS_ABI } from \"../../entity/events\"\nimport { decodeCreationFlags } from \"../../entity/flags\"\nimport type {\n EntityCreatedEvent,\n EntityDeletedEvent,\n EntityEvent,\n EntityEventContext,\n EntityPatchedEvent,\n ExpiryExtendedEvent,\n OwnershipTransferredEvent,\n} from \"../../types/events\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:public:watch-entity-events\")\n\n/**\n * How often to poll, when the caller does not say.\n *\n * Half a block: fast enough that an event is never a whole block stale, slow enough not to hammer\n * the node. viem's own default is derived from a 12-second Ethereum block and is far too slow here.\n */\nconst DEFAULT_POLLING_INTERVAL = (BLOCK_TIME * 1000) / 2\n\n/**\n * Handlers and options for `client.watchEntityEvents`. Every handler is optional; the watcher does\n * the work for the ones you pass.\n */\nexport type WatchEntityEventsParameters = {\n onEntityCreated?: ((event: EntityCreatedEvent) => void) | undefined\n onEntityPatched?: ((event: EntityPatchedEvent) => void) | undefined\n onExpiryExtended?: ((event: ExpiryExtendedEvent) => void) | undefined\n onOwnershipTransferred?: ((event: OwnershipTransferredEvent) => void) | undefined\n onEntityDeleted?: ((event: EntityDeletedEvent) => void) | undefined\n /**\n * Every event, in application order, whatever its type. Runs *before* the per-event handler for\n * the same event.\n *\n * This is the replay seam: operations apply in batch order and emit one event each, so an\n * off-chain replica that consumes this in order sees exactly what the engine did.\n */\n onEvent?: ((event: EntityEvent) => void) | undefined\n /**\n * Transport failures, logs that will not decode, and anything one of your own handlers throws.\n *\n * Defaults to `console.error`. A watcher whose filter the node dropped otherwise just goes quiet,\n * and a quiet watcher is indistinguishable from a quiet chain.\n */\n onError?: ((error: Error) => void) | undefined\n /** Replay from this block before following the head. Defaults to the head. */\n fromBlock?: bigint | undefined\n /** How often to poll, in milliseconds. Defaults to half a block. */\n pollingInterval?: number | undefined\n}\n\n/**\n * Watches entity events, calling the handlers you pass as they arrive.\n *\n * Every event here is decoded from a log the Arkiv operation address emitted, and carries the\n * block, transaction and log index it came from — so consuming them in order replays exactly what\n * the engine did.\n *\n * @param parameters - Handlers and options. {@link WatchEntityEventsParameters}\n * @returns A function that stops the watcher.\n *\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({ chain: cheesecake, transport: http() })\n *\n * const unwatch = client.watchEntityEvents({\n * onEntityCreated: ({ entityKey, owner, expiresAt }) =>\n * console.log(\"created\", entityKey, \"by\", owner, \"until block\", expiresAt),\n * onEntityDeleted: ({ entityKey }) => console.log(\"deleted\", entityKey),\n * onError: (error) => console.error(error),\n * })\n *\n * unwatch()\n */\nexport function watchEntityEvents(\n client: ArkivClient,\n parameters: WatchEntityEventsParameters,\n): () => void {\n const {\n onEntityCreated,\n onEntityPatched,\n onExpiryExtended,\n onOwnershipTransferred,\n onEntityDeleted,\n onEvent,\n onError,\n fromBlock,\n pollingInterval = DEFAULT_POLLING_INTERVAL,\n } = parameters\n\n const publicClient = client as PublicArkivClient\n const reportError = onError ?? logToConsole\n\n function emit(event: EntityEvent): void {\n deliver(onEvent, event)\n switch (event.type) {\n case \"EntityCreated\":\n deliver(onEntityCreated, event)\n break\n case \"EntityPatched\":\n deliver(onEntityPatched, event)\n break\n case \"ExpiryExtended\":\n deliver(onExpiryExtended, event)\n break\n case \"OwnershipTransferred\":\n deliver(onOwnershipTransferred, event)\n break\n case \"EntityDeleted\":\n deliver(onEntityDeleted, event)\n break\n }\n }\n\n /**\n * Runs one handler, keeping its failure to itself.\n *\n * A handler that throws is the consumer's problem, not the watcher's: letting it escape would\n * reject the poll, drop the rest of the batch, and take down every other handler with it.\n */\n function deliver<TEvent>(handler: ((event: TEvent) => void) | undefined, event: TEvent): void {\n if (handler === undefined) return\n try {\n handler(event)\n } catch (error) {\n reportError(asError(error))\n }\n }\n\n const unwatchLogs = publicClient.watchEvent({\n // Only the Arkiv operation address emits these. Without the filter any contract whose event\n // happens to hash to the same topic lands in `onLogs`, and viem's observer key — which covers\n // the address but not `events` — would make this subscription collide with any other\n // unaddressed `watchEvent` on the same client.\n address: ARKIV_ADDRESS,\n events: ENTITY_EVENTS_ABI,\n pollingInterval,\n ...(fromBlock !== undefined && { fromBlock }),\n onLogs: (logs) => {\n logger(\"logs %o\", logs)\n for (const log of logs) {\n // A log with no position cannot be placed in application order, which is the one thing an\n // event consumer needs from it. Dropping it beats inventing a position it never had.\n if (log.blockNumber === null || log.transactionHash === null || log.logIndex === null) {\n continue\n }\n const context: EntityEventContext = {\n blockNumber: log.blockNumber,\n transactionHash: log.transactionHash,\n logIndex: log.logIndex,\n }\n\n // Only the decode is guarded here. Dispatch guards each handler separately, so a consumer's\n // exception is never reported as if the log were the thing that was malformed.\n let event: EntityEvent\n try {\n event = toEntityEvent(log.topics, log.data, context)\n } catch (error) {\n reportError(asError(error))\n continue\n }\n emit(event)\n }\n },\n onError: (error) => reportError(error),\n })\n\n return unwatchLogs\n}\n\n/** The fallback when no `onError` was given — see {@link WatchEntityEventsParameters.onError}. */\nfunction logToConsole(error: Error): void {\n console.error(\"watchEntityEvents error\", error)\n}\n\n/** Handlers take an `Error`, and a `throw` can be anything. */\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error))\n}\n\n/**\n * Decodes one log into the {@link EntityEvent} it carries.\n *\n * @throws If the log does not decode against {@link ENTITY_EVENTS_ABI}.\n */\nfunction toEntityEvent(\n topics: readonly Hex[],\n data: Hex,\n context: EntityEventContext,\n): EntityEvent {\n const decoded = decodeEventLog({\n abi: ENTITY_EVENTS_ABI,\n topics: topics as [Hex, ...Hex[]] | [],\n data,\n })\n\n switch (decoded.eventName) {\n case \"EntityCreated\":\n return {\n type: \"EntityCreated\",\n ...context,\n ...decoded.args,\n creationFlags: decodeCreationFlags(decoded.args.creationFlags),\n }\n case \"EntityPatched\":\n return { type: \"EntityPatched\", ...context, ...decoded.args }\n case \"ExpiryExtended\":\n return { type: \"ExpiryExtended\", ...context, ...decoded.args }\n case \"OwnershipTransferred\":\n return { type: \"OwnershipTransferred\", ...context, ...decoded.args }\n case \"EntityDeleted\":\n return { type: \"EntityDeleted\", ...context, ...decoded.args }\n }\n}\n","import type { Account, Address, Chain, Client, Hex, PublicActions, Transport } from \"viem\"\nimport { type GetBlockTimingReturnType, getBlockTiming } from \"../../actions/public/getBlockTiming\"\nimport { getEntity } from \"../../actions/public/getEntity\"\nimport { getEntityCount } from \"../../actions/public/getEntityCount\"\nimport { getEntityNonce } from \"../../actions/public/getEntityNonce\"\nimport {\n type PredictEntityKeysParameters,\n type PredictEntityKeysReturnType,\n predictEntityKeys,\n} from \"../../actions/public/predictEntityKeys\"\nimport { type QueryOptions, type QueryReturnType, query } from \"../../actions/public/query\"\nimport {\n type WatchEntityEventsParameters,\n watchEntityEvents,\n} from \"../../actions/public/watchEntityEvents\"\nimport type { SaltInput } from \"../../entity/key\"\nimport type { Expression } from \"../../query/expression\"\nimport { SelectQueryBuilder } from \"../../query/queryBuilder\"\nimport type { EntitySelection, FullEntity, ProjectedEntity, SelectArg } from \"../../query/selection\"\nimport type { Entity } from \"../../types/entity\"\n\nexport type PublicArkivActions<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n account extends Account | undefined = Account | undefined,\n> = Pick<\n PublicActions<transport, chain, account>,\n | \"getBalance\"\n | \"getBlock\"\n | \"getBlockNumber\"\n | \"getChainId\"\n | \"getLogs\"\n | \"getTransaction\"\n | \"getTransactionCount\"\n | \"getTransactionReceipt\"\n | \"waitForTransactionReceipt\"\n | \"watchEvent\"\n> & {\n /**\n * Returns the entity with the given key.\n *\n * - JSON-RPC Methods: `arkiv_query`\n *\n * @param key - The entity key (hex string)\n * @returns The entity with the given key, with every field populated. {@link FullEntity}\n *\n * @throws {InvalidValueError} If the key is not 32 bytes.\n * @throws {NoEntityFoundError} If no live entity has that key — it never existed, or it was\n * deleted or has expired.\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: cheesecake,\n * transport: http(),\n * })\n * const entity = await client.getEntity(entityKey)\n * // Entity {\n * // key: \"0x9f2c…\",\n * // owner: \"0xabc…\",\n * // contentType: \"application/json\",\n * // payload: Uint8Array, // entity.toJson() / entity.toText() decode it\n * // attributes: { category: { type: \"str\", value: \"docs\" } },\n * // expiresAt: 1_297_000n,\n * // }\n */\n getEntity: (key: Hex) => Promise<FullEntity>\n\n /**\n * Returns a SelectQueryBuilder for building and executing queries — the recommended way to\n * read entities. You declare up front which parts of an entity you want returned, so results\n * always contain exactly the data you asked for.\n *\n * - JSON-RPC Methods: `arkiv_query`\n *\n * @param selection - What to include in the results. Omit it (or pass `\"*\"`) to select everything,\n * or pass an object to select specific parts (at least one field is required). Every part is\n * opt-in, including the `key`. The selection is flat — each field maps to an entity field.\n * {@link SelectArg}\n * @returns A SelectQueryBuilder instance for building and executing queries. {@link SelectQueryBuilder}\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { eq } from \"@arkiv-network/sdk/query\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: cheesecake,\n * transport: http(),\n * })\n * // select everything\n * await client.select().where(eq(\"category\", \"docs\")).fetch()\n * await client.select(\"*\").where(eq(\"category\", \"docs\")).fetch()\n * // only the key\n * await client.select({ key: true }).where(eq(\"category\", \"docs\")).fetch()\n * // select specific fields — result typed { owner: Hex; attributes: Attributes }\n * await client.select({ owner: true, attributes: true }).fetch()\n * // a single field — result typed { owner: Hex }\n * await client.select({ owner: true }).fetch()\n */\n select: {\n /** Select every field. Pass nothing or `\"*\"`; the returned entities contain all fields. */\n (selection?: \"*\"): SelectQueryBuilder<FullEntity>\n /**\n * Pick the entity fields to return. Set the ones you want to `true` (at least one is required);\n * the result is typed to exactly those fields, so reading anything else is a compile error.\n *\n * Available fields: `key`, `owner`, `creator`, `createdAt`, `updatedAt`, `expiresAt`,\n * `creationFlags`, `contentType`, `payload`, `attributeSchema` and `attributes`.\n *\n * `attributes` also takes a map of names, to fetch only those:\n * `select({ key: true, attributes: { projectId: true } })`.\n *\n * Pass the selection inline so its fields stay literal `true`. A selection stored in a `let`/\n * `const` variable widens to `boolean` and the result type can no longer be narrowed — annotate\n * it `as const` (e.g. `const sel = { owner: true } as const`) in that case.\n *\n * @example\n * client.select({ owner: true, attributes: true }) // entities typed { owner, attributes }\n * client.select({ key: true, payload: true }) // includes payload → toText()/toJson() too\n * client.select({ key: true, attributeSchema: true }) // what shape is the data?\n */\n <const S extends EntitySelection>(selection: S): SelectQueryBuilder<ProjectedEntity<S>>\n /**\n * Dynamic selection: accepts a value typed {@link SelectArg} (e.g. built at runtime). The\n * result cannot be narrowed in this case, so the entities are typed as the full entity.\n */\n (selection: SelectArg): SelectQueryBuilder<FullEntity>\n }\n\n /**\n * Runs one query and returns one page, with no builder in between.\n *\n * Use {@link PublicArkivActions.select} for anything typed — this returns full {@link Entity} objects whatever the\n * selection, and takes a raw string as an escape hatch for a query built elsewhere. A raw string\n * goes to the node exactly as written, with none of the name, type or operator checks the\n * expression combinators apply.\n *\n * @param query - An {@link Expression}, or the raw query string.\n * @param queryOptions - Selection, page size, cursor and block. {@link QueryOptions}\n * @returns One page of entities. {@link QueryReturnType}\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { and, eq, gte } from \"@arkiv-network/sdk/query\"\n * import { i32 } from \"@arkiv-network/sdk/attr\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: cheesecake,\n * transport: http(),\n * })\n * const page = await client.query(and(eq(\"category\", \"docs\"), gte(\"level\", i32(10))), {\n * select: { key: true, attributes: true },\n * limit: 100,\n * })\n * // { entities: [Entity], cursor: \"b64:…\", blockNumber: 32223n }\n *\n * // The raw form, unchecked:\n * await client.query(\"category = str('docs') AND level >= i32(10)\")\n */\n query: (query: Expression | string, queryOptions?: QueryOptions) => Promise<QueryReturnType>\n\n /**\n * Returns the total number of entities on the chain.\n * @returns The number of entities currently stored\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: cheesecake,\n * transport: http(),\n * })\n * const entityCount = await client.getEntityCount()\n * // entityCount = 0\n */\n getEntityCount: () => Promise<number>\n\n /**\n * Returns how many entities an account has created — its entity-minting nonce.\n *\n * Not the account's transaction nonce: the engine keeps its own counter per creator and mixes it\n * into every key it mints, which is why two identical creates from one account never collide.\n *\n * @param owner - The account whose nonce to read.\n * @returns The nonce the account's next create will use.\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: cheesecake,\n * transport: http(),\n * })\n * const nonce = await client.getEntityNonce(\"0xabc…\")\n * // 7n — the next entity this account creates is its eighth\n */\n getEntityNonce: (owner: Address) => Promise<bigint>\n\n /**\n * Works out the keys an account's next creates will be given, before sending them.\n *\n * The engine derives a key from the chain, the registry, the owner, the owner's nonce and a\n * salt — everything but the nonce is known to the caller, and the nonce is read here. This is\n * what lets a batch reference an entity it is about to mint.\n *\n * Each key arrives paired with the salt that mints it, because a create defaults to a *random*\n * salt: a predicted key only holds if the create carries the salt it was predicted with. And the\n * prediction holds only while nothing else from this owner is in flight — for a key you can rely\n * on unconditionally, read it back from the create instead.\n *\n * A literal `count` comes back as a fixed-length tuple, so the pairs destructure into names.\n *\n * @param parameters - Owner, and either a count or the salts. {@link PredictEntityKeysParameters}\n * @returns One `{ key, salt }` pair per create, in batch order.\n * {@link PredictEntityKeysReturnType}\n *\n * @example A batch whose second entity points at its first.\n * import { key } from \"@arkiv-network/sdk/attr\"\n *\n * const [parent, child] = await client.predictEntityKeys({ owner: account.address, count: 2 })\n * await wallet.executeBatch({\n * creates: [\n * { payload, contentType, expires, salt: parent.salt },\n * {\n * payload,\n * contentType,\n * expires,\n * salt: child.salt,\n * attributes: { parent: key(parent.key) },\n * },\n * ],\n * })\n */\n predictEntityKeys: <\n const TCount extends number = number,\n const TSalts extends readonly SaltInput[] | undefined = undefined,\n >(\n parameters: PredictEntityKeysParameters<TCount, TSalts>,\n ) => Promise<PredictEntityKeysReturnType<TCount, TSalts>>\n\n /**\n * Returns the current block timing.\n * @returns The current block timing. {@link GetBlockTimingReturnType}\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: cheesecake,\n * transport: http(),\n * })\n * const blockTiming = await client.getBlockTiming()\n * // {\n * // currentBlock: 10n, // block number\n * // currentBlockTime: 1234567890, // block timestamp\n * // blockDuration: 2, // in seconds\n * // }\n */\n getBlockTiming: () => Promise<GetBlockTimingReturnType>\n\n /**\n * Watches entity events, calling the handlers you pass as they arrive.\n *\n * All five are decoded from logs — `onEntityCreated`, `onEntityPatched`, `onExpiryExtended`,\n * `onOwnershipTransferred`, `onEntityDeleted` — and each carries the block, transaction and log\n * index it came from, which is the order the operations were applied in. `onEvent` receives all\n * of them, whatever their type.\n *\n * @param parameters - Handlers and options, all optional. {@link WatchEntityEventsParameters}\n * @returns A function that stops the watcher.\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: cheesecake,\n * transport: http(),\n * })\n * const unwatch = client.watchEntityEvents({\n * onEntityCreated: ({ entityKey, expiresAt }) => console.log(entityKey, \"until\", expiresAt),\n * onError: (error) => console.error(\"watchEntityEvents error\", error),\n * })\n * unwatch() // stop watching\n */\n watchEntityEvents: (parameters: WatchEntityEventsParameters) => () => void\n}\n\nexport function publicArkivActions<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n account extends Account | undefined = Account | undefined,\n>(client: Client<transport, chain, account>) {\n return {\n getEntity: (key: Hex) => getEntity(client, key),\n query: (rawQuery: Expression | string, queryOptions?: QueryOptions) =>\n query(client, rawQuery, queryOptions),\n select: (selection?: SelectArg) => new SelectQueryBuilder(client, selection),\n getBlockTiming: () => getBlockTiming(client),\n getEntityCount: () => getEntityCount(client),\n getEntityNonce: (owner: Address) => getEntityNonce(client, owner),\n predictEntityKeys: <\n const TCount extends number = number,\n const TSalts extends readonly SaltInput[] | undefined = undefined,\n >(\n parameters: PredictEntityKeysParameters<TCount, TSalts>,\n ) => predictEntityKeys(client, parameters),\n watchEntityEvents: (parameters: WatchEntityEventsParameters) =>\n watchEntityEvents(client, parameters),\n }\n}\n","import type {\n Account,\n Address,\n Chain,\n Client,\n ParseAccount,\n Prettify,\n PublicClientConfig,\n RpcSchema,\n Transport,\n} from \"viem\"\nimport { createClient, publicActions } from \"viem\"\nimport type { ArkivRpcSchema } from \"../types/rpcSchema\"\nimport { type PublicArkivActions, publicArkivActions } from \"./decorators/arkivPublic\"\n\nexport type PublicArkivClient<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n accountOrAddress extends Account | undefined = undefined,\n rpcSchema extends RpcSchema | undefined = ArkivRpcSchema,\n> = Prettify<\n Client<transport, chain, accountOrAddress, rpcSchema, PublicArkivActions<transport, chain>>\n>\n\n/**\n * Creates a Public Client with a given [Transport](https://viem.sh/docs/clients/intro) configured for a [Chain](https://viem.sh/docs/chains/introduction).\n *\n * A Public Client is an interface to the \"public\" [Ethereum JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/)\n * and the Arkiv JSON-RPC API — retrieving block numbers and transactions, reading from\n * contracts, and querying entities — through {@link PublicArkivActions}.\n *\n * @param parameters - Configuration object for the public client (chain, transport, etc.)\n * @returns An Arkiv Public Client. {@link PublicArkivClient}\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: cheesecake,\n * transport: http(),\n * })\n */\nexport function createPublicClient<\n transport extends Transport,\n chain extends Chain | undefined = undefined,\n accountOrAddress extends Account | Address | undefined = undefined,\n rpcSchema extends RpcSchema | undefined = ArkivRpcSchema,\n>(\n parameters: PublicClientConfig<transport, chain, accountOrAddress, rpcSchema>,\n): PublicArkivClient<transport, chain, ParseAccount<accountOrAddress>, rpcSchema> {\n const { key = \"public\", name = \"Public Client\" } = parameters\n const client = createClient({\n ...parameters,\n key,\n name,\n })\n\n return client.extend(publicActions).extend(publicArkivActions) as unknown as PublicArkivClient<\n transport,\n chain,\n ParseAccount<accountOrAddress>,\n rpcSchema\n >\n}\n","import { BaseError, ContractFunctionRevertedError, type Hex, hexToString } from \"viem\"\n\n/**\n * Turns a decoded engine revert into a sentence that says what to change.\n *\n * viem decodes the error and then renders it positionally — `Ident32InvalidByte(uint256 position,\n * bytes1 value)` arrives as `(5, 0x41)`, which is the right data and no help at all. The engine's\n * errors carry enough to name the actual problem, so this spends the args rather than printing\n * them.\n *\n * @param error - Anything thrown by a write action.\n * @returns The explanation, or `undefined` if this was not a decodable engine revert — in which\n * case the caller should fall back to whatever the transport said.\n */\nexport function describeEntityRevert(error: unknown): string | undefined {\n if (!(error instanceof BaseError)) return undefined\n const reverted = error.walk((e) => e instanceof ContractFunctionRevertedError)\n if (!(reverted instanceof ContractFunctionRevertedError)) return undefined\n\n const name = reverted.data?.errorName\n if (name === undefined) return undefined\n const args = (reverted.data?.args ?? []) as readonly unknown[]\n\n return explain(name, args) ?? `the engine rejected the batch with ${name}`\n}\n\n/** The attribute-name charset, quoted the way an error message should read. */\nconst CHARSET = '\"A\"-\"Z\", \"a\"-\"z\", \"0\"-\"9\", \".\", \"-\" and \"_\", with a letter first'\n\nfunction explain(name: string, args: readonly unknown[]): string | undefined {\n switch (name) {\n // ── attribute names ──────────────────────────────────────────────────────\n case \"Ident32InvalidByte\": {\n const position = Number(args[0] ?? 0)\n const char = printable(String(args[1] ?? \"0x00\"))\n return (\n `an attribute name holds ${char} at byte ${position}, which is outside the ` +\n `name charset (${CHARSET})`\n )\n }\n case \"Ident32Empty\":\n return \"an attribute name is empty\"\n\n // ── the attribute list ───────────────────────────────────────────────────\n case \"SystemAttributeNotWritable\":\n return (\n `\"${identName(args[0])}\" is owned by the engine and cannot be written. Only $payload and ` +\n \"$contentType are yours to set\"\n )\n case \"TombstoneInCreate\":\n return (\n `a create cannot unset \"${identName(args[0])}\" — nothing exists yet, so leave the name ` +\n \"out instead\"\n )\n case \"TombstoneValueNotEmpty\":\n return `the tombstone for \"${identName(args[0])}\" carries a value; unsetting takes no value`\n case \"InvalidValueType\":\n return `\"${identName(args[0])}\" names type id ${String(args[1])}, which is not a known type`\n case \"AttributesNotSorted\":\n return \"attributes must be strictly ascending by name, which also makes each name unique\"\n case \"TooManyAttributes\":\n return `${String(args[0])} attributes exceeds the limit of ${String(args[1])}`\n case \"EmptyMutations\":\n return `the patch of ${short(args[0])} has no mutations, so it would do nothing`\n\n // ── entity state and authorisation ───────────────────────────────────────\n case \"EntityNotFound\":\n return `no entity ${short(args[0])} — it may have been deleted, or have expired`\n case \"EntityExpired\":\n return `entity ${short(args[0])} expired at block ${String(args[1])}`\n case \"NotOwner\":\n return `entity ${short(args[0])} is owned by ${String(args[2])}, not ${String(args[1])}`\n case \"ReadOnlyEntity\":\n return (\n `entity ${short(args[0])} was created readonly, so its contents can never change. Its ` +\n \"expiry can still be extended, and it can be transferred or deleted\"\n )\n case \"ReservedCreationFlags\":\n return (\n `creation flags 0b${Number(args[0] ?? 0)\n .toString(2)\n .padStart(8, \"0\")} set a reserved ` +\n \"bit; only readonly and permissionlessExtension are defined\"\n )\n\n // ── expiry ───────────────────────────────────────────────────────────────\n case \"ExpiryDeadOnArrival\":\n return (\n `the expiry resolves to block ${String(args[0])}, which is not after the current block ` +\n `${String(args[1])}`\n )\n case \"ExpiryNotExtended\":\n return (\n `entity ${short(args[0])} already expires at block ${String(args[2])}, so extending it ` +\n `to ${String(args[1])} would shorten its life`\n )\n\n // ── ownership ────────────────────────────────────────────────────────────\n case \"TransferToZeroAddress\":\n return `entity ${short(args[0])} cannot be transferred to the zero address`\n case \"TransferToSelf\":\n return `entity ${short(args[0])} is already owned by that account`\n\n // ── batch framing ────────────────────────────────────────────────────────\n case \"EmptyBatch\":\n return \"the batch has no operations\"\n case \"InvalidOpType\":\n return `operation tag ${String(args[0])} is not one the engine knows`\n case \"NonCanonicalOperationData\":\n return (\n `the payload for operation tag ${String(args[0])} is not its canonical encoding, so the ` +\n \"engine refused it rather than accept a second spelling of the same operation\"\n )\n\n default:\n return undefined\n }\n}\n\n/** A `bytes32` Ident32 cell as the name it holds — left-aligned, null-padded. */\nfunction identName(raw: unknown): string {\n if (typeof raw !== \"string\") return String(raw)\n try {\n // Cut at the first null rather than trimming with a regex: the padding is whatever follows\n // the name, so everything before it is the name and nothing after it is. Written as an escape\n // because a literal NUL byte in source is invisible to every reader after you.\n return hexToString(raw as Hex).split(\"\\u0000\")[0] ?? \"\"\n } catch {\n return raw\n }\n}\n\n/** An entity key, abbreviated */\nfunction short(raw: unknown): string {\n const text = String(raw)\n return text.length > 18 ? `${text.slice(0, 10)}…${text.slice(-6)}` : text\n}\n\n/** A `bytes1` as something readable: the character it is, plus the byte it was. */\nfunction printable(byte: string): string {\n const code = Number.parseInt(byte.replace(/^0x/, \"\"), 16)\n if (!Number.isFinite(code)) return `byte ${byte}`\n const char = String.fromCharCode(code)\n return code >= 0x21 && code <= 0x7e ? `\"${char}\" (${byte})` : `byte ${byte}`\n}\n","import {\n type Address,\n ContractFunctionExecutionError,\n ContractFunctionRevertedError,\n decodeEventLog,\n type Hex,\n parseAbi,\n TransactionExecutionError,\n type TransactionReceipt,\n} from \"viem\"\nimport type { ChangeOwnershipParameters } from \"../actions/wallet/changeOwnership\"\nimport type { CreateEntityParameters } from \"../actions/wallet/createEntity\"\nimport type { DeleteEntityParameters } from \"../actions/wallet/deleteEntity\"\nimport type { ExtendEntityParameters } from \"../actions/wallet/extendEntity\"\nimport type { PatchEntityParameters } from \"../actions/wallet/patchEntity\"\n// Internal seam: the ABI encoders are not part of the package's public surface.\nimport { encodeAttributes, encodeMutations } from \"../attr/attributes\"\nimport type { ArkivClient } from \"../clients/baseClient\"\nimport type { WalletArkivClient } from \"../clients/createWalletClient\"\nimport { ARKIV_ADDRESS } from \"../consts\"\nimport { ENTITY_EVENTS_ABI } from \"../entity/events\"\nimport { resolveExpiry } from \"../entity/expiry\"\nimport { encodeCreationFlags } from \"../entity/flags\"\nimport { randomSalt, resolveSalt } from \"../entity/key\"\nimport {\n createOperation,\n deleteOperation,\n EXECUTE_ABI as EXECUTE_FUNCTION_ABI,\n extendExpiryOperation,\n type Operation,\n patchOperation,\n transferOwnershipOperation,\n} from \"../entity/operations\"\nimport { EmptyPatchError, EntityMutationError, InvalidContentTypeError } from \"../errors\"\nimport type { TxParams } from \"../types\"\n\nimport { getLogger } from \"./logger\"\nimport { describeEntityRevert } from \"./revert\"\n\nconst logger = getLogger(\"utils:arkiv-transactions\")\n\n// RFC 2045 token chars, lowercase only. Rejects uppercase to prevent text/plain vs Text/Plain ambiguity.\nconst MIME_REGEX = /^[a-z][a-z0-9!#$&\\-^_]*\\/[a-z0-9][a-z0-9!#$&\\-^_.+]*$/\n\nfunction validateContentType(contentType: string): void {\n if (!MIME_REGEX.test(contentType)) {\n throw new InvalidContentTypeError(contentType)\n }\n}\n\nexport const ENTITY_ERRORS_ABI = parseAbi([\n // Batch and operation framing.\n \"error EmptyBatch()\",\n \"error InvalidOpType(uint8 operation)\",\n \"error NonCanonicalOperationData(uint8 operation)\",\n // The attribute triple list, structural.\n \"error AttributesNotSorted()\",\n \"error TooManyAttributes(uint256 count, uint256 maxCount)\",\n \"error EmptyMutations(bytes32 entityKey)\",\n \"error TombstoneInCreate(bytes32 name)\",\n \"error TombstoneValueNotEmpty(bytes32 name)\",\n \"error SystemAttributeNotWritable(bytes32 name)\",\n \"error InvalidValueType(bytes32 name, uint8 typeId)\",\n // Attribute-name validation. `Ident32` is a bytes32 on the wire.\n \"error Ident32Empty()\",\n \"error Ident32InvalidByte(uint256 position, bytes1 value)\",\n // Entity state and authorisation.\n \"error EntityNotFound(bytes32 entityKey)\",\n \"error EntityExpired(bytes32 entityKey, uint64 expiresAt)\",\n \"error NotOwner(bytes32 entityKey, address caller, address owner)\",\n \"error ReadOnlyEntity(bytes32 entityKey)\",\n \"error ReservedCreationFlags(uint8 creationFlags)\",\n // Expiry. The engine bounds an expiry only by the width of the field and by liveness — there is\n // no MAX_EXPIRES_AT or MAX_LIFETIME, so there is no error for exceeding one.\n \"error ExpiryDeadOnArrival(uint64 target, uint64 currentBlock)\",\n \"error ExpiryNotExtended(bytes32 entityKey, uint64 newExpiresAt, uint64 currentExpiresAt)\",\n // Ownership transfer.\n \"error TransferToZeroAddress(bytes32 entityKey)\",\n \"error TransferToSelf(bytes32 entityKey)\",\n])\n\nconst EXECUTE_ABI = [...EXECUTE_FUNCTION_ABI, ...ENTITY_ERRORS_ABI]\n\nexport type SendArkivTransactionResult = {\n receipt: TransactionReceipt\n /** The keys the engine minted for the entities this transaction created, in batch order. */\n createdEntityKeys: Hex[]\n /** The block each created entity expires at, as the engine recorded it, in the same order. */\n createdExpiries: bigint[]\n /** The block each extended entity now expires at, as the engine recorded it, in batch order. */\n extendedExpiries: bigint[]\n}\n\nexport async function sendArkivTransaction(\n client: ArkivClient,\n ops: {\n creates?: CreateEntityParameters[]\n patches?: PatchEntityParameters[]\n deletes?: DeleteEntityParameters[]\n extensions?: ExtendEntityParameters[]\n ownershipChanges?: ChangeOwnershipParameters[]\n },\n txParams?: TxParams,\n): Promise<SendArkivTransactionResult> {\n if (!client.account) throw new Error(\"Account required\")\n if (!client.chain) throw new Error(\"Chain required\")\n const walletClient = client as WalletArkivClient\n\n const { creates, patches, deletes, extensions, ownershipChanges } = ops\n\n // The block height, to resolve any relative expiry — which both creates and extensions carry.\n // Skipped entirely for a batch with neither.\n const currentBlock =\n creates?.length || extensions?.length ? await walletClient.getBlockNumber() : 0n\n\n const expiryContext = { currentBlock }\n\n const createOps = (creates ?? []).map((item) => {\n validateContentType(item.contentType)\n\n const salt = item.salt === undefined ? randomSalt() : resolveSalt(item.salt)\n const expiry = resolveExpiry(item.expires, expiryContext)\n\n return createOperation({\n salt,\n expiry,\n creationFlags: encodeCreationFlags(item.flags),\n attributes: encodeAttributes(item.attributes, {\n payload: item.payload,\n contentType: item.contentType,\n }),\n })\n })\n\n const patchOps = (patches ?? []).map((item) => {\n if (item.contentType !== undefined) validateContentType(item.contentType)\n const mutations = encodeMutations(item)\n if (mutations.length === 0) {\n throw new EmptyPatchError(item.entityKey)\n }\n return patchOperation({ entityKey: item.entityKey, mutations })\n })\n\n // An extension resolves its expiry exactly as a create does — the engine applies the same\n // `max(expiresAt, currentBlock + minLifetime)` to both — so the same bounds are checked here\n // rather than left to a revert.\n const extendOps = (extensions ?? []).map((item) => {\n const expiry = resolveExpiry(item.expires, expiryContext)\n return extendExpiryOperation({ entityKey: item.entityKey, expiry })\n })\n\n const operations: Operation[] = [\n ...createOps,\n ...patchOps,\n ...(deletes ?? []).map((item) => deleteOperation({ entityKey: item.entityKey })),\n ...extendOps,\n ...(ownershipChanges ?? []).map((item) =>\n transferOwnershipOperation({\n entityKey: item.entityKey,\n newOwner: item.newOwner as Address,\n }),\n ),\n ]\n\n if (operations.length === 0) {\n throw new Error(\"No operations to perform\")\n }\n\n logger(\"Sending execute with %d operations %o\", operations.length, operations)\n\n let txHash: Hex | undefined\n\n try {\n txHash = await walletClient.writeContract({\n address: ARKIV_ADDRESS,\n abi: EXECUTE_ABI,\n functionName: \"execute\",\n args: [operations],\n account: client.account,\n chain: client.chain,\n ...txParams,\n })\n\n const receipt = await walletClient.waitForTransactionReceipt({ hash: txHash })\n logger(\"Tx receipt %o\", receipt)\n\n if (receipt.status === \"reverted\") {\n try {\n await walletClient.simulateContract({\n address: ARKIV_ADDRESS,\n abi: EXECUTE_ABI,\n functionName: \"execute\",\n args: [operations],\n account: client.account,\n chain: client.chain,\n })\n } catch (err) {\n const error = err as { shortMessage?: string; cause?: { details?: string } }\n const reason =\n describeEntityRevert(err) ??\n error.shortMessage ??\n error.cause?.details ??\n \"No reason provided by backend.\"\n throw new EntityMutationError(\n `Transaction ${receipt.transactionHash} reverted. Reason: ${reason}`,\n { cause: err, txHash: receipt.transactionHash },\n )\n }\n throw new EntityMutationError(\n `Transaction ${receipt.transactionHash} reverted. No reason provided by backend.`,\n { txHash: receipt.transactionHash },\n )\n }\n\n return {\n receipt,\n ...readAppliedOperations(receipt, {\n creates: createOps.length,\n extensions: extendOps.length,\n }),\n }\n } catch (error) {\n const described = error instanceof EntityMutationError ? undefined : describeEntityRevert(error)\n if (described !== undefined) {\n throw new EntityMutationError(`Transaction failed: ${described}`, { cause: error, txHash })\n }\n\n let message = \"Transaction failed\"\n if (error instanceof TransactionExecutionError) {\n message += `: ${error.details}`\n } else if (error instanceof ContractFunctionExecutionError) {\n logger(\"Contract function execution error data:\", error.shortMessage)\n if (error.cause instanceof ContractFunctionRevertedError) {\n message += `: ${error.cause.message}`\n } else {\n message += \": Execution error without revert data\"\n }\n } else if (error instanceof EntityMutationError) {\n throw error\n } else if (error instanceof Error) {\n message += `: ${error.message}`\n }\n\n throw new EntityMutationError(message, { cause: error, txHash })\n }\n}\n\n/**\n * The keys and expiries the engine recorded, read back from the events the batch emitted.\n */\nfunction readAppliedOperations(\n receipt: TransactionReceipt,\n expected: { creates: number; extensions: number },\n): Omit<SendArkivTransactionResult, \"receipt\"> {\n const createdEntityKeys: Hex[] = []\n const createdExpiries: bigint[] = []\n const extendedExpiries: bigint[] = []\n\n // `?? []` so a receipt without logs is reported by the count check below, which explains what is\n // missing and that the write succeeded, rather than as a TypeError from this loop.\n for (const log of receipt.logs ?? []) {\n // Only the operation address emits these, and a batch's transaction can carry logs from\n // anything else it touched.\n if (log.address.toLowerCase() !== ARKIV_ADDRESS.toLowerCase()) continue\n const decoded = decodeEntityLog(log)\n if (decoded === undefined) continue\n\n if (decoded.eventName === \"EntityCreated\") {\n createdEntityKeys.push(decoded.args.entityKey)\n createdExpiries.push(decoded.args.expiresAt)\n } else if (decoded.eventName === \"ExpiryExtended\") {\n extendedExpiries.push(decoded.args.expiresAt)\n }\n }\n\n // Operations apply in batch order and emit one event each, and creates lead the batch — so these\n // arrive already aligned with the parameters they came from. A count that disagrees means that\n // assumption broke, and a misaligned array would hand back a key belonging to another entity.\n assertCount(receipt, \"create\", createdEntityKeys.length, expected.creates)\n assertCount(receipt, \"extension\", extendedExpiries.length, expected.extensions)\n\n return { createdEntityKeys, createdExpiries, extendedExpiries }\n}\n\n/** One log as an entity event, or `undefined` for anything this SDK has no name for. */\nfunction decodeEntityLog(log: TransactionReceipt[\"logs\"][number]) {\n try {\n return decodeEventLog({ abi: ENTITY_EVENTS_ABI, topics: log.topics, data: log.data })\n } catch {\n // An event a newer engine emits and this ABI does not describe. Not this function's business.\n return undefined\n }\n}\n\nfunction assertCount(receipt: TransactionReceipt, what: string, got: number, want: number): void {\n if (got === want) return\n // Deliberately explicit that the write succeeded: this throws *after* a successful transaction,\n // and a caller who reads it as a failure and retries would create the entities a second time.\n throw new EntityMutationError(\n `Transaction ${receipt.transactionHash} succeeded — do not retry it — but emitted ${got} ` +\n `${what} event(s) for ${want} ${what} operation(s). The batch was applied; the SDK cannot ` +\n `say which entity each operation produced, so read them back to find them.`,\n { txHash: receipt.transactionHash },\n )\n}\n","import type { Hash, Hex } from \"viem\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { TxParams } from \"../../types\"\nimport { sendArkivTransaction } from \"../../utils/arkivTransactions\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:wallet:change-ownership\")\n\n/**\n * Parameters for the changeOwnership function.\n * - entityKey: The key of the entity.\n * - newOwner: The address of the new owner.\n */\nexport type ChangeOwnershipParameters = {\n entityKey: Hex\n newOwner: Hex\n}\n\n/**\n * Return type for the changeOwnership function.\n * - entityKey: The key of the entity.\n * - txHash: The transaction hash.\n */\nexport type ChangeOwnershipReturnType = {\n entityKey: Hex\n txHash: Hash\n}\n\nexport async function changeOwnership(\n client: ArkivClient,\n data: ChangeOwnershipParameters,\n txParams?: TxParams,\n): Promise<ChangeOwnershipReturnType> {\n logger(\"changeOwnership %o\", data)\n const { receipt } = await sendArkivTransaction(client, { ownershipChanges: [data] }, txParams)\n\n logger(\"Receipt from changeOwnership %o\", receipt)\n\n return {\n txHash: receipt.transactionHash,\n entityKey: data.entityKey,\n }\n}\n","import type { Hash, Hex } from \"viem\"\nimport type { AttributeInputs } from \"../../attr\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { CreationFlags, Expiry, NO_SALT, SaltInput } from \"../../entity\"\nimport { EntityMutationError } from \"../../errors\"\nimport type { MimeType, TxParams } from \"../../types\"\nimport { sendArkivTransaction } from \"../../utils/arkivTransactions\"\nimport type { ExpirationTime } from \"../../utils/expirationTime\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:wallet:create-entity\")\n\n/**\n * Parameters for creating an entity.\n *\n * An entity always carries contents and a type for them, plus a lifetime. Attributes, flags and a\n * salt are optional on top of that.\n *\n * @example\n * const { entityKey } = await client.createEntity({\n * attributes: {\n * level: i32(10),\n * balance: u256(1_000_000n),\n * score: dec(\"3.5\"),\n * name: \"Bob\", // bare string -> str\n * flagged: true, // bare boolean -> bool\n * },\n * payload: jsonToPayload({ hello: \"world\" }),\n * contentType: \"application/json\",\n * expires: ExpirationTime.fromDays(30),\n * flags: { readonly: true },\n * })\n *\n * @example Pin an absolute deadline, but refuse to create something nearly dead:\n * await client.createEntity({\n * payload, contentType: \"application/json\",\n * expires: ExpirationTime.atDate(someDeadline, {\n * atLeast: ExpirationTime.fromDays(1), // ...but live at least a day regardless\n * }),\n * })\n *\n * @example An entity that is nothing but queryable attributes still declares its (empty) contents:\n * await client.createEntity({\n * attributes: { parent: key(parentKey), rank: i32(3) },\n * payload: new Uint8Array(),\n * contentType: \"application/octet-stream\",\n * expires: ExpirationTime.fromDays(30),\n * })\n */\nexport type CreateEntityParameters = {\n /**\n * How long the entity should live, built with {@link ExpirationTime}.\n *\n * `ExpirationTime.fromDays(30)` is the everyday form. `atBlock` / `atDate` pin an absolute\n * deadline instead, and either can carry `{ atLeast }` to guarantee a minimum life on top of it.\n */\n expires: Expiry\n /**\n * The entity's opaque payload. Travels to the engine as the `$payload` system attribute; on this\n * surface it is just the entity's contents.\n *\n * Pass an empty `Uint8Array` for an entity that is nothing but queryable attributes — it is\n * written as an empty payload rather than left unset, so what you pass is what is stored.\n */\n payload: Uint8Array\n /** The payload's MIME type, e.g. `\"application/json\"`. Sent as the `$contentType` cell. */\n contentType: MimeType | (string & {})\n /**\n * The entity's queryable attributes, keyed by name. Values are the tagged constructors from\n * `@arkiv-network/sdk/attr` — `i32`, `u64`, `u256`, `dec`, `str`, `addr`, `key`, `bytes32`,\n * `bool` — or a bare `boolean`, `number`, `bigint` or `string` where the type is unambiguous.\n *\n * @throws {InvalidAttributeNameError} If a name violates the attribute-name grammar.\n * @throws {InvalidValueError} If a value does not fit the type it names or defaults to.\n */\n attributes?: AttributeInputs | undefined\n /**\n * Properties fixed at creation: `readonly` and `permissionlessExtension`. No operation changes\n * them afterwards, so an entity is whatever it was created as for life. Both default to `false`.\n */\n flags?: CreationFlags | undefined\n /**\n * The salt mixed into the entity key. Defaults to 128 random bits, which makes the key\n * unpredictable to everyone but the creator.\n *\n * Pass {@link NO_SALT} for a key derived from the owner and nonce alone — predictable by anyone,\n * which is what you want only when a third party must be able to compute the key in advance.\n */\n salt?: SaltInput | undefined\n}\n\n/**\n * The result of creating an entity.\n */\nexport type CreateEntityReturnType = {\n /** The new entity's key. */\n entityKey: Hex\n txHash: Hash\n /**\n * The block the entity is expected to expire at, resolved against the block the transaction was\n * built on.\n *\n * The engine resolves a duration against the block the transaction actually lands in, so for\n * `ExpirationTime.fromDays(30)` and friends this is a lower bound: the real expiry is later by\n * however many blocks passed between building and inclusion. An `atBlock` deadline is exact.\n */\n expiresAt: bigint\n}\n\nexport async function createEntity(\n client: ArkivClient,\n data: CreateEntityParameters,\n txParams?: TxParams,\n): Promise<CreateEntityReturnType> {\n logger(\"createEntity %o\", data)\n const { receipt, createdEntityKeys, createdExpiries } = await sendArkivTransaction(\n client,\n { creates: [data] },\n txParams,\n )\n\n logger(\"Receipt from createEntity %o\", receipt)\n\n const [entityKey] = createdEntityKeys\n const [expiresAt] = createdExpiries\n if (entityKey === undefined || expiresAt === undefined) {\n throw new EntityMutationError(\n `Transaction ${receipt.transactionHash} succeeded, but the receipt did not carry the expected entity key or expiry.`,\n { txHash: receipt.transactionHash },\n )\n }\n\n return {\n txHash: receipt.transactionHash as Hash,\n entityKey,\n expiresAt,\n }\n}\n","import type { Hash, Hex } from \"viem\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { TxParams } from \"../../types\"\nimport { sendArkivTransaction } from \"../../utils/arkivTransactions\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:wallet:delete-entity\")\n\n/**\n * Parameters for the deleteEntity function.\n * - entityKey: The key of the entity to delete.\n */\nexport type DeleteEntityParameters = {\n entityKey: Hex\n}\n\n/**\n * Return type for the deleteEntity function.\n * - entityKey: The key of the entity.\n * - txHash: The transaction hash.\n */\nexport type DeleteEntityReturnType = {\n entityKey: Hex\n txHash: Hash\n}\n\nexport async function deleteEntity(\n client: ArkivClient,\n data: DeleteEntityParameters,\n txParams?: TxParams,\n): Promise<DeleteEntityReturnType> {\n logger(\"deleteEntity %o\", data)\n const { receipt } = await sendArkivTransaction(client, { deletes: [data] }, txParams)\n\n logger(\"Receipt from deleteEntity %o\", receipt)\n\n return {\n txHash: receipt.transactionHash as Hash,\n entityKey: data.entityKey,\n }\n}\n","import type { Hash, Hex } from \"viem\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { TxParams } from \"../../types\"\nimport { sendArkivTransaction } from \"../../utils/arkivTransactions\"\nimport { getLogger } from \"../../utils/logger\"\nimport type { ChangeOwnershipParameters } from \"./changeOwnership\"\nimport type { CreateEntityParameters } from \"./createEntity\"\nimport type { DeleteEntityParameters } from \"./deleteEntity\"\nimport type { ExtendEntityParameters } from \"./extendEntity\"\nimport type { PatchEntityParameters } from \"./patchEntity\"\n\nconst logger = getLogger(\"actions:wallet:execute-batch\")\n\n/**\n * Parameters for the executeBatch function.\n *\n * At least one operation is required; a batch with nothing in it throws rather than spending gas on\n * an empty transaction.\n */\nexport type ExecuteBatchParameters = {\n /** The entities to create. */\n creates?: CreateEntityParameters[]\n /** The patches to apply. */\n patches?: PatchEntityParameters[]\n /** The entities to delete. */\n deletes?: DeleteEntityParameters[]\n /** The expiries to set. */\n extensions?: ExtendEntityParameters[]\n /** The ownership transfers to perform. */\n ownershipChanges?: ChangeOwnershipParameters[]\n}\n\n/** Return type for the executeBatch function. */\nexport type ExecuteBatchReturnType = {\n /** The transaction hash. */\n txHash: Hash\n /** The keys of the created entities, in batch order. */\n createdEntities: Hex[]\n /** The keys of the patched entities. */\n patchedEntities: Hex[]\n /** The keys of the deleted entities. */\n deletedEntities: Hex[]\n /** The keys of the extended entities. */\n extendedEntities: Hex[]\n /** The keys of the entities handed to a new owner. */\n ownershipChanges: Hex[]\n}\n\nexport async function executeBatch(\n client: ArkivClient,\n data: ExecuteBatchParameters,\n txParams?: TxParams,\n): Promise<ExecuteBatchReturnType> {\n const { receipt, createdEntityKeys } = await sendArkivTransaction(client, data, txParams)\n\n logger(\"Receipt from executeBatch %o\", receipt)\n\n return {\n txHash: receipt.transactionHash as Hash,\n createdEntities: createdEntityKeys,\n patchedEntities: (data.patches ?? []).map((p) => p.entityKey),\n deletedEntities: (data.deletes ?? []).map((d) => d.entityKey),\n extendedEntities: (data.extensions ?? []).map((e) => e.entityKey),\n ownershipChanges: (data.ownershipChanges ?? []).map((o) => o.entityKey),\n }\n}\n","import type { Hash, Hex } from \"viem\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { Expiry } from \"../../entity\"\nimport { EntityMutationError } from \"../../errors\"\nimport type { TxParams } from \"../../types\"\nimport { sendArkivTransaction } from \"../../utils/arkivTransactions\"\nimport type { ExpirationTime } from \"../../utils/expirationTime\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:wallet:extend-entity\")\n\n/**\n * Parameters for extending an entity's life.\n *\n * An extension **sets a new expiry**; it does not add to the existing one. It is resolved exactly\n * as a create's is — a duration counts from now, not from the entity's current expiry — so\n * `ExpirationTime.fromDays(30)` means \"alive for thirty more days from now\" whatever the entity's\n * remaining life happened to be.\n *\n * The engine rejects an extension that would not move the expiry later, so extending an entity by\n * less than it already has left is an error rather than a silent shortening.\n *\n * @example\n * await client.extendEntity({ entityKey, expires: ExpirationTime.fromDays(30) })\n * await client.extendEntity({ entityKey, expires: ExpirationTime.atBlock(1_200_000n) })\n */\nexport type ExtendEntityParameters = {\n entityKey: Hex\n /** The entity's new lifetime, built with {@link ExpirationTime}. */\n expires: Expiry\n}\n\n/**\n * The result of extending an entity.\n */\nexport type ExtendEntityReturnType = {\n entityKey: Hex\n txHash: Hash\n /**\n * The block the entity is now expected to expire at, resolved against the block the transaction\n * was built on. Durations are approximate, so treat this as the estimate the operation was built\n * from rather than the block the engine settled on.\n */\n expiresAt: bigint\n}\n\nexport async function extendEntity(\n client: ArkivClient,\n data: ExtendEntityParameters,\n txParams?: TxParams,\n): Promise<ExtendEntityReturnType> {\n logger(\"extendEntity %o\", data)\n const { receipt, extendedExpiries } = await sendArkivTransaction(\n client,\n { extensions: [data] },\n txParams,\n )\n\n logger(\"Receipt from extendEntity %o\", receipt)\n\n const [expiresAt] = extendedExpiries\n if (expiresAt === undefined) {\n throw new EntityMutationError(\n `Transaction ${receipt.transactionHash} succeeded, but the receipt did not carry the expected entity expiry.`,\n { txHash: receipt.transactionHash },\n )\n }\n\n return {\n txHash: receipt.transactionHash as Hash,\n entityKey: data.entityKey,\n expiresAt,\n }\n}\n","import type { Hash, Hex } from \"viem\"\nimport type { AttributeInputs } from \"../../attr\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { MimeType, TxParams } from \"../../types\"\nimport { sendArkivTransaction } from \"../../utils/arkivTransactions\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:wallet:patch-entity\")\n\n/**\n * Parameters for patching an entity.\n *\n * A patch names only what changes. Attributes it does not mention keep whatever value they have, and\n * the payload and content type stay as they are unless given — so a caller can change one field\n * without first reading the entity to learn what the others are, and without racing anyone else who\n * is changing a different field.\n *\n * The entity's identity is fixed: a patch never moves the key, the owner, the creation flags or the\n * expiry. Use `extendEntity` for the expiry and `changeOwnership` for the owner.\n *\n * @example Change one attribute and remove another, leaving the payload alone:\n * await client.patchEntity({\n * entityKey,\n * set: { status: \"published\", level: i32(11) },\n * unset: [\"draft\"],\n * })\n *\n * @example Replace the contents without touching a single attribute:\n * await client.patchEntity({\n * entityKey,\n * payload: jsonToPayload({ hello: \"again\" }),\n * })\n */\nexport type PatchEntityParameters = {\n /** The entity to patch. */\n entityKey: Hex\n /**\n * Attributes to write, keyed by name. An existing attribute is overwritten — including with a\n * different type — and a name the entity does not carry yet is added.\n *\n * Values are the tagged constructors from `@arkiv-network/sdk/attr` — `i32`, `u64`, `u256`,\n * `dec`, `str`, `addr`, `key`, `bytes32`, `bool` — or a bare `boolean`, `number`, `bigint` or\n * `string` where the type is unambiguous.\n *\n * @throws {InvalidAttributeNameError} If a name violates the attribute-name grammar.\n * @throws {InvalidValueError} If a value does not fit the type it names or defaults to.\n */\n set?: AttributeInputs | undefined\n /**\n * Attribute names to remove. Naming one the entity does not carry is not an error — the outcome\n * is the same either way, and a caller clearing a field should not have to know whether it was\n * ever set.\n *\n * @throws {ConflictingMutationError} If a name also appears in `set`.\n */\n unset?: readonly string[] | undefined\n /**\n * The entity's new payload. Omit it to leave the current contents untouched; pass an empty\n * `Uint8Array` to replace them with nothing.\n */\n payload?: Uint8Array | undefined\n /**\n * The payload's new MIME type. Omit it to keep the current one — which is what you want when the\n * new payload is the same kind of thing as the old.\n */\n contentType?: MimeType | (string & {}) | undefined\n}\n\n/** The result of patching an entity. */\nexport type PatchEntityReturnType = {\n /** The patched entity's key — unchanged, since a patch never moves it. */\n entityKey: Hex\n txHash: Hash\n}\n\nexport async function patchEntity(\n client: ArkivClient,\n data: PatchEntityParameters,\n txParams?: TxParams,\n): Promise<PatchEntityReturnType> {\n logger(\"patchEntity %o\", data)\n const { receipt } = await sendArkivTransaction(client, { patches: [data] }, txParams)\n\n logger(\"Receipt from patchEntity %o\", receipt)\n\n return {\n txHash: receipt.transactionHash as Hash,\n entityKey: data.entityKey,\n }\n}\n","import type { Account, Chain, Client, PublicActions, Transport, WalletActions } from \"viem\"\nimport type {\n ChangeOwnershipParameters,\n ChangeOwnershipReturnType,\n} from \"../../actions/wallet/changeOwnership\"\nimport { changeOwnership } from \"../../actions/wallet/changeOwnership\"\nimport {\n type CreateEntityParameters,\n type CreateEntityReturnType,\n createEntity,\n} from \"../../actions/wallet/createEntity\"\nimport type {\n DeleteEntityParameters,\n DeleteEntityReturnType,\n} from \"../../actions/wallet/deleteEntity\"\nimport { deleteEntity } from \"../../actions/wallet/deleteEntity\"\nimport type {\n ExecuteBatchParameters,\n ExecuteBatchReturnType,\n} from \"../../actions/wallet/executeBatch\"\nimport { executeBatch } from \"../../actions/wallet/executeBatch\"\nimport type {\n ExtendEntityParameters,\n ExtendEntityReturnType,\n} from \"../../actions/wallet/extendEntity\"\nimport { extendEntity } from \"../../actions/wallet/extendEntity\"\nimport type { PatchEntityParameters, PatchEntityReturnType } from \"../../actions/wallet/patchEntity\"\nimport { patchEntity } from \"../../actions/wallet/patchEntity\"\nimport type { TxParams } from \"../../types\"\n\nexport type WalletArkivActions<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n account extends Account | undefined = Account | undefined,\n> = Pick<\n PublicActions<transport, chain, account>,\n \"waitForTransactionReceipt\" | \"call\" | \"simulateContract\" | \"readContract\" | \"getBlockNumber\"\n> &\n Pick<\n WalletActions<chain, account>,\n | \"addChain\"\n | \"sendCalls\"\n | \"waitForCallsStatus\"\n | \"sendTransaction\"\n | \"sendRawTransaction\"\n | \"signMessage\"\n | \"signTransaction\"\n | \"writeContract\"\n > & {\n /**\n * Creates a new entity.\n *\n * - JSON-RPC Methods: `eth_sendRawTransaction`\n *\n * @param data - The entity creation parameters\n * @param txParams - Optional transaction parameters\n * @returns The new entity's key, the transaction hash, and the block it is expected to\n * expire at. {@link CreateEntityReturnType}\n *\n * @throws {InvalidExpiryError} If the expiry exceeds a protocol bound or would leave the\n * entity dead on arrival.\n * @throws {InvalidValueError} If an attribute value does not fit the type it names.\n * @throws {InvalidAttributeNameError} If a name violates the attribute-name grammar.\n *\n * @example\n * import { createWalletClient, ExpirationTime, jsonToPayload } from \"@arkiv-network/sdk\"\n * import { i32 } from \"@arkiv-network/sdk/attr\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n * import { privateKeyToAccount } from \"viem/accounts\"\n *\n * const client = createWalletClient({\n * account: privateKeyToAccount(\"0x...\"),\n * chain: cheesecake,\n * transport: http(),\n * })\n * const { entityKey, txHash, expiresAt } = await client.createEntity({\n * payload: jsonToPayload({ entityType: \"testType\", entityId: \"testId\" }),\n * contentType: \"application/json\",\n * attributes: { testKey: \"testValue\", level: i32(3) },\n * expires: ExpirationTime.fromDays(30),\n * })\n */\n createEntity: (\n data: CreateEntityParameters,\n txParams?: TxParams,\n ) => Promise<CreateEntityReturnType>\n\n /**\n * Applies a patch to the entity with the given key: sets some fields, unsets others, and leaves\n * everything it does not name alone.\n *\n * - JSON-RPC Methods: `eth_sendRawTransaction`\n *\n * @param data - The entity key and the mutations to apply\n * @param txParams - Optional transaction parameters\n * @returns The patched entity's key and the transaction hash. {@link PatchEntityReturnType}\n *\n * @throws {EmptyPatchError} If the patch has nothing to apply.\n * @throws {ConflictingMutationError} If a name appears in both `set` and `unset`.\n * @throws {InvalidValueError} If an attribute value does not fit the type it names.\n * @throws {InvalidAttributeNameError} If a name violates the attribute-name grammar.\n *\n * @example\n * import { createWalletClient, jsonToPayload } from \"@arkiv-network/sdk\"\n * import { i32 } from \"@arkiv-network/sdk/attr\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n * import { privateKeyToAccount } from \"viem/accounts\"\n *\n * const client = createWalletClient({\n * account: privateKeyToAccount(\"0x...\"),\n * chain: cheesecake,\n * transport: http(),\n * })\n * // Publish the entity: one attribute changes, one goes away, the payload is replaced.\n * const { txHash } = await client.patchEntity({\n * entityKey,\n * set: { status: \"published\", revision: i32(2) },\n * unset: [\"draft\"],\n * payload: jsonToPayload({ title: \"Hello\" }),\n * })\n */\n patchEntity: (\n data: PatchEntityParameters,\n txParams?: TxParams,\n ) => Promise<PatchEntityReturnType>\n\n /**\n * Deletes the entity with the given key.\n *\n * - JSON-RPC Methods: `eth_sendRawTransaction`\n *\n * @param data - The entity deletion parameters\n * @param txParams - Optional transaction parameters\n * @returns The deleted entity's key and the transaction hash. {@link DeleteEntityReturnType}\n *\n * @example\n * import { createWalletClient } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n * import { privateKeyToAccount } from \"viem/accounts\"\n *\n * const client = createWalletClient({\n * account: privateKeyToAccount(\"0x...\"),\n * chain: cheesecake,\n * transport: http(),\n * })\n * // entityKey is the bytes32 key returned by createEntity.\n * const { txHash } = await client.deleteEntity({ entityKey })\n */\n deleteEntity: (\n data: DeleteEntityParameters,\n txParams?: TxParams,\n ) => Promise<DeleteEntityReturnType>\n\n /**\n * Sets a new expiry on the entity with the given key.\n *\n * The new lifetime is resolved the same way a create's is: a duration counts from now rather\n * than adding to what the entity has left, and `atBlock` / `atDate` pin an absolute deadline.\n * The engine rejects an extension that would not move the expiry later.\n *\n * - JSON-RPC Methods: `eth_sendRawTransaction`\n *\n * @param data - The entity key and its new lifetime\n * @param txParams - Optional transaction parameters\n * @returns The entity's key, the transaction hash, and the block it is now expected to expire\n * at. {@link ExtendEntityReturnType}\n *\n * @throws {InvalidExpiryError} If the expiry is malformed, exceeds a protocol bound, or would\n * leave the entity dead on arrival.\n *\n * @example\n * import { createWalletClient, ExpirationTime } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n * import { privateKeyToAccount } from \"viem/accounts\"\n *\n * const client = createWalletClient({\n * account: privateKeyToAccount(\"0x...\"),\n * chain: cheesecake,\n * transport: http(),\n * })\n * const { txHash, expiresAt } = await client.extendEntity({\n * entityKey,\n * expires: ExpirationTime.fromDays(30),\n * })\n */\n extendEntity: (\n data: ExtendEntityParameters,\n txParams?: TxParams,\n ) => Promise<ExtendEntityReturnType>\n\n /**\n * Hands the entity with the given key to a new owner.\n *\n * - JSON-RPC Methods: `eth_sendRawTransaction`\n *\n * @param data - The ownership change parameters\n * @param txParams - Optional transaction parameters\n * @returns The entity's key and the transaction hash. {@link ChangeOwnershipReturnType}\n */\n changeOwnership: (\n data: ChangeOwnershipParameters,\n txParams?: TxParams,\n ) => Promise<ChangeOwnershipReturnType>\n\n /**\n * Applies a batch of entity operations — creates, patches, deletes, extensions and ownership\n * transfers — in one transaction.\n *\n * - JSON-RPC Methods: `eth_sendRawTransaction`\n *\n * Every operation lands in one transaction, so the whole batch applies or none of it does.\n * At least one operation is required.\n *\n * @param data - The batch parameters (creates, patches, deletes, extensions, ownershipChanges)\n * @param txParams - Optional transaction parameters\n * @returns The transaction hash, plus the keys touched by each kind of operation.\n * {@link ExecuteBatchReturnType}\n *\n * @throws {InvalidExpiryError} If an expiry exceeds a protocol bound or would leave the entity\n * dead on arrival.\n * @throws {InvalidValueError} If an attribute value does not fit the type it names.\n *\n * @example\n * import { createWalletClient, ExpirationTime, jsonToPayload } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n * import { privateKeyToAccount } from \"viem/accounts\"\n *\n * const client = createWalletClient({\n * account: privateKeyToAccount(\"0x...\"),\n * chain: cheesecake,\n * transport: http(),\n * })\n * const { txHash, createdEntities } = await client.executeBatch({\n * creates: [{\n * payload: jsonToPayload({ entityType: \"testType\", entityId: \"testId\" }),\n * contentType: \"application/json\",\n * attributes: { testKey: \"testValue\" },\n * expires: ExpirationTime.fromDays(30),\n * }],\n * patches: [{ entityKey: keyToRevise, set: { status: \"archived\" }, unset: [\"draft\"] }],\n * deletes: [{ entityKey: staleKey }],\n * extensions: [{\n * entityKey: keyToKeepAlive,\n * expires: ExpirationTime.atBlock(1_200_000n),\n * }],\n * ownershipChanges: [{ entityKey: keyToHandOver, newOwner }],\n * })\n */\n executeBatch: (\n data: ExecuteBatchParameters,\n txParams?: TxParams,\n ) => Promise<ExecuteBatchReturnType>\n }\n\nexport function walletArkivActions<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n account extends Account | undefined = Account | undefined,\n>(client: Client<transport, chain, account>) {\n return {\n createEntity: (data: CreateEntityParameters, txParams?: TxParams) =>\n createEntity(client, data, txParams),\n patchEntity: (data: PatchEntityParameters, txParams?: TxParams) =>\n patchEntity(client, data, txParams),\n deleteEntity: (data: DeleteEntityParameters, txParams?: TxParams) =>\n deleteEntity(client, data, txParams),\n extendEntity: (data: ExtendEntityParameters, txParams?: TxParams) =>\n extendEntity(client, data, txParams),\n changeOwnership: (data: ChangeOwnershipParameters, txParams?: TxParams) =>\n changeOwnership(client, data, txParams),\n executeBatch: (data: ExecuteBatchParameters, txParams?: TxParams) =>\n executeBatch(client, data, txParams),\n }\n}\n","import type {\n Account,\n Address,\n Chain,\n Client,\n ParseAccount,\n Prettify,\n RpcSchema,\n Transport,\n WalletClientConfig,\n} from \"viem\"\nimport { createClient, publicActions, walletActions } from \"viem\"\nimport type { ArkivRpcSchema } from \"../types/rpcSchema\"\nimport { type WalletArkivActions, walletArkivActions } from \"./decorators/arkivWallet\"\n\nexport type WalletArkivClient<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n account extends Account | undefined = Account | undefined,\n rpcSchema extends RpcSchema | undefined = ArkivRpcSchema,\n> = Prettify<\n Client<transport, chain, account, rpcSchema, WalletArkivActions<transport, chain, account>>\n>\n\n/**\n * Creates a Wallet Client with a given [Transport](https://viem.sh/docs/clients/intro) configured\n * for a [Chain](https://viem.sh/docs/chains/introduction) and an account.\n *\n * A Wallet Client signs and sends transactions, so it carries an `account` and exposes everything\n * that mutates state — `createEntity`, `patchEntity`, `deleteEntity`, `extendEntity`,\n * `changeOwnership` and `executeBatch` — on top of the read actions a Public Client has.\n *\n * @param parameters - Configuration object for the wallet client (chain, transport, account, etc.)\n * @returns An Arkiv Wallet Client. {@link WalletArkivClient}\n *\n * @example\n * import { createWalletClient } from \"@arkiv-network/sdk\"\n * import { cheesecake } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n * import { privateKeyToAccount } from \"viem/accounts\"\n *\n * const client = createWalletClient({\n * chain: cheesecake,\n * transport: http(),\n * account: privateKeyToAccount(\"0x...\"),\n * })\n */\nexport function createWalletClient<\n transport extends Transport,\n chain extends Chain | undefined = undefined,\n accountOrAddress extends Account | Address | undefined = undefined,\n rpcSchema extends RpcSchema | undefined = ArkivRpcSchema,\n>(\n parameters: WalletClientConfig<transport, chain, accountOrAddress, rpcSchema>,\n): WalletArkivClient<transport, chain, ParseAccount<accountOrAddress>, rpcSchema> {\n const { key = \"wallet\", name = \"Wallet Client\" } = parameters\n const client = createClient({\n ...parameters,\n key,\n name,\n })\n\n return client\n .extend(publicActions)\n .extend(walletActions)\n .extend(walletArkivActions) as unknown as WalletArkivClient<\n transport,\n chain,\n ParseAccount<accountOrAddress>,\n rpcSchema\n >\n}\n","import type { Chain } from \"viem\"\nimport * as chains from \"../chains\"\n\n// Create a lookup map from all exported chains\nconst chainMap = new Map(Object.entries(chains).map(([key, value]) => [key.toLowerCase(), value]))\n\n/**\n * Get a chain from its name\n * @param name - The name of the chain, case insensitive\n * @returns The chain\n * @throws An error if the chain is not found\n */\nexport function chainFromName(name: string): Chain {\n const chain = chainMap.get(name.toLowerCase())\n if (!chain) {\n throw new Error(`Unknown chain: ${name}`)\n }\n return chain as Chain\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["logger","logger","query","logger","context: EntityEventContext","event: EntityEvent","key","logger","EXECUTE_ABI","EXECUTE_FUNCTION_ABI","operations: Operation[]","txHash: Hex | undefined","createdEntityKeys: Hex[]","createdExpiries: bigint[]","extendedExpiries: bigint[]","logger","logger","logger","logger","logger","chains","key"],"sources":["../src/actions/public/getBlockTiming.ts","../src/actions/public/getEntity.ts","../src/actions/public/getEntityCount.ts","../src/entity/operations.ts","../src/actions/public/getEntityNonce.ts","../src/actions/public/predictEntityKeys.ts","../src/actions/public/query.ts","../src/actions/public/watchEntityEvents.ts","../src/clients/decorators/arkivPublic.ts","../src/clients/createPublicClient.ts","../src/utils/revert.ts","../src/utils/arkivTransactions.ts","../src/actions/wallet/changeOwnership.ts","../src/actions/wallet/createEntity.ts","../src/actions/wallet/deleteEntity.ts","../src/actions/wallet/executeBatch.ts","../src/actions/wallet/extendEntity.ts","../src/actions/wallet/patchEntity.ts","../src/clients/decorators/arkivWallet.ts","../src/clients/createWalletClient.ts","../src/utils/chains.ts"],"sourcesContent":["import type { ArkivClient } from \"../../clients/baseClient\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:public:get-block-timing\")\n\nexport type GetBlockTimingReturnType = {\n currentBlock: bigint\n currentBlockTime: number\n blockDuration: number\n}\n\nexport async function getBlockTiming(client: ArkivClient) {\n const blockTiming = await client.request({\n method: \"arkiv_getBlockTiming\",\n params: [],\n })\n logger(\"Block timing %o\", blockTiming)\n return {\n currentBlock: BigInt(blockTiming.current_block),\n currentBlockTime: blockTiming.current_block_time,\n blockDuration: blockTiming.duration,\n }\n}\n","import type { Hex } from \"viem\"\nimport { key } from \"../../attr\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport { NoEntityFoundError } from \"../../errors\"\nimport { runQuery } from \"../../query/engine\"\nimport { eq } from \"../../query/expression\"\nimport { type FullEntity, toRpcSelect } from \"../../query/selection\"\nimport type { Entity } from \"../../types/entity\"\n\n/**\n * Reads one entity by key, with every field selected.\n *\n * Returns a {@link FullEntity} rather than an {@link Entity}: the selection is fixed at `\"*\"`, so\n * every field is populated and none of them needs a `?` at the call site. The bare `Entity` type\n * has every field optional because a `select()` result carries only what it asked for.\n *\n * @throws {InvalidValueError} If the key is not 32 bytes.\n * @throws {NoEntityFoundError} If no live entity has that key — it never existed, or it was\n * deleted or has expired.\n */\nexport async function getEntity(client: ArkivClient, entityKey: Hex): Promise<FullEntity> {\n const { entities } = await runQuery(client, {\n query: eq(\"$key\", key(entityKey)).toString(),\n select: toRpcSelect(\"*\"),\n limit: 1,\n })\n\n const entity = entities[0]\n if (entity === undefined) {\n throw new NoEntityFoundError(entityKey)\n }\n // Every field was selected, so the runtime Entity carries them all; the cast is the same\n // narrowing `client.select(\"*\")` gets from its own inference.\n return entity as unknown as FullEntity\n}\n","import type { ArkivClient } from \"../../clients/baseClient\"\n\nexport async function getEntityCount(client: ArkivClient) {\n const count = await client.request({\n method: \"arkiv_getEntityCount\",\n params: [],\n })\n\n return count\n}\n","import { type Address, encodeAbiParameters, type Hex, parseAbi, parseAbiParameters } from \"viem\"\nimport type { AbiAttribute } from \"../attr/codec\"\nimport type { EncodedExpiry } from \"./expiry\"\nimport type { predictEntityKey } from \"./key\"\nimport { OperationType } from \"./params\"\n\n/**\n * The one external entry point. A transaction is an ordered, **atomic** batch of entity operations:\n * all of them apply or none do, operation *n+1* observes operation *n*'s effects, and each applied\n * operation emits one event.\n */\nexport const EXECUTE_ABI = parseAbi([\n \"function execute((uint8 operation, bytes operationData)[] ops) external returns (bytes32[] keys)\",\n])\n\n/**\n * The engine's one read-only view: an owner's entity-minting nonce, which is the input\n * {@link predictEntityKey} needs and the only part of the derivation the caller cannot know.\n *\n * It is a `view` on the same address `execute` is called on, so it answers over `eth_call` without\n * a transaction.\n */\nexport const ENTITY_NONCE_ABI = parseAbi([\n \"function entityNonce(address owner) external view returns (uint64)\",\n])\n\n/**\n * The shared attribute shape, used by `create` (attributes) and `patch` (mutations). Written out\n * once and reused by every payload that carries attributes.\n */\nconst ATTRIBUTE_TUPLE = \"(bytes32 name, uint8 typeId, bytes value)[]\"\n\n/**\n * The payload struct for each operation tag. `operationData` is `abi.encode` of the struct the tag\n * selects — a tagged union, so a new operation is additive rather than a change to `execute`.\n */\nconst PAYLOAD_PARAMS = {\n [OperationType.Create]: parseAbiParameters(\n `(uint128 salt, uint64 expiresAt, uint64 minLifetime, uint8 creationFlags, ${ATTRIBUTE_TUPLE} attributes)`,\n ),\n [OperationType.Patch]: parseAbiParameters(`(bytes32 entityKey, ${ATTRIBUTE_TUPLE} mutations)`),\n [OperationType.ExtendExpiry]: parseAbiParameters(\n \"(bytes32 entityKey, uint64 expiresAt, uint64 minLifetime)\",\n ),\n [OperationType.TransferOwnership]: parseAbiParameters(\"(bytes32 entityKey, address newOwner)\"),\n [OperationType.Delete]: parseAbiParameters(\"(bytes32 entityKey)\"),\n} as const\n\n/** One entry of the `execute` batch: the operation tag and its ABI-encoded payload. */\nexport type Operation = {\n operation: number\n operationData: Hex\n}\n\n/** Creates an entity. The key is derived by the engine; predict it with `predictEntityKey`. */\nexport function createOperation({\n salt,\n expiry,\n creationFlags,\n attributes,\n}: {\n salt: bigint\n expiry: EncodedExpiry\n creationFlags: number\n attributes: AbiAttribute[]\n}): Operation {\n return {\n operation: OperationType.Create,\n operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.Create], [\n {\n salt,\n expiresAt: expiry.expiresAt,\n minLifetime: expiry.minLifetime,\n creationFlags,\n attributes,\n },\n ]),\n }\n}\n\n/** Applies a set of mutations to an existing entity. Tombstones unset attributes. */\nexport function patchOperation({\n entityKey,\n mutations,\n}: {\n entityKey: Hex\n mutations: AbiAttribute[]\n}): Operation {\n return {\n operation: OperationType.Patch,\n operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.Patch], [\n { entityKey, mutations },\n ]),\n }\n}\n\n/** Pushes an entity's expiry further out. Extending is allowed; shortening reverts. */\nexport function extendExpiryOperation({\n entityKey,\n expiry,\n}: {\n entityKey: Hex\n expiry: EncodedExpiry\n}): Operation {\n return {\n operation: OperationType.ExtendExpiry,\n operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.ExtendExpiry], [\n { entityKey, expiresAt: expiry.expiresAt, minLifetime: expiry.minLifetime },\n ]),\n }\n}\n\n/** Hands an entity to a new owner. */\nexport function transferOwnershipOperation({\n entityKey,\n newOwner,\n}: {\n entityKey: Hex\n newOwner: Address\n}): Operation {\n return {\n operation: OperationType.TransferOwnership,\n operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.TransferOwnership], [\n { entityKey, newOwner },\n ]),\n }\n}\n\n/** Deletes an entity before its expiry. */\nexport function deleteOperation({ entityKey }: { entityKey: Hex }): Operation {\n return {\n operation: OperationType.Delete,\n operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.Delete], [{ entityKey }]),\n }\n}\n","import type { Address } from \"viem\"\nimport { readContract } from \"viem/actions\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport { ARKIV_ADDRESS } from \"../../consts\"\nimport { ENTITY_NONCE_ABI } from \"../../entity/operations\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:public:get-entity-nonce\")\n\n/**\n * Reads an owner's entity-minting nonce — how many entities that account has created.\n *\n * This is not the account's transaction nonce. The engine keeps a separate counter per creator and\n * mixes it into every key it mints, which is what makes two identical creates from one account land\n * on different keys.\n *\n * @param owner - The account whose nonce to read.\n * @returns The number of entities `owner` has created so far, which is the nonce its next create\n * will use.\n */\nexport async function getEntityNonce(client: ArkivClient, owner: Address): Promise<bigint> {\n const nonce = await readContract(client, {\n address: ARKIV_ADDRESS,\n abi: ENTITY_NONCE_ABI,\n functionName: \"entityNonce\",\n args: [owner],\n })\n logger(\"entity nonce of %s is %s\", owner, nonce)\n return nonce\n}\n","import type { Address, Hex } from \"viem\"\nimport { getChainId } from \"viem/actions\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport {\n NO_SALT,\n predictEntityKey,\n randomSalt,\n resolveSalt,\n type SaltInput,\n} from \"../../entity/key\"\nimport { getEntityNonce } from \"./getEntityNonce\"\n\n/**\n * A key a create will be given, together with the salt that mints it.\n *\n * The two travel as a pair because neither is any use alone: a create defaults to a *random* salt,\n * so the key only comes out as predicted if that same create carries this salt.\n */\nexport type PredictedEntityKey = {\n /** The key the create will be given. */\n key: Hex\n /**\n * The salt the create must carry for its key to come out as {@link PredictedEntityKey.key}.\n * Always a plain `uint128` — a requested {@link NO_SALT} comes back as the `0n` it resolves to,\n * which a create accepts just the same.\n */\n salt: bigint\n}\n\n/** Parameters for `client.predictEntityKeys`. */\nexport type PredictEntityKeysParameters<\n TCount extends number = number,\n TSalts extends readonly SaltInput[] | undefined = readonly SaltInput[] | undefined,\n> = {\n /** The account that will sign the creates. Its nonce is what the keys are derived from. */\n owner: Address\n /**\n * How many creates the batch will carry. Ignored when `salts` is given, which already says how\n * many there are.\n *\n * A literal count comes back as a fixed-length tuple, so `count: 2` destructures into two named\n * pairs without a cast.\n */\n count?: TCount | undefined\n /**\n * The salt each create will carry, in batch order. Defaults to `count` fresh random salts —\n * either way each key comes back paired with the salt that mints it. Pass {@link NO_SALT} in a\n * slot whose create opts out of salting.\n */\n salts?: TSalts\n}\n\n/**\n * The keys a batch would mint, in batch order, each paired with its salt.\n *\n * The length follows the request whenever it is known statically: a literal `count`, or a `salts`\n * tuple, gives a fixed-length tuple; a count computed at runtime gives a plain array.\n *\n * `TSalts` is wrapped in a tuple to stop the conditional distributing over it. Left naked, the\n * `readonly SaltInput[] | undefined` default would take both branches and union a tuple with an\n * array, which widens the length straight back to `number`.\n */\nexport type PredictEntityKeysReturnType<\n TCount extends number = number,\n TSalts extends readonly SaltInput[] | undefined = readonly SaltInput[] | undefined,\n> = [TSalts] extends [readonly SaltInput[]]\n ? { -readonly [Index in keyof TSalts]: PredictedEntityKey }\n : Repeat<PredictedEntityKey, TCount>\n\n/**\n * A tuple of `TLength` × `T`, or a plain array when the length is only known at runtime.\n *\n * Written tail-recursively so TypeScript can build the batch sizes anyone would actually send.\n */\ntype Repeat<T, TLength extends number, TAcc extends T[] = []> = number extends TLength\n ? T[]\n : TAcc[\"length\"] extends TLength\n ? TAcc\n : Repeat<T, TLength, [...TAcc, T]>\n\n/**\n * Works out the keys an account's next creates will be given, before sending them.\n *\n * A key is `keccak256(chainId ++ registry ++ owner ++ nonce ++ salt)`. Everything but the nonce is\n * known to the caller, and the nonce is read here — so a batch can reference a key it is about to\n * mint, storing it as a `key` attribute on a sibling entity created in the same transaction.\n *\n * Each key arrives paired with its salt, and the create must be given that salt: a create left to\n * pick its own salt picks a random one, which mints a different key.\n *\n * The prediction is valid only while nothing else from this owner is in flight. Every create that\n * lands first takes the nonce with it and moves these keys. For a key you can rely on\n * unconditionally, read it back from the create instead — `createEntity` and `executeBatch`\n * report the keys the engine actually minted.\n *\n * @param parameters - Owner, and either a count or the salts. {@link PredictEntityKeysParameters}\n * @returns One `{ key, salt }` pair per create, in batch order. {@link PredictEntityKeysReturnType}\n *\n * @example A batch whose second entity points at its first.\n * import { key } from \"@arkiv-network/sdk/attr\"\n *\n * const [parent, child] = await client.predictEntityKeys({ owner: account.address, count: 2 })\n * await client.executeBatch({\n * creates: [\n * { payload, contentType, expires, salt: parent.salt },\n * {\n * payload,\n * contentType,\n * expires,\n * salt: child.salt,\n * attributes: { parent: key(parent.key) },\n * },\n * ],\n * })\n */\nexport async function predictEntityKeys<\n const TCount extends number = number,\n const TSalts extends readonly SaltInput[] | undefined = undefined,\n>(\n client: ArkivClient,\n { owner, count, salts }: PredictEntityKeysParameters<TCount, TSalts>,\n): Promise<PredictEntityKeysReturnType<TCount, TSalts>> {\n const resolvedSalts = resolveSalts(count, salts)\n\n const chainId = client.chain?.id ?? (await getChainId(client))\n const nonce = await getEntityNonce(client, owner)\n\n return resolvedSalts.map((salt, index) => ({\n key: predictEntityKey({ owner, nonce: nonce + BigInt(index), salt, chainId }),\n salt,\n })) as PredictEntityKeysReturnType<TCount, TSalts>\n}\n\n/** The salts to derive from: the ones given, or `count` fresh random ones. */\nfunction resolveSalts(\n count: number | undefined,\n salts: readonly SaltInput[] | undefined,\n): bigint[] {\n if (salts !== undefined) {\n if (salts.length === 0) {\n throw new Error(\"predictEntityKeys: `salts` is empty — there is nothing to predict\")\n }\n return salts.map(resolveSalt)\n }\n if (count === undefined) {\n throw new Error(\"predictEntityKeys: pass either `count` or `salts`\")\n }\n if (!Number.isInteger(count) || count <= 0) {\n throw new Error(`predictEntityKeys: \\`count\\` must be a positive whole number, got ${count}`)\n }\n return Array.from({ length: count }, () => randomSalt())\n}\n","import type { ArkivClient } from \"../../clients/baseClient\"\nimport { runQuery } from \"../../query/engine\"\nimport type { Expression } from \"../../query/expression\"\nimport { type SelectArg, toRpcSelect } from \"../../query/selection\"\nimport type { Entity } from \"../../types/entity\"\n\nexport type QueryOptions = {\n /** What to return. Defaults to everything. */\n select?: SelectArg | undefined\n /** Block height to read at. Defaults to the head. */\n atBlock?: bigint | undefined\n /** Page size, up to the node maximum of 200. */\n limit?: number | undefined\n /** Cursor from a previous page. */\n cursor?: string | undefined\n}\n\nexport type QueryReturnType = {\n entities: Entity[]\n /** The cursor for the next page, or `undefined` when no pages remain. */\n cursor: string | undefined\n /** The block the page was read at. */\n blockNumber: bigint\n}\n\n/**\n * Runs a single query and returns one page, with no builder in between.\n *\n * Takes either an {@link Expression} or a raw query string. The string form is an escape hatch for\n * a query built elsewhere — it goes to the node exactly as written, with none of the name, type or\n * operator checks the expression combinators apply.\n *\n * @throws {QueryError} If the node rejects the query.\n */\nexport function query(\n client: ArkivClient,\n query: Expression | string,\n options: QueryOptions = {},\n): Promise<QueryReturnType> {\n return runQuery(client, {\n query: query.toString(),\n select: toRpcSelect(options.select),\n limit: options.limit,\n cursor: options.cursor,\n atBlock: options.atBlock,\n })\n}\n","import { decodeEventLog, type Hex } from \"viem\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { PublicArkivClient } from \"../../clients/createPublicClient\"\nimport { ARKIV_ADDRESS, BLOCK_TIME } from \"../../consts\"\nimport { ENTITY_EVENTS_ABI } from \"../../entity/events\"\nimport { decodeCreationFlags } from \"../../entity/flags\"\nimport type {\n EntityCreatedEvent,\n EntityDeletedEvent,\n EntityEvent,\n EntityEventContext,\n EntityPatchedEvent,\n ExpiryExtendedEvent,\n OwnershipTransferredEvent,\n} from \"../../types/events\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:public:watch-entity-events\")\n\n/**\n * How often to poll, when the caller does not say.\n *\n * Half a block: fast enough that an event is never a whole block stale, slow enough not to hammer\n * the node. viem's own default is derived from a 12-second Ethereum block and is far too slow here.\n */\nconst DEFAULT_POLLING_INTERVAL = (BLOCK_TIME * 1000) / 2\n\n/**\n * Handlers and options for `client.watchEntityEvents`. Every handler is optional; the watcher does\n * the work for the ones you pass.\n */\nexport type WatchEntityEventsParameters = {\n onEntityCreated?: ((event: EntityCreatedEvent) => void) | undefined\n onEntityPatched?: ((event: EntityPatchedEvent) => void) | undefined\n onExpiryExtended?: ((event: ExpiryExtendedEvent) => void) | undefined\n onOwnershipTransferred?: ((event: OwnershipTransferredEvent) => void) | undefined\n onEntityDeleted?: ((event: EntityDeletedEvent) => void) | undefined\n /**\n * Every event, in application order, whatever its type. Runs *before* the per-event handler for\n * the same event.\n *\n * This is the replay seam: operations apply in batch order and emit one event each, so an\n * off-chain replica that consumes this in order sees exactly what the engine did.\n */\n onEvent?: ((event: EntityEvent) => void) | undefined\n /**\n * Transport failures, logs that will not decode, and anything one of your own handlers throws.\n *\n * Defaults to `console.error`. A watcher whose filter the node dropped otherwise just goes quiet,\n * and a quiet watcher is indistinguishable from a quiet chain.\n */\n onError?: ((error: Error) => void) | undefined\n /** Replay from this block before following the head. Defaults to the head. */\n fromBlock?: bigint | undefined\n /** How often to poll, in milliseconds. Defaults to half a block. */\n pollingInterval?: number | undefined\n}\n\n/**\n * Watches entity events, calling the handlers you pass as they arrive.\n *\n * Every event here is decoded from a log the Arkiv operation address emitted, and carries the\n * block, transaction and log index it came from — so consuming them in order replays exactly what\n * the engine did.\n *\n * @param parameters - Handlers and options. {@link WatchEntityEventsParameters}\n * @returns A function that stops the watcher.\n *\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({ chain: tiramisu, transport: http() })\n *\n * const unwatch = client.watchEntityEvents({\n * onEntityCreated: ({ entityKey, owner, expiresAt }) =>\n * console.log(\"created\", entityKey, \"by\", owner, \"until block\", expiresAt),\n * onEntityDeleted: ({ entityKey }) => console.log(\"deleted\", entityKey),\n * onError: (error) => console.error(error),\n * })\n *\n * unwatch()\n */\nexport function watchEntityEvents(\n client: ArkivClient,\n parameters: WatchEntityEventsParameters,\n): () => void {\n const {\n onEntityCreated,\n onEntityPatched,\n onExpiryExtended,\n onOwnershipTransferred,\n onEntityDeleted,\n onEvent,\n onError,\n fromBlock,\n pollingInterval = DEFAULT_POLLING_INTERVAL,\n } = parameters\n\n const publicClient = client as PublicArkivClient\n const reportError = onError ?? logToConsole\n\n function emit(event: EntityEvent): void {\n deliver(onEvent, event)\n switch (event.type) {\n case \"EntityCreated\":\n deliver(onEntityCreated, event)\n break\n case \"EntityPatched\":\n deliver(onEntityPatched, event)\n break\n case \"ExpiryExtended\":\n deliver(onExpiryExtended, event)\n break\n case \"OwnershipTransferred\":\n deliver(onOwnershipTransferred, event)\n break\n case \"EntityDeleted\":\n deliver(onEntityDeleted, event)\n break\n }\n }\n\n /**\n * Runs one handler, keeping its failure to itself.\n *\n * A handler that throws is the consumer's problem, not the watcher's: letting it escape would\n * reject the poll, drop the rest of the batch, and take down every other handler with it.\n */\n function deliver<TEvent>(handler: ((event: TEvent) => void) | undefined, event: TEvent): void {\n if (handler === undefined) return\n try {\n handler(event)\n } catch (error) {\n reportError(asError(error))\n }\n }\n\n const unwatchLogs = publicClient.watchEvent({\n // Only the Arkiv operation address emits these. Without the filter any contract whose event\n // happens to hash to the same topic lands in `onLogs`, and viem's observer key — which covers\n // the address but not `events` — would make this subscription collide with any other\n // unaddressed `watchEvent` on the same client.\n address: ARKIV_ADDRESS,\n events: ENTITY_EVENTS_ABI,\n pollingInterval,\n ...(fromBlock !== undefined && { fromBlock }),\n onLogs: (logs) => {\n logger(\"logs %o\", logs)\n for (const log of logs) {\n // A log with no position cannot be placed in application order, which is the one thing an\n // event consumer needs from it. Dropping it beats inventing a position it never had.\n if (log.blockNumber === null || log.transactionHash === null || log.logIndex === null) {\n continue\n }\n const context: EntityEventContext = {\n blockNumber: log.blockNumber,\n transactionHash: log.transactionHash,\n logIndex: log.logIndex,\n }\n\n // Only the decode is guarded here. Dispatch guards each handler separately, so a consumer's\n // exception is never reported as if the log were the thing that was malformed.\n let event: EntityEvent\n try {\n event = toEntityEvent(log.topics, log.data, context)\n } catch (error) {\n reportError(asError(error))\n continue\n }\n emit(event)\n }\n },\n onError: (error) => reportError(error),\n })\n\n return unwatchLogs\n}\n\n/** The fallback when no `onError` was given — see {@link WatchEntityEventsParameters.onError}. */\nfunction logToConsole(error: Error): void {\n console.error(\"watchEntityEvents error\", error)\n}\n\n/** Handlers take an `Error`, and a `throw` can be anything. */\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error))\n}\n\n/**\n * Decodes one log into the {@link EntityEvent} it carries.\n *\n * @throws If the log does not decode against {@link ENTITY_EVENTS_ABI}.\n */\nfunction toEntityEvent(\n topics: readonly Hex[],\n data: Hex,\n context: EntityEventContext,\n): EntityEvent {\n const decoded = decodeEventLog({\n abi: ENTITY_EVENTS_ABI,\n topics: topics as [Hex, ...Hex[]] | [],\n data,\n })\n\n switch (decoded.eventName) {\n case \"EntityCreated\":\n return {\n type: \"EntityCreated\",\n ...context,\n ...decoded.args,\n creationFlags: decodeCreationFlags(decoded.args.creationFlags),\n }\n case \"EntityPatched\":\n return { type: \"EntityPatched\", ...context, ...decoded.args }\n case \"ExpiryExtended\":\n return { type: \"ExpiryExtended\", ...context, ...decoded.args }\n case \"OwnershipTransferred\":\n return { type: \"OwnershipTransferred\", ...context, ...decoded.args }\n case \"EntityDeleted\":\n return { type: \"EntityDeleted\", ...context, ...decoded.args }\n }\n}\n","import type { Account, Address, Chain, Client, Hex, PublicActions, Transport } from \"viem\"\nimport { type GetBlockTimingReturnType, getBlockTiming } from \"../../actions/public/getBlockTiming\"\nimport { getEntity } from \"../../actions/public/getEntity\"\nimport { getEntityCount } from \"../../actions/public/getEntityCount\"\nimport { getEntityNonce } from \"../../actions/public/getEntityNonce\"\nimport {\n type PredictEntityKeysParameters,\n type PredictEntityKeysReturnType,\n predictEntityKeys,\n} from \"../../actions/public/predictEntityKeys\"\nimport { type QueryOptions, type QueryReturnType, query } from \"../../actions/public/query\"\nimport {\n type WatchEntityEventsParameters,\n watchEntityEvents,\n} from \"../../actions/public/watchEntityEvents\"\nimport type { SaltInput } from \"../../entity/key\"\nimport type { Expression } from \"../../query/expression\"\nimport { SelectQueryBuilder } from \"../../query/queryBuilder\"\nimport type { EntitySelection, FullEntity, ProjectedEntity, SelectArg } from \"../../query/selection\"\nimport type { Entity } from \"../../types/entity\"\n\nexport type PublicArkivActions<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n account extends Account | undefined = Account | undefined,\n> = Pick<\n PublicActions<transport, chain, account>,\n | \"getBalance\"\n | \"getBlock\"\n | \"getBlockNumber\"\n | \"getChainId\"\n | \"getLogs\"\n | \"getTransaction\"\n | \"getTransactionCount\"\n | \"getTransactionReceipt\"\n | \"waitForTransactionReceipt\"\n | \"watchEvent\"\n> & {\n /**\n * Returns the entity with the given key.\n *\n * - JSON-RPC Methods: `arkiv_query`\n *\n * @param key - The entity key (hex string)\n * @returns The entity with the given key, with every field populated. {@link FullEntity}\n *\n * @throws {InvalidValueError} If the key is not 32 bytes.\n * @throws {NoEntityFoundError} If no live entity has that key — it never existed, or it was\n * deleted or has expired.\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: tiramisu,\n * transport: http(),\n * })\n * const entity = await client.getEntity(entityKey)\n * // Entity {\n * // key: \"0x9f2c…\",\n * // owner: \"0xabc…\",\n * // contentType: \"application/json\",\n * // payload: Uint8Array, // entity.toJson() / entity.toText() decode it\n * // attributes: { category: { type: \"str\", value: \"docs\" } },\n * // expiresAt: 1_297_000n,\n * // }\n */\n getEntity: (key: Hex) => Promise<FullEntity>\n\n /**\n * Returns a SelectQueryBuilder for building and executing queries — the recommended way to\n * read entities. You declare up front which parts of an entity you want returned, so results\n * always contain exactly the data you asked for.\n *\n * - JSON-RPC Methods: `arkiv_query`\n *\n * @param selection - What to include in the results. Omit it (or pass `\"*\"`) to select everything,\n * or pass an object to select specific parts (at least one field is required). Every part is\n * opt-in, including the `key`. The selection is flat — each field maps to an entity field.\n * {@link SelectArg}\n * @returns A SelectQueryBuilder instance for building and executing queries. {@link SelectQueryBuilder}\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { eq } from \"@arkiv-network/sdk/query\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: tiramisu,\n * transport: http(),\n * })\n * // select everything\n * await client.select().where(eq(\"category\", \"docs\")).fetch()\n * await client.select(\"*\").where(eq(\"category\", \"docs\")).fetch()\n * // only the key\n * await client.select({ key: true }).where(eq(\"category\", \"docs\")).fetch()\n * // select specific fields — result typed { owner: Hex; attributes: Attributes }\n * await client.select({ owner: true, attributes: true }).fetch()\n * // a single field — result typed { owner: Hex }\n * await client.select({ owner: true }).fetch()\n */\n select: {\n /** Select every field. Pass nothing or `\"*\"`; the returned entities contain all fields. */\n (selection?: \"*\"): SelectQueryBuilder<FullEntity>\n /**\n * Pick the entity fields to return. Set the ones you want to `true` (at least one is required);\n * the result is typed to exactly those fields, so reading anything else is a compile error.\n *\n * Available fields: `key`, `owner`, `creator`, `createdAt`, `updatedAt`, `expiresAt`,\n * `creationFlags`, `contentType`, `payload`, `attributeSchema` and `attributes`.\n *\n * `attributes` also takes a map of names, to fetch only those:\n * `select({ key: true, attributes: { projectId: true } })`.\n *\n * Pass the selection inline so its fields stay literal `true`. A selection stored in a `let`/\n * `const` variable widens to `boolean` and the result type can no longer be narrowed — annotate\n * it `as const` (e.g. `const sel = { owner: true } as const`) in that case.\n *\n * @example\n * client.select({ owner: true, attributes: true }) // entities typed { owner, attributes }\n * client.select({ key: true, payload: true }) // includes payload → toText()/toJson() too\n * client.select({ key: true, attributeSchema: true }) // what shape is the data?\n */\n <const S extends EntitySelection>(selection: S): SelectQueryBuilder<ProjectedEntity<S>>\n /**\n * Dynamic selection: accepts a value typed {@link SelectArg} (e.g. built at runtime). The\n * result cannot be narrowed in this case, so the entities are typed as the full entity.\n */\n (selection: SelectArg): SelectQueryBuilder<FullEntity>\n }\n\n /**\n * Runs one query and returns one page, with no builder in between.\n *\n * Use {@link PublicArkivActions.select} for anything typed — this returns full {@link Entity} objects whatever the\n * selection, and takes a raw string as an escape hatch for a query built elsewhere. A raw string\n * goes to the node exactly as written, with none of the name, type or operator checks the\n * expression combinators apply.\n *\n * @param query - An {@link Expression}, or the raw query string.\n * @param queryOptions - Selection, page size, cursor and block. {@link QueryOptions}\n * @returns One page of entities. {@link QueryReturnType}\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { and, eq, gte } from \"@arkiv-network/sdk/query\"\n * import { i32 } from \"@arkiv-network/sdk/attr\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: tiramisu,\n * transport: http(),\n * })\n * const page = await client.query(and(eq(\"category\", \"docs\"), gte(\"level\", i32(10))), {\n * select: { key: true, attributes: true },\n * limit: 100,\n * })\n * // { entities: [Entity], cursor: \"b64:…\", blockNumber: 32223n }\n *\n * // The raw form, unchecked:\n * await client.query(\"category = str('docs') AND level >= i32(10)\")\n */\n query: (query: Expression | string, queryOptions?: QueryOptions) => Promise<QueryReturnType>\n\n /**\n * Returns the total number of entities on the chain.\n * @returns The number of entities currently stored\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: tiramisu,\n * transport: http(),\n * })\n * const entityCount = await client.getEntityCount()\n * // entityCount = 0\n */\n getEntityCount: () => Promise<number>\n\n /**\n * Returns how many entities an account has created — its entity-minting nonce.\n *\n * Not the account's transaction nonce: the engine keeps its own counter per creator and mixes it\n * into every key it mints, which is why two identical creates from one account never collide.\n *\n * @param owner - The account whose nonce to read.\n * @returns The nonce the account's next create will use.\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: tiramisu,\n * transport: http(),\n * })\n * const nonce = await client.getEntityNonce(\"0xabc…\")\n * // 7n — the next entity this account creates is its eighth\n */\n getEntityNonce: (owner: Address) => Promise<bigint>\n\n /**\n * Works out the keys an account's next creates will be given, before sending them.\n *\n * The engine derives a key from the chain, the registry, the owner, the owner's nonce and a\n * salt — everything but the nonce is known to the caller, and the nonce is read here. This is\n * what lets a batch reference an entity it is about to mint.\n *\n * Each key arrives paired with the salt that mints it, because a create defaults to a *random*\n * salt: a predicted key only holds if the create carries the salt it was predicted with. And the\n * prediction holds only while nothing else from this owner is in flight — for a key you can rely\n * on unconditionally, read it back from the create instead.\n *\n * A literal `count` comes back as a fixed-length tuple, so the pairs destructure into names.\n *\n * @param parameters - Owner, and either a count or the salts. {@link PredictEntityKeysParameters}\n * @returns One `{ key, salt }` pair per create, in batch order.\n * {@link PredictEntityKeysReturnType}\n *\n * @example A batch whose second entity points at its first.\n * import { key } from \"@arkiv-network/sdk/attr\"\n *\n * const [parent, child] = await client.predictEntityKeys({ owner: account.address, count: 2 })\n * await wallet.executeBatch({\n * creates: [\n * { payload, contentType, expires, salt: parent.salt },\n * {\n * payload,\n * contentType,\n * expires,\n * salt: child.salt,\n * attributes: { parent: key(parent.key) },\n * },\n * ],\n * })\n */\n predictEntityKeys: <\n const TCount extends number = number,\n const TSalts extends readonly SaltInput[] | undefined = undefined,\n >(\n parameters: PredictEntityKeysParameters<TCount, TSalts>,\n ) => Promise<PredictEntityKeysReturnType<TCount, TSalts>>\n\n /**\n * Returns the current block timing.\n * @returns The current block timing. {@link GetBlockTimingReturnType}\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: tiramisu,\n * transport: http(),\n * })\n * const blockTiming = await client.getBlockTiming()\n * // {\n * // currentBlock: 10n, // block number\n * // currentBlockTime: 1234567890, // block timestamp\n * // blockDuration: 2, // in seconds\n * // }\n */\n getBlockTiming: () => Promise<GetBlockTimingReturnType>\n\n /**\n * Watches entity events, calling the handlers you pass as they arrive.\n *\n * All five are decoded from logs — `onEntityCreated`, `onEntityPatched`, `onExpiryExtended`,\n * `onOwnershipTransferred`, `onEntityDeleted` — and each carries the block, transaction and log\n * index it came from, which is the order the operations were applied in. `onEvent` receives all\n * of them, whatever their type.\n *\n * @param parameters - Handlers and options, all optional. {@link WatchEntityEventsParameters}\n * @returns A function that stops the watcher.\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: tiramisu,\n * transport: http(),\n * })\n * const unwatch = client.watchEntityEvents({\n * onEntityCreated: ({ entityKey, expiresAt }) => console.log(entityKey, \"until\", expiresAt),\n * onError: (error) => console.error(\"watchEntityEvents error\", error),\n * })\n * unwatch() // stop watching\n */\n watchEntityEvents: (parameters: WatchEntityEventsParameters) => () => void\n}\n\nexport function publicArkivActions<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n account extends Account | undefined = Account | undefined,\n>(client: Client<transport, chain, account>) {\n return {\n getEntity: (key: Hex) => getEntity(client, key),\n query: (rawQuery: Expression | string, queryOptions?: QueryOptions) =>\n query(client, rawQuery, queryOptions),\n select: (selection?: SelectArg) => new SelectQueryBuilder(client, selection),\n getBlockTiming: () => getBlockTiming(client),\n getEntityCount: () => getEntityCount(client),\n getEntityNonce: (owner: Address) => getEntityNonce(client, owner),\n predictEntityKeys: <\n const TCount extends number = number,\n const TSalts extends readonly SaltInput[] | undefined = undefined,\n >(\n parameters: PredictEntityKeysParameters<TCount, TSalts>,\n ) => predictEntityKeys(client, parameters),\n watchEntityEvents: (parameters: WatchEntityEventsParameters) =>\n watchEntityEvents(client, parameters),\n }\n}\n","import type {\n Account,\n Address,\n Chain,\n Client,\n ParseAccount,\n Prettify,\n PublicClientConfig,\n RpcSchema,\n Transport,\n} from \"viem\"\nimport { createClient, publicActions } from \"viem\"\nimport type { ArkivRpcSchema } from \"../types/rpcSchema\"\nimport { type PublicArkivActions, publicArkivActions } from \"./decorators/arkivPublic\"\n\nexport type PublicArkivClient<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n accountOrAddress extends Account | undefined = undefined,\n rpcSchema extends RpcSchema | undefined = ArkivRpcSchema,\n> = Prettify<\n Client<transport, chain, accountOrAddress, rpcSchema, PublicArkivActions<transport, chain>>\n>\n\n/**\n * Creates a Public Client with a given [Transport](https://viem.sh/docs/clients/intro) configured for a [Chain](https://viem.sh/docs/chains/introduction).\n *\n * A Public Client is an interface to the \"public\" [Ethereum JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/)\n * and the Arkiv JSON-RPC API — retrieving block numbers and transactions, reading from\n * contracts, and querying entities — through {@link PublicArkivActions}.\n *\n * @param parameters - Configuration object for the public client (chain, transport, etc.)\n * @returns An Arkiv Public Client. {@link PublicArkivClient}\n *\n * @example\n * import { createPublicClient } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n *\n * const client = createPublicClient({\n * chain: tiramisu,\n * transport: http(),\n * })\n */\nexport function createPublicClient<\n transport extends Transport,\n chain extends Chain | undefined = undefined,\n accountOrAddress extends Account | Address | undefined = undefined,\n rpcSchema extends RpcSchema | undefined = ArkivRpcSchema,\n>(\n parameters: PublicClientConfig<transport, chain, accountOrAddress, rpcSchema>,\n): PublicArkivClient<transport, chain, ParseAccount<accountOrAddress>, rpcSchema> {\n const { key = \"public\", name = \"Public Client\" } = parameters\n const client = createClient({\n ...parameters,\n key,\n name,\n })\n\n return client.extend(publicActions).extend(publicArkivActions) as unknown as PublicArkivClient<\n transport,\n chain,\n ParseAccount<accountOrAddress>,\n rpcSchema\n >\n}\n","import { BaseError, ContractFunctionRevertedError, type Hex, hexToString } from \"viem\"\n\n/**\n * Turns a decoded engine revert into a sentence that says what to change.\n *\n * viem decodes the error and then renders it positionally — `Ident32InvalidByte(uint256 position,\n * bytes1 value)` arrives as `(5, 0x41)`, which is the right data and no help at all. The engine's\n * errors carry enough to name the actual problem, so this spends the args rather than printing\n * them.\n *\n * @param error - Anything thrown by a write action.\n * @returns The explanation, or `undefined` if this was not a decodable engine revert — in which\n * case the caller should fall back to whatever the transport said.\n */\nexport function describeEntityRevert(error: unknown): string | undefined {\n if (!(error instanceof BaseError)) return undefined\n const reverted = error.walk((e) => e instanceof ContractFunctionRevertedError)\n if (!(reverted instanceof ContractFunctionRevertedError)) return undefined\n\n const name = reverted.data?.errorName\n if (name === undefined) return undefined\n const args = (reverted.data?.args ?? []) as readonly unknown[]\n\n return explain(name, args) ?? `the engine rejected the batch with ${name}`\n}\n\n/** The attribute-name charset, quoted the way an error message should read. */\nconst CHARSET = '\"A\"-\"Z\", \"a\"-\"z\", \"0\"-\"9\", \".\", \"-\" and \"_\", with a letter first'\n\nfunction explain(name: string, args: readonly unknown[]): string | undefined {\n switch (name) {\n // ── attribute names ──────────────────────────────────────────────────────\n case \"Ident32InvalidByte\": {\n const position = Number(args[0] ?? 0)\n const char = printable(String(args[1] ?? \"0x00\"))\n return (\n `an attribute name holds ${char} at byte ${position}, which is outside the ` +\n `name charset (${CHARSET})`\n )\n }\n case \"Ident32Empty\":\n return \"an attribute name is empty\"\n\n // ── the attribute list ───────────────────────────────────────────────────\n case \"SystemAttributeNotWritable\":\n return (\n `\"${identName(args[0])}\" is owned by the engine and cannot be written. Only $payload and ` +\n \"$contentType are yours to set\"\n )\n case \"TombstoneInCreate\":\n return (\n `a create cannot unset \"${identName(args[0])}\" — nothing exists yet, so leave the name ` +\n \"out instead\"\n )\n case \"TombstoneValueNotEmpty\":\n return `the tombstone for \"${identName(args[0])}\" carries a value; unsetting takes no value`\n case \"InvalidValueType\":\n return `\"${identName(args[0])}\" names type id ${String(args[1])}, which is not a known type`\n case \"AttributesNotSorted\":\n return \"attributes must be strictly ascending by name, which also makes each name unique\"\n case \"TooManyAttributes\":\n return `${String(args[0])} attributes exceeds the limit of ${String(args[1])}`\n case \"EmptyMutations\":\n return `the patch of ${short(args[0])} has no mutations, so it would do nothing`\n\n // ── entity state and authorisation ───────────────────────────────────────\n case \"EntityNotFound\":\n return `no entity ${short(args[0])} — it may have been deleted, or have expired`\n case \"EntityExpired\":\n return `entity ${short(args[0])} expired at block ${String(args[1])}`\n case \"NotOwner\":\n return `entity ${short(args[0])} is owned by ${String(args[2])}, not ${String(args[1])}`\n case \"ReadOnlyEntity\":\n return (\n `entity ${short(args[0])} was created readonly, so its contents can never change. Its ` +\n \"expiry can still be extended, and it can be transferred or deleted\"\n )\n case \"ReservedCreationFlags\":\n return (\n `creation flags 0b${Number(args[0] ?? 0)\n .toString(2)\n .padStart(8, \"0\")} set a reserved ` +\n \"bit; only readonly and permissionlessExtension are defined\"\n )\n\n // ── expiry ───────────────────────────────────────────────────────────────\n case \"ExpiryDeadOnArrival\":\n return (\n `the expiry resolves to block ${String(args[0])}, which is not after the current block ` +\n `${String(args[1])}`\n )\n case \"ExpiryNotExtended\":\n return (\n `entity ${short(args[0])} already expires at block ${String(args[2])}, so extending it ` +\n `to ${String(args[1])} would shorten its life`\n )\n\n // ── ownership ────────────────────────────────────────────────────────────\n case \"TransferToZeroAddress\":\n return `entity ${short(args[0])} cannot be transferred to the zero address`\n case \"TransferToSelf\":\n return `entity ${short(args[0])} is already owned by that account`\n\n // ── batch framing ────────────────────────────────────────────────────────\n case \"EmptyBatch\":\n return \"the batch has no operations\"\n case \"InvalidOpType\":\n return `operation tag ${String(args[0])} is not one the engine knows`\n case \"NonCanonicalOperationData\":\n return (\n `the payload for operation tag ${String(args[0])} is not its canonical encoding, so the ` +\n \"engine refused it rather than accept a second spelling of the same operation\"\n )\n\n default:\n return undefined\n }\n}\n\n/** A `bytes32` Ident32 cell as the name it holds — left-aligned, null-padded. */\nfunction identName(raw: unknown): string {\n if (typeof raw !== \"string\") return String(raw)\n try {\n // Cut at the first null rather than trimming with a regex: the padding is whatever follows\n // the name, so everything before it is the name and nothing after it is. Written as an escape\n // because a literal NUL byte in source is invisible to every reader after you.\n return hexToString(raw as Hex).split(\"\\u0000\")[0] ?? \"\"\n } catch {\n return raw\n }\n}\n\n/** An entity key, abbreviated */\nfunction short(raw: unknown): string {\n const text = String(raw)\n return text.length > 18 ? `${text.slice(0, 10)}…${text.slice(-6)}` : text\n}\n\n/** A `bytes1` as something readable: the character it is, plus the byte it was. */\nfunction printable(byte: string): string {\n const code = Number.parseInt(byte.replace(/^0x/, \"\"), 16)\n if (!Number.isFinite(code)) return `byte ${byte}`\n const char = String.fromCharCode(code)\n return code >= 0x21 && code <= 0x7e ? `\"${char}\" (${byte})` : `byte ${byte}`\n}\n","import {\n type Address,\n ContractFunctionExecutionError,\n ContractFunctionRevertedError,\n decodeEventLog,\n type Hex,\n parseAbi,\n TransactionExecutionError,\n type TransactionReceipt,\n} from \"viem\"\nimport type { ChangeOwnershipParameters } from \"../actions/wallet/changeOwnership\"\nimport type { CreateEntityParameters } from \"../actions/wallet/createEntity\"\nimport type { DeleteEntityParameters } from \"../actions/wallet/deleteEntity\"\nimport type { ExtendEntityParameters } from \"../actions/wallet/extendEntity\"\nimport type { PatchEntityParameters } from \"../actions/wallet/patchEntity\"\n// Internal seam: the ABI encoders are not part of the package's public surface.\nimport { encodeAttributes, encodeMutations } from \"../attr/attributes\"\nimport type { ArkivClient } from \"../clients/baseClient\"\nimport type { WalletArkivClient } from \"../clients/createWalletClient\"\nimport { ARKIV_ADDRESS } from \"../consts\"\nimport { ENTITY_EVENTS_ABI } from \"../entity/events\"\nimport { resolveExpiry } from \"../entity/expiry\"\nimport { encodeCreationFlags } from \"../entity/flags\"\nimport { randomSalt, resolveSalt } from \"../entity/key\"\nimport {\n createOperation,\n deleteOperation,\n EXECUTE_ABI as EXECUTE_FUNCTION_ABI,\n extendExpiryOperation,\n type Operation,\n patchOperation,\n transferOwnershipOperation,\n} from \"../entity/operations\"\nimport { EmptyPatchError, EntityMutationError, InvalidContentTypeError } from \"../errors\"\nimport type { TxParams } from \"../types\"\n\nimport { getLogger } from \"./logger\"\nimport { describeEntityRevert } from \"./revert\"\n\nconst logger = getLogger(\"utils:arkiv-transactions\")\n\n// RFC 2045 token chars, lowercase only. Rejects uppercase to prevent text/plain vs Text/Plain ambiguity.\nconst MIME_REGEX = /^[a-z][a-z0-9!#$&\\-^_]*\\/[a-z0-9][a-z0-9!#$&\\-^_.+]*$/\n\nfunction validateContentType(contentType: string): void {\n if (!MIME_REGEX.test(contentType)) {\n throw new InvalidContentTypeError(contentType)\n }\n}\n\nexport const ENTITY_ERRORS_ABI = parseAbi([\n // Batch and operation framing.\n \"error EmptyBatch()\",\n \"error InvalidOpType(uint8 operation)\",\n \"error NonCanonicalOperationData(uint8 operation)\",\n // The attribute triple list, structural.\n \"error AttributesNotSorted()\",\n \"error TooManyAttributes(uint256 count, uint256 maxCount)\",\n \"error EmptyMutations(bytes32 entityKey)\",\n \"error TombstoneInCreate(bytes32 name)\",\n \"error TombstoneValueNotEmpty(bytes32 name)\",\n \"error SystemAttributeNotWritable(bytes32 name)\",\n \"error InvalidValueType(bytes32 name, uint8 typeId)\",\n // Attribute-name validation. `Ident32` is a bytes32 on the wire.\n \"error Ident32Empty()\",\n \"error Ident32InvalidByte(uint256 position, bytes1 value)\",\n // Entity state and authorisation.\n \"error EntityNotFound(bytes32 entityKey)\",\n \"error EntityExpired(bytes32 entityKey, uint64 expiresAt)\",\n \"error NotOwner(bytes32 entityKey, address caller, address owner)\",\n \"error ReadOnlyEntity(bytes32 entityKey)\",\n \"error ReservedCreationFlags(uint8 creationFlags)\",\n // Expiry. The engine bounds an expiry only by the width of the field and by liveness — there is\n // no MAX_EXPIRES_AT or MAX_LIFETIME, so there is no error for exceeding one.\n \"error ExpiryDeadOnArrival(uint64 target, uint64 currentBlock)\",\n \"error ExpiryNotExtended(bytes32 entityKey, uint64 newExpiresAt, uint64 currentExpiresAt)\",\n // Ownership transfer.\n \"error TransferToZeroAddress(bytes32 entityKey)\",\n \"error TransferToSelf(bytes32 entityKey)\",\n])\n\nconst EXECUTE_ABI = [...EXECUTE_FUNCTION_ABI, ...ENTITY_ERRORS_ABI]\n\nexport type SendArkivTransactionResult = {\n receipt: TransactionReceipt\n /** The keys the engine minted for the entities this transaction created, in batch order. */\n createdEntityKeys: Hex[]\n /** The block each created entity expires at, as the engine recorded it, in the same order. */\n createdExpiries: bigint[]\n /** The block each extended entity now expires at, as the engine recorded it, in batch order. */\n extendedExpiries: bigint[]\n}\n\nexport async function sendArkivTransaction(\n client: ArkivClient,\n ops: {\n creates?: CreateEntityParameters[]\n patches?: PatchEntityParameters[]\n deletes?: DeleteEntityParameters[]\n extensions?: ExtendEntityParameters[]\n ownershipChanges?: ChangeOwnershipParameters[]\n },\n txParams?: TxParams,\n): Promise<SendArkivTransactionResult> {\n if (!client.account) throw new Error(\"Account required\")\n if (!client.chain) throw new Error(\"Chain required\")\n const walletClient = client as WalletArkivClient\n\n const { creates, patches, deletes, extensions, ownershipChanges } = ops\n\n // The block height, to resolve any relative expiry — which both creates and extensions carry.\n // Skipped entirely for a batch with neither.\n const currentBlock =\n creates?.length || extensions?.length ? await walletClient.getBlockNumber() : 0n\n\n const expiryContext = { currentBlock }\n\n const createOps = (creates ?? []).map((item) => {\n validateContentType(item.contentType)\n\n const salt = item.salt === undefined ? randomSalt() : resolveSalt(item.salt)\n const expiry = resolveExpiry(item.expires, expiryContext)\n\n return createOperation({\n salt,\n expiry,\n creationFlags: encodeCreationFlags(item.flags),\n attributes: encodeAttributes(item.attributes, {\n payload: item.payload,\n contentType: item.contentType,\n }),\n })\n })\n\n const patchOps = (patches ?? []).map((item) => {\n if (item.contentType !== undefined) validateContentType(item.contentType)\n const mutations = encodeMutations(item)\n if (mutations.length === 0) {\n throw new EmptyPatchError(item.entityKey)\n }\n return patchOperation({ entityKey: item.entityKey, mutations })\n })\n\n // An extension resolves its expiry exactly as a create does — the engine applies the same\n // `max(expiresAt, currentBlock + minLifetime)` to both — so the same bounds are checked here\n // rather than left to a revert.\n const extendOps = (extensions ?? []).map((item) => {\n const expiry = resolveExpiry(item.expires, expiryContext)\n return extendExpiryOperation({ entityKey: item.entityKey, expiry })\n })\n\n const operations: Operation[] = [\n ...createOps,\n ...patchOps,\n ...(deletes ?? []).map((item) => deleteOperation({ entityKey: item.entityKey })),\n ...extendOps,\n ...(ownershipChanges ?? []).map((item) =>\n transferOwnershipOperation({\n entityKey: item.entityKey,\n newOwner: item.newOwner as Address,\n }),\n ),\n ]\n\n if (operations.length === 0) {\n throw new Error(\"No operations to perform\")\n }\n\n logger(\"Sending execute with %d operations %o\", operations.length, operations)\n\n let txHash: Hex | undefined\n\n try {\n txHash = await walletClient.writeContract({\n address: ARKIV_ADDRESS,\n abi: EXECUTE_ABI,\n functionName: \"execute\",\n args: [operations],\n account: client.account,\n chain: client.chain,\n ...txParams,\n })\n\n const receipt = await walletClient.waitForTransactionReceipt({ hash: txHash })\n logger(\"Tx receipt %o\", receipt)\n\n if (receipt.status === \"reverted\") {\n try {\n await walletClient.simulateContract({\n address: ARKIV_ADDRESS,\n abi: EXECUTE_ABI,\n functionName: \"execute\",\n args: [operations],\n account: client.account,\n chain: client.chain,\n })\n } catch (err) {\n const error = err as { shortMessage?: string; cause?: { details?: string } }\n const reason =\n describeEntityRevert(err) ??\n error.shortMessage ??\n error.cause?.details ??\n \"No reason provided by backend.\"\n throw new EntityMutationError(\n `Transaction ${receipt.transactionHash} reverted. Reason: ${reason}`,\n { cause: err, txHash: receipt.transactionHash },\n )\n }\n throw new EntityMutationError(\n `Transaction ${receipt.transactionHash} reverted. No reason provided by backend.`,\n { txHash: receipt.transactionHash },\n )\n }\n\n return {\n receipt,\n ...readAppliedOperations(receipt, {\n creates: createOps.length,\n extensions: extendOps.length,\n }),\n }\n } catch (error) {\n const described = error instanceof EntityMutationError ? undefined : describeEntityRevert(error)\n if (described !== undefined) {\n throw new EntityMutationError(`Transaction failed: ${described}`, { cause: error, txHash })\n }\n\n let message = \"Transaction failed\"\n if (error instanceof TransactionExecutionError) {\n message += `: ${error.details}`\n } else if (error instanceof ContractFunctionExecutionError) {\n logger(\"Contract function execution error data:\", error.shortMessage)\n if (error.cause instanceof ContractFunctionRevertedError) {\n message += `: ${error.cause.message}`\n } else {\n message += \": Execution error without revert data\"\n }\n } else if (error instanceof EntityMutationError) {\n throw error\n } else if (error instanceof Error) {\n message += `: ${error.message}`\n }\n\n throw new EntityMutationError(message, { cause: error, txHash })\n }\n}\n\n/**\n * The keys and expiries the engine recorded, read back from the events the batch emitted.\n */\nfunction readAppliedOperations(\n receipt: TransactionReceipt,\n expected: { creates: number; extensions: number },\n): Omit<SendArkivTransactionResult, \"receipt\"> {\n const createdEntityKeys: Hex[] = []\n const createdExpiries: bigint[] = []\n const extendedExpiries: bigint[] = []\n\n // `?? []` so a receipt without logs is reported by the count check below, which explains what is\n // missing and that the write succeeded, rather than as a TypeError from this loop.\n for (const log of receipt.logs ?? []) {\n // Only the operation address emits these, and a batch's transaction can carry logs from\n // anything else it touched.\n if (log.address.toLowerCase() !== ARKIV_ADDRESS.toLowerCase()) continue\n const decoded = decodeEntityLog(log)\n if (decoded === undefined) continue\n\n if (decoded.eventName === \"EntityCreated\") {\n createdEntityKeys.push(decoded.args.entityKey)\n createdExpiries.push(decoded.args.expiresAt)\n } else if (decoded.eventName === \"ExpiryExtended\") {\n extendedExpiries.push(decoded.args.expiresAt)\n }\n }\n\n // Operations apply in batch order and emit one event each, and creates lead the batch — so these\n // arrive already aligned with the parameters they came from. A count that disagrees means that\n // assumption broke, and a misaligned array would hand back a key belonging to another entity.\n assertCount(receipt, \"create\", createdEntityKeys.length, expected.creates)\n assertCount(receipt, \"extension\", extendedExpiries.length, expected.extensions)\n\n return { createdEntityKeys, createdExpiries, extendedExpiries }\n}\n\n/** One log as an entity event, or `undefined` for anything this SDK has no name for. */\nfunction decodeEntityLog(log: TransactionReceipt[\"logs\"][number]) {\n try {\n return decodeEventLog({ abi: ENTITY_EVENTS_ABI, topics: log.topics, data: log.data })\n } catch {\n // An event a newer engine emits and this ABI does not describe. Not this function's business.\n return undefined\n }\n}\n\nfunction assertCount(receipt: TransactionReceipt, what: string, got: number, want: number): void {\n if (got === want) return\n // Deliberately explicit that the write succeeded: this throws *after* a successful transaction,\n // and a caller who reads it as a failure and retries would create the entities a second time.\n throw new EntityMutationError(\n `Transaction ${receipt.transactionHash} succeeded — do not retry it — but emitted ${got} ` +\n `${what} event(s) for ${want} ${what} operation(s). The batch was applied; the SDK cannot ` +\n `say which entity each operation produced, so read them back to find them.`,\n { txHash: receipt.transactionHash },\n )\n}\n","import type { Hash, Hex } from \"viem\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { TxParams } from \"../../types\"\nimport { sendArkivTransaction } from \"../../utils/arkivTransactions\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:wallet:change-ownership\")\n\n/**\n * Parameters for the changeOwnership function.\n * - entityKey: The key of the entity.\n * - newOwner: The address of the new owner.\n */\nexport type ChangeOwnershipParameters = {\n entityKey: Hex\n newOwner: Hex\n}\n\n/**\n * Return type for the changeOwnership function.\n * - entityKey: The key of the entity.\n * - txHash: The transaction hash.\n */\nexport type ChangeOwnershipReturnType = {\n entityKey: Hex\n txHash: Hash\n}\n\nexport async function changeOwnership(\n client: ArkivClient,\n data: ChangeOwnershipParameters,\n txParams?: TxParams,\n): Promise<ChangeOwnershipReturnType> {\n logger(\"changeOwnership %o\", data)\n const { receipt } = await sendArkivTransaction(client, { ownershipChanges: [data] }, txParams)\n\n logger(\"Receipt from changeOwnership %o\", receipt)\n\n return {\n txHash: receipt.transactionHash,\n entityKey: data.entityKey,\n }\n}\n","import type { Hash, Hex } from \"viem\"\nimport type { AttributeInputs } from \"../../attr\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { CreationFlags, Expiry, NO_SALT, SaltInput } from \"../../entity\"\nimport { EntityMutationError } from \"../../errors\"\nimport type { MimeType, TxParams } from \"../../types\"\nimport { sendArkivTransaction } from \"../../utils/arkivTransactions\"\nimport type { ExpirationTime } from \"../../utils/expirationTime\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:wallet:create-entity\")\n\n/**\n * Parameters for creating an entity.\n *\n * An entity always carries contents and a type for them, plus a lifetime. Attributes, flags and a\n * salt are optional on top of that.\n *\n * @example\n * const { entityKey } = await client.createEntity({\n * attributes: {\n * level: i32(10),\n * balance: u256(1_000_000n),\n * score: dec(\"3.5\"),\n * name: \"Bob\", // bare string -> str\n * flagged: true, // bare boolean -> bool\n * },\n * payload: jsonToPayload({ hello: \"world\" }),\n * contentType: \"application/json\",\n * expires: ExpirationTime.fromDays(30),\n * flags: { readonly: true },\n * })\n *\n * @example Pin an absolute deadline, but refuse to create something nearly dead:\n * await client.createEntity({\n * payload, contentType: \"application/json\",\n * expires: ExpirationTime.atDate(someDeadline, {\n * atLeast: ExpirationTime.fromDays(1), // ...but live at least a day regardless\n * }),\n * })\n *\n * @example An entity that is nothing but queryable attributes still declares its (empty) contents:\n * await client.createEntity({\n * attributes: { parent: key(parentKey), rank: i32(3) },\n * payload: new Uint8Array(),\n * contentType: \"application/octet-stream\",\n * expires: ExpirationTime.fromDays(30),\n * })\n */\nexport type CreateEntityParameters = {\n /**\n * How long the entity should live, built with {@link ExpirationTime}.\n *\n * `ExpirationTime.fromDays(30)` is the everyday form. `atBlock` / `atDate` pin an absolute\n * deadline instead, and either can carry `{ atLeast }` to guarantee a minimum life on top of it.\n */\n expires: Expiry\n /**\n * The entity's opaque payload. Travels to the engine as the `$payload` system attribute; on this\n * surface it is just the entity's contents.\n *\n * Pass an empty `Uint8Array` for an entity that is nothing but queryable attributes — it is\n * written as an empty payload rather than left unset, so what you pass is what is stored.\n */\n payload: Uint8Array\n /** The payload's MIME type, e.g. `\"application/json\"`. Sent as the `$contentType` cell. */\n contentType: MimeType | (string & {})\n /**\n * The entity's queryable attributes, keyed by name. Values are the tagged constructors from\n * `@arkiv-network/sdk/attr` — `i32`, `u64`, `u256`, `dec`, `str`, `addr`, `key`, `bytes32`,\n * `bool` — or a bare `boolean`, `number`, `bigint` or `string` where the type is unambiguous.\n *\n * @throws {InvalidAttributeNameError} If a name violates the attribute-name grammar.\n * @throws {InvalidValueError} If a value does not fit the type it names or defaults to.\n */\n attributes?: AttributeInputs | undefined\n /**\n * Properties fixed at creation: `readonly` and `permissionlessExtension`. No operation changes\n * them afterwards, so an entity is whatever it was created as for life. Both default to `false`.\n */\n flags?: CreationFlags | undefined\n /**\n * The salt mixed into the entity key. Defaults to 128 random bits, which makes the key\n * unpredictable to everyone but the creator.\n *\n * Pass {@link NO_SALT} for a key derived from the owner and nonce alone — predictable by anyone,\n * which is what you want only when a third party must be able to compute the key in advance.\n */\n salt?: SaltInput | undefined\n}\n\n/**\n * The result of creating an entity.\n */\nexport type CreateEntityReturnType = {\n /** The new entity's key. */\n entityKey: Hex\n txHash: Hash\n /**\n * The block the entity is expected to expire at, resolved against the block the transaction was\n * built on.\n *\n * The engine resolves a duration against the block the transaction actually lands in, so for\n * `ExpirationTime.fromDays(30)` and friends this is a lower bound: the real expiry is later by\n * however many blocks passed between building and inclusion. An `atBlock` deadline is exact.\n */\n expiresAt: bigint\n}\n\nexport async function createEntity(\n client: ArkivClient,\n data: CreateEntityParameters,\n txParams?: TxParams,\n): Promise<CreateEntityReturnType> {\n logger(\"createEntity %o\", data)\n const { receipt, createdEntityKeys, createdExpiries } = await sendArkivTransaction(\n client,\n { creates: [data] },\n txParams,\n )\n\n logger(\"Receipt from createEntity %o\", receipt)\n\n const [entityKey] = createdEntityKeys\n const [expiresAt] = createdExpiries\n if (entityKey === undefined || expiresAt === undefined) {\n throw new EntityMutationError(\n `Transaction ${receipt.transactionHash} succeeded, but the receipt did not carry the expected entity key or expiry.`,\n { txHash: receipt.transactionHash },\n )\n }\n\n return {\n txHash: receipt.transactionHash as Hash,\n entityKey,\n expiresAt,\n }\n}\n","import type { Hash, Hex } from \"viem\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { TxParams } from \"../../types\"\nimport { sendArkivTransaction } from \"../../utils/arkivTransactions\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:wallet:delete-entity\")\n\n/**\n * Parameters for the deleteEntity function.\n * - entityKey: The key of the entity to delete.\n */\nexport type DeleteEntityParameters = {\n entityKey: Hex\n}\n\n/**\n * Return type for the deleteEntity function.\n * - entityKey: The key of the entity.\n * - txHash: The transaction hash.\n */\nexport type DeleteEntityReturnType = {\n entityKey: Hex\n txHash: Hash\n}\n\nexport async function deleteEntity(\n client: ArkivClient,\n data: DeleteEntityParameters,\n txParams?: TxParams,\n): Promise<DeleteEntityReturnType> {\n logger(\"deleteEntity %o\", data)\n const { receipt } = await sendArkivTransaction(client, { deletes: [data] }, txParams)\n\n logger(\"Receipt from deleteEntity %o\", receipt)\n\n return {\n txHash: receipt.transactionHash as Hash,\n entityKey: data.entityKey,\n }\n}\n","import type { Hash, Hex } from \"viem\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { TxParams } from \"../../types\"\nimport { sendArkivTransaction } from \"../../utils/arkivTransactions\"\nimport { getLogger } from \"../../utils/logger\"\nimport type { ChangeOwnershipParameters } from \"./changeOwnership\"\nimport type { CreateEntityParameters } from \"./createEntity\"\nimport type { DeleteEntityParameters } from \"./deleteEntity\"\nimport type { ExtendEntityParameters } from \"./extendEntity\"\nimport type { PatchEntityParameters } from \"./patchEntity\"\n\nconst logger = getLogger(\"actions:wallet:execute-batch\")\n\n/**\n * Parameters for the executeBatch function.\n *\n * At least one operation is required; a batch with nothing in it throws rather than spending gas on\n * an empty transaction.\n */\nexport type ExecuteBatchParameters = {\n /** The entities to create. */\n creates?: CreateEntityParameters[]\n /** The patches to apply. */\n patches?: PatchEntityParameters[]\n /** The entities to delete. */\n deletes?: DeleteEntityParameters[]\n /** The expiries to set. */\n extensions?: ExtendEntityParameters[]\n /** The ownership transfers to perform. */\n ownershipChanges?: ChangeOwnershipParameters[]\n}\n\n/** Return type for the executeBatch function. */\nexport type ExecuteBatchReturnType = {\n /** The transaction hash. */\n txHash: Hash\n /** The keys of the created entities, in batch order. */\n createdEntities: Hex[]\n /** The keys of the patched entities. */\n patchedEntities: Hex[]\n /** The keys of the deleted entities. */\n deletedEntities: Hex[]\n /** The keys of the extended entities. */\n extendedEntities: Hex[]\n /** The keys of the entities handed to a new owner. */\n ownershipChanges: Hex[]\n}\n\nexport async function executeBatch(\n client: ArkivClient,\n data: ExecuteBatchParameters,\n txParams?: TxParams,\n): Promise<ExecuteBatchReturnType> {\n const { receipt, createdEntityKeys } = await sendArkivTransaction(client, data, txParams)\n\n logger(\"Receipt from executeBatch %o\", receipt)\n\n return {\n txHash: receipt.transactionHash as Hash,\n createdEntities: createdEntityKeys,\n patchedEntities: (data.patches ?? []).map((p) => p.entityKey),\n deletedEntities: (data.deletes ?? []).map((d) => d.entityKey),\n extendedEntities: (data.extensions ?? []).map((e) => e.entityKey),\n ownershipChanges: (data.ownershipChanges ?? []).map((o) => o.entityKey),\n }\n}\n","import type { Hash, Hex } from \"viem\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { Expiry } from \"../../entity\"\nimport { EntityMutationError } from \"../../errors\"\nimport type { TxParams } from \"../../types\"\nimport { sendArkivTransaction } from \"../../utils/arkivTransactions\"\nimport type { ExpirationTime } from \"../../utils/expirationTime\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:wallet:extend-entity\")\n\n/**\n * Parameters for extending an entity's life.\n *\n * An extension **sets a new expiry**; it does not add to the existing one. It is resolved exactly\n * as a create's is — a duration counts from now, not from the entity's current expiry — so\n * `ExpirationTime.fromDays(30)` means \"alive for thirty more days from now\" whatever the entity's\n * remaining life happened to be.\n *\n * The engine rejects an extension that would not move the expiry later, so extending an entity by\n * less than it already has left is an error rather than a silent shortening.\n *\n * @example\n * await client.extendEntity({ entityKey, expires: ExpirationTime.fromDays(30) })\n * await client.extendEntity({ entityKey, expires: ExpirationTime.atBlock(1_200_000n) })\n */\nexport type ExtendEntityParameters = {\n entityKey: Hex\n /** The entity's new lifetime, built with {@link ExpirationTime}. */\n expires: Expiry\n}\n\n/**\n * The result of extending an entity.\n */\nexport type ExtendEntityReturnType = {\n entityKey: Hex\n txHash: Hash\n /**\n * The block the entity is now expected to expire at, resolved against the block the transaction\n * was built on. Durations are approximate, so treat this as the estimate the operation was built\n * from rather than the block the engine settled on.\n */\n expiresAt: bigint\n}\n\nexport async function extendEntity(\n client: ArkivClient,\n data: ExtendEntityParameters,\n txParams?: TxParams,\n): Promise<ExtendEntityReturnType> {\n logger(\"extendEntity %o\", data)\n const { receipt, extendedExpiries } = await sendArkivTransaction(\n client,\n { extensions: [data] },\n txParams,\n )\n\n logger(\"Receipt from extendEntity %o\", receipt)\n\n const [expiresAt] = extendedExpiries\n if (expiresAt === undefined) {\n throw new EntityMutationError(\n `Transaction ${receipt.transactionHash} succeeded, but the receipt did not carry the expected entity expiry.`,\n { txHash: receipt.transactionHash },\n )\n }\n\n return {\n txHash: receipt.transactionHash as Hash,\n entityKey: data.entityKey,\n expiresAt,\n }\n}\n","import type { Hash, Hex } from \"viem\"\nimport type { AttributeInputs } from \"../../attr\"\nimport type { ArkivClient } from \"../../clients/baseClient\"\nimport type { MimeType, TxParams } from \"../../types\"\nimport { sendArkivTransaction } from \"../../utils/arkivTransactions\"\nimport { getLogger } from \"../../utils/logger\"\n\nconst logger = getLogger(\"actions:wallet:patch-entity\")\n\n/**\n * Parameters for patching an entity.\n *\n * A patch names only what changes. Attributes it does not mention keep whatever value they have, and\n * the payload and content type stay as they are unless given — so a caller can change one field\n * without first reading the entity to learn what the others are, and without racing anyone else who\n * is changing a different field.\n *\n * The entity's identity is fixed: a patch never moves the key, the owner, the creation flags or the\n * expiry. Use `extendEntity` for the expiry and `changeOwnership` for the owner.\n *\n * @example Change one attribute and remove another, leaving the payload alone:\n * await client.patchEntity({\n * entityKey,\n * set: { status: \"published\", level: i32(11) },\n * unset: [\"draft\"],\n * })\n *\n * @example Replace the contents without touching a single attribute:\n * await client.patchEntity({\n * entityKey,\n * payload: jsonToPayload({ hello: \"again\" }),\n * })\n */\nexport type PatchEntityParameters = {\n /** The entity to patch. */\n entityKey: Hex\n /**\n * Attributes to write, keyed by name. An existing attribute is overwritten — including with a\n * different type — and a name the entity does not carry yet is added.\n *\n * Values are the tagged constructors from `@arkiv-network/sdk/attr` — `i32`, `u64`, `u256`,\n * `dec`, `str`, `addr`, `key`, `bytes32`, `bool` — or a bare `boolean`, `number`, `bigint` or\n * `string` where the type is unambiguous.\n *\n * @throws {InvalidAttributeNameError} If a name violates the attribute-name grammar.\n * @throws {InvalidValueError} If a value does not fit the type it names or defaults to.\n */\n set?: AttributeInputs | undefined\n /**\n * Attribute names to remove. Naming one the entity does not carry is not an error — the outcome\n * is the same either way, and a caller clearing a field should not have to know whether it was\n * ever set.\n *\n * @throws {ConflictingMutationError} If a name also appears in `set`.\n */\n unset?: readonly string[] | undefined\n /**\n * The entity's new payload. Omit it to leave the current contents untouched; pass an empty\n * `Uint8Array` to replace them with nothing.\n */\n payload?: Uint8Array | undefined\n /**\n * The payload's new MIME type. Omit it to keep the current one — which is what you want when the\n * new payload is the same kind of thing as the old.\n */\n contentType?: MimeType | (string & {}) | undefined\n}\n\n/** The result of patching an entity. */\nexport type PatchEntityReturnType = {\n /** The patched entity's key — unchanged, since a patch never moves it. */\n entityKey: Hex\n txHash: Hash\n}\n\nexport async function patchEntity(\n client: ArkivClient,\n data: PatchEntityParameters,\n txParams?: TxParams,\n): Promise<PatchEntityReturnType> {\n logger(\"patchEntity %o\", data)\n const { receipt } = await sendArkivTransaction(client, { patches: [data] }, txParams)\n\n logger(\"Receipt from patchEntity %o\", receipt)\n\n return {\n txHash: receipt.transactionHash as Hash,\n entityKey: data.entityKey,\n }\n}\n","import type { Account, Chain, Client, PublicActions, Transport, WalletActions } from \"viem\"\nimport type {\n ChangeOwnershipParameters,\n ChangeOwnershipReturnType,\n} from \"../../actions/wallet/changeOwnership\"\nimport { changeOwnership } from \"../../actions/wallet/changeOwnership\"\nimport {\n type CreateEntityParameters,\n type CreateEntityReturnType,\n createEntity,\n} from \"../../actions/wallet/createEntity\"\nimport type {\n DeleteEntityParameters,\n DeleteEntityReturnType,\n} from \"../../actions/wallet/deleteEntity\"\nimport { deleteEntity } from \"../../actions/wallet/deleteEntity\"\nimport type {\n ExecuteBatchParameters,\n ExecuteBatchReturnType,\n} from \"../../actions/wallet/executeBatch\"\nimport { executeBatch } from \"../../actions/wallet/executeBatch\"\nimport type {\n ExtendEntityParameters,\n ExtendEntityReturnType,\n} from \"../../actions/wallet/extendEntity\"\nimport { extendEntity } from \"../../actions/wallet/extendEntity\"\nimport type { PatchEntityParameters, PatchEntityReturnType } from \"../../actions/wallet/patchEntity\"\nimport { patchEntity } from \"../../actions/wallet/patchEntity\"\nimport type { TxParams } from \"../../types\"\n\nexport type WalletArkivActions<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n account extends Account | undefined = Account | undefined,\n> = Pick<\n PublicActions<transport, chain, account>,\n \"waitForTransactionReceipt\" | \"call\" | \"simulateContract\" | \"readContract\" | \"getBlockNumber\"\n> &\n Pick<\n WalletActions<chain, account>,\n | \"addChain\"\n | \"sendCalls\"\n | \"waitForCallsStatus\"\n | \"sendTransaction\"\n | \"sendRawTransaction\"\n | \"signMessage\"\n | \"signTransaction\"\n | \"writeContract\"\n > & {\n /**\n * Creates a new entity.\n *\n * - JSON-RPC Methods: `eth_sendRawTransaction`\n *\n * @param data - The entity creation parameters\n * @param txParams - Optional transaction parameters\n * @returns The new entity's key, the transaction hash, and the block it is expected to\n * expire at. {@link CreateEntityReturnType}\n *\n * @throws {InvalidExpiryError} If the expiry exceeds a protocol bound or would leave the\n * entity dead on arrival.\n * @throws {InvalidValueError} If an attribute value does not fit the type it names.\n * @throws {InvalidAttributeNameError} If a name violates the attribute-name grammar.\n *\n * @example\n * import { createWalletClient, ExpirationTime, jsonToPayload } from \"@arkiv-network/sdk\"\n * import { i32 } from \"@arkiv-network/sdk/attr\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n * import { privateKeyToAccount } from \"viem/accounts\"\n *\n * const client = createWalletClient({\n * account: privateKeyToAccount(\"0x...\"),\n * chain: tiramisu,\n * transport: http(),\n * })\n * const { entityKey, txHash, expiresAt } = await client.createEntity({\n * payload: jsonToPayload({ entityType: \"testType\", entityId: \"testId\" }),\n * contentType: \"application/json\",\n * attributes: { testKey: \"testValue\", level: i32(3) },\n * expires: ExpirationTime.fromDays(30),\n * })\n */\n createEntity: (\n data: CreateEntityParameters,\n txParams?: TxParams,\n ) => Promise<CreateEntityReturnType>\n\n /**\n * Applies a patch to the entity with the given key: sets some fields, unsets others, and leaves\n * everything it does not name alone.\n *\n * - JSON-RPC Methods: `eth_sendRawTransaction`\n *\n * @param data - The entity key and the mutations to apply\n * @param txParams - Optional transaction parameters\n * @returns The patched entity's key and the transaction hash. {@link PatchEntityReturnType}\n *\n * @throws {EmptyPatchError} If the patch has nothing to apply.\n * @throws {ConflictingMutationError} If a name appears in both `set` and `unset`.\n * @throws {InvalidValueError} If an attribute value does not fit the type it names.\n * @throws {InvalidAttributeNameError} If a name violates the attribute-name grammar.\n *\n * @example\n * import { createWalletClient, jsonToPayload } from \"@arkiv-network/sdk\"\n * import { i32 } from \"@arkiv-network/sdk/attr\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n * import { privateKeyToAccount } from \"viem/accounts\"\n *\n * const client = createWalletClient({\n * account: privateKeyToAccount(\"0x...\"),\n * chain: tiramisu,\n * transport: http(),\n * })\n * // Publish the entity: one attribute changes, one goes away, the payload is replaced.\n * const { txHash } = await client.patchEntity({\n * entityKey,\n * set: { status: \"published\", revision: i32(2) },\n * unset: [\"draft\"],\n * payload: jsonToPayload({ title: \"Hello\" }),\n * })\n */\n patchEntity: (\n data: PatchEntityParameters,\n txParams?: TxParams,\n ) => Promise<PatchEntityReturnType>\n\n /**\n * Deletes the entity with the given key.\n *\n * - JSON-RPC Methods: `eth_sendRawTransaction`\n *\n * @param data - The entity deletion parameters\n * @param txParams - Optional transaction parameters\n * @returns The deleted entity's key and the transaction hash. {@link DeleteEntityReturnType}\n *\n * @example\n * import { createWalletClient } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n * import { privateKeyToAccount } from \"viem/accounts\"\n *\n * const client = createWalletClient({\n * account: privateKeyToAccount(\"0x...\"),\n * chain: tiramisu,\n * transport: http(),\n * })\n * // entityKey is the bytes32 key returned by createEntity.\n * const { txHash } = await client.deleteEntity({ entityKey })\n */\n deleteEntity: (\n data: DeleteEntityParameters,\n txParams?: TxParams,\n ) => Promise<DeleteEntityReturnType>\n\n /**\n * Sets a new expiry on the entity with the given key.\n *\n * The new lifetime is resolved the same way a create's is: a duration counts from now rather\n * than adding to what the entity has left, and `atBlock` / `atDate` pin an absolute deadline.\n * The engine rejects an extension that would not move the expiry later.\n *\n * - JSON-RPC Methods: `eth_sendRawTransaction`\n *\n * @param data - The entity key and its new lifetime\n * @param txParams - Optional transaction parameters\n * @returns The entity's key, the transaction hash, and the block it is now expected to expire\n * at. {@link ExtendEntityReturnType}\n *\n * @throws {InvalidExpiryError} If the expiry is malformed, exceeds a protocol bound, or would\n * leave the entity dead on arrival.\n *\n * @example\n * import { createWalletClient, ExpirationTime } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n * import { privateKeyToAccount } from \"viem/accounts\"\n *\n * const client = createWalletClient({\n * account: privateKeyToAccount(\"0x...\"),\n * chain: tiramisu,\n * transport: http(),\n * })\n * const { txHash, expiresAt } = await client.extendEntity({\n * entityKey,\n * expires: ExpirationTime.fromDays(30),\n * })\n */\n extendEntity: (\n data: ExtendEntityParameters,\n txParams?: TxParams,\n ) => Promise<ExtendEntityReturnType>\n\n /**\n * Hands the entity with the given key to a new owner.\n *\n * - JSON-RPC Methods: `eth_sendRawTransaction`\n *\n * @param data - The ownership change parameters\n * @param txParams - Optional transaction parameters\n * @returns The entity's key and the transaction hash. {@link ChangeOwnershipReturnType}\n */\n changeOwnership: (\n data: ChangeOwnershipParameters,\n txParams?: TxParams,\n ) => Promise<ChangeOwnershipReturnType>\n\n /**\n * Applies a batch of entity operations — creates, patches, deletes, extensions and ownership\n * transfers — in one transaction.\n *\n * - JSON-RPC Methods: `eth_sendRawTransaction`\n *\n * Every operation lands in one transaction, so the whole batch applies or none of it does.\n * At least one operation is required.\n *\n * @param data - The batch parameters (creates, patches, deletes, extensions, ownershipChanges)\n * @param txParams - Optional transaction parameters\n * @returns The transaction hash, plus the keys touched by each kind of operation.\n * {@link ExecuteBatchReturnType}\n *\n * @throws {InvalidExpiryError} If an expiry exceeds a protocol bound or would leave the entity\n * dead on arrival.\n * @throws {InvalidValueError} If an attribute value does not fit the type it names.\n *\n * @example\n * import { createWalletClient, ExpirationTime, jsonToPayload } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n * import { privateKeyToAccount } from \"viem/accounts\"\n *\n * const client = createWalletClient({\n * account: privateKeyToAccount(\"0x...\"),\n * chain: tiramisu,\n * transport: http(),\n * })\n * const { txHash, createdEntities } = await client.executeBatch({\n * creates: [{\n * payload: jsonToPayload({ entityType: \"testType\", entityId: \"testId\" }),\n * contentType: \"application/json\",\n * attributes: { testKey: \"testValue\" },\n * expires: ExpirationTime.fromDays(30),\n * }],\n * patches: [{ entityKey: keyToRevise, set: { status: \"archived\" }, unset: [\"draft\"] }],\n * deletes: [{ entityKey: staleKey }],\n * extensions: [{\n * entityKey: keyToKeepAlive,\n * expires: ExpirationTime.atBlock(1_200_000n),\n * }],\n * ownershipChanges: [{ entityKey: keyToHandOver, newOwner }],\n * })\n */\n executeBatch: (\n data: ExecuteBatchParameters,\n txParams?: TxParams,\n ) => Promise<ExecuteBatchReturnType>\n }\n\nexport function walletArkivActions<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n account extends Account | undefined = Account | undefined,\n>(client: Client<transport, chain, account>) {\n return {\n createEntity: (data: CreateEntityParameters, txParams?: TxParams) =>\n createEntity(client, data, txParams),\n patchEntity: (data: PatchEntityParameters, txParams?: TxParams) =>\n patchEntity(client, data, txParams),\n deleteEntity: (data: DeleteEntityParameters, txParams?: TxParams) =>\n deleteEntity(client, data, txParams),\n extendEntity: (data: ExtendEntityParameters, txParams?: TxParams) =>\n extendEntity(client, data, txParams),\n changeOwnership: (data: ChangeOwnershipParameters, txParams?: TxParams) =>\n changeOwnership(client, data, txParams),\n executeBatch: (data: ExecuteBatchParameters, txParams?: TxParams) =>\n executeBatch(client, data, txParams),\n }\n}\n","import type {\n Account,\n Address,\n Chain,\n Client,\n ParseAccount,\n Prettify,\n RpcSchema,\n Transport,\n WalletClientConfig,\n} from \"viem\"\nimport { createClient, publicActions, walletActions } from \"viem\"\nimport type { ArkivRpcSchema } from \"../types/rpcSchema\"\nimport { type WalletArkivActions, walletArkivActions } from \"./decorators/arkivWallet\"\n\nexport type WalletArkivClient<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n account extends Account | undefined = Account | undefined,\n rpcSchema extends RpcSchema | undefined = ArkivRpcSchema,\n> = Prettify<\n Client<transport, chain, account, rpcSchema, WalletArkivActions<transport, chain, account>>\n>\n\n/**\n * Creates a Wallet Client with a given [Transport](https://viem.sh/docs/clients/intro) configured\n * for a [Chain](https://viem.sh/docs/chains/introduction) and an account.\n *\n * A Wallet Client signs and sends transactions, so it carries an `account` and exposes everything\n * that mutates state — `createEntity`, `patchEntity`, `deleteEntity`, `extendEntity`,\n * `changeOwnership` and `executeBatch` — on top of the read actions a Public Client has.\n *\n * @param parameters - Configuration object for the wallet client (chain, transport, account, etc.)\n * @returns An Arkiv Wallet Client. {@link WalletArkivClient}\n *\n * @example\n * import { createWalletClient } from \"@arkiv-network/sdk\"\n * import { tiramisu } from \"@arkiv-network/sdk/chains\"\n * import { http } from \"viem\"\n * import { privateKeyToAccount } from \"viem/accounts\"\n *\n * const client = createWalletClient({\n * chain: tiramisu,\n * transport: http(),\n * account: privateKeyToAccount(\"0x...\"),\n * })\n */\nexport function createWalletClient<\n transport extends Transport,\n chain extends Chain | undefined = undefined,\n accountOrAddress extends Account | Address | undefined = undefined,\n rpcSchema extends RpcSchema | undefined = ArkivRpcSchema,\n>(\n parameters: WalletClientConfig<transport, chain, accountOrAddress, rpcSchema>,\n): WalletArkivClient<transport, chain, ParseAccount<accountOrAddress>, rpcSchema> {\n const { key = \"wallet\", name = \"Wallet Client\" } = parameters\n const client = createClient({\n ...parameters,\n key,\n name,\n })\n\n return client\n .extend(publicActions)\n .extend(walletActions)\n .extend(walletArkivActions) as unknown as WalletArkivClient<\n transport,\n chain,\n ParseAccount<accountOrAddress>,\n rpcSchema\n >\n}\n","import type { Chain } from \"viem\"\nimport * as chains from \"../chains\"\n\n// Create a lookup map from all exported chains\nconst chainMap = new Map(Object.entries(chains).map(([key, value]) => [key.toLowerCase(), value]))\n\n/**\n * Get a chain from its name\n * @param name - The name of the chain, case insensitive\n * @returns The chain\n * @throws An error if the chain is not found\n */\nexport function chainFromName(name: string): Chain {\n const chain = chainMap.get(name.toLowerCase())\n if (!chain) {\n throw new Error(`Unknown chain: ${name}`)\n }\n return chain as Chain\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  require('../attr-BXTkpnoc.cjs');
2
- const require_queryBuilder = require('../queryBuilder-DaLxNgeI.cjs');
2
+ const require_queryBuilder = require('../queryBuilder-BmRTaoJ8.cjs');
3
3
  require('../errors-DhV00966.cjs');
4
4
  require('../flags-DCD26uhe.cjs');
5
5
  require('../entity-B0t6sN7F.cjs');
@@ -1,5 +1,5 @@
1
1
  import "../index-CIcHPx2j.cjs";
2
2
  import "../flags-0Vl5rrHq.cjs";
3
3
  import { C as lte, D as render, E as or, O as startsWith, S as lt, T as not, _ as eq, a as SelectionFields, b as gte, c as ComparisonNode, d as Expression, f as NotNode, g as and, h as TypeOfNode, i as SelectArg, l as ComparisonOperator, m as StartsWithNode, n as FullEntity, o as toRpcSelect, p as OrNode, r as ProjectedEntity, s as AndNode, t as EntitySelection, u as ExistsNode, v as exists, w as ne, x as hasType, y as gt } from "../selection-Bv8_o-7i.cjs";
4
- import { a as QueryErrorKind, c as QueryRequest, i as QueryError, l as QueryResponse, n as QueryResult, o as UnsupportedOperatorError, r as InvalidPredicateError, s as MAX_LIMIT, t as SelectQueryBuilder, u as runQuery } from "../index-rINthNuU.cjs";
4
+ import { a as QueryErrorKind, c as QueryRequest, i as QueryError, l as QueryResponse, n as QueryResult, o as UnsupportedOperatorError, r as InvalidPredicateError, s as MAX_LIMIT, t as SelectQueryBuilder, u as runQuery } from "../index-DsM7EXu6.cjs";
5
5
  export { AndNode, ComparisonNode, ComparisonOperator, EntitySelection, ExistsNode, Expression, FullEntity, InvalidPredicateError, MAX_LIMIT, NotNode, OrNode, ProjectedEntity, QueryError, QueryErrorKind, QueryRequest, QueryResponse, QueryResult, SelectArg, SelectQueryBuilder, SelectionFields, StartsWithNode, TypeOfNode, UnsupportedOperatorError, and, eq, exists, gt, gte, hasType, lt, lte, ne, not, or, render, runQuery, startsWith, toRpcSelect };
@@ -1,5 +1,5 @@
1
1
  import "../index-Cd2aaWme.js";
2
2
  import "../flags-wmcMoAnN.js";
3
3
  import { C as lte, D as render, E as or, O as startsWith, S as lt, T as not, _ as eq, a as SelectionFields, b as gte, c as ComparisonNode, d as Expression, f as NotNode, g as and, h as TypeOfNode, i as SelectArg, l as ComparisonOperator, m as StartsWithNode, n as FullEntity, o as toRpcSelect, p as OrNode, r as ProjectedEntity, s as AndNode, t as EntitySelection, u as ExistsNode, v as exists, w as ne, x as hasType, y as gt } from "../selection-ox7zdtVm.js";
4
- import { a as QueryErrorKind, c as QueryRequest, i as QueryError, l as QueryResponse, n as QueryResult, o as UnsupportedOperatorError, r as InvalidPredicateError, s as MAX_LIMIT, t as SelectQueryBuilder, u as runQuery } from "../index-BKB875Um.js";
4
+ import { a as QueryErrorKind, c as QueryRequest, i as QueryError, l as QueryResponse, n as QueryResult, o as UnsupportedOperatorError, r as InvalidPredicateError, s as MAX_LIMIT, t as SelectQueryBuilder, u as runQuery } from "../index-CmEefH8_.js";
5
5
  export { AndNode, ComparisonNode, ComparisonOperator, EntitySelection, ExistsNode, Expression, FullEntity, InvalidPredicateError, MAX_LIMIT, NotNode, OrNode, ProjectedEntity, QueryError, QueryErrorKind, QueryRequest, QueryResponse, QueryResult, SelectArg, SelectQueryBuilder, SelectionFields, StartsWithNode, TypeOfNode, UnsupportedOperatorError, and, eq, exists, gt, gte, hasType, lt, lte, ne, not, or, render, runQuery, startsWith, toRpcSelect };
@@ -1,5 +1,5 @@
1
1
  import "../attr-tmyREHtw.js";
2
- import { _ as MAX_LIMIT, a as eq, b as QueryError, c as gte, d as lte, f as ne, g as startsWith, h as render, i as and, l as hasType, m as or, n as QueryResult, o as exists, p as not, r as toRpcSelect, s as gt, t as SelectQueryBuilder, u as lt, v as runQuery, x as UnsupportedOperatorError, y as InvalidPredicateError } from "../queryBuilder-COWt6aIF.js";
2
+ import { _ as MAX_LIMIT, a as eq, b as QueryError, c as gte, d as lte, f as ne, g as startsWith, h as render, i as and, l as hasType, m as or, n as QueryResult, o as exists, p as not, r as toRpcSelect, s as gt, t as SelectQueryBuilder, u as lt, v as runQuery, x as UnsupportedOperatorError, y as InvalidPredicateError } from "../queryBuilder-MubNEvA4.js";
3
3
  import "../errors-D2E1GRjw.js";
4
4
  import "../flags-DUT2gHEU.js";
5
5
  import "../entity-BIp_df9u.js";
@@ -816,11 +816,11 @@ var QueryResult = class {
816
816
  * @example
817
817
  * import { createPublicClient } from "@arkiv-network/sdk"
818
818
  * import { i32 } from "@arkiv-network/sdk/attr"
819
- * import { cheesecake } from "@arkiv-network/sdk/chains"
819
+ * import { tiramisu } from "@arkiv-network/sdk/chains"
820
820
  * import { eq, gte, or } from "@arkiv-network/sdk/query"
821
821
  * import { http } from "viem"
822
822
  *
823
- * const client = createPublicClient({ chain: cheesecake, transport: http() })
823
+ * const client = createPublicClient({ chain: tiramisu, transport: http() })
824
824
  *
825
825
  * const page = await client
826
826
  * .select({ key: true, attributes: true })