UNPKG

@arkiv-network/sdk

Version:

TypeScript client library for Arkiv's blockchains interactions

136 lines (125 loc) • 4.34 kB
import { type Address, encodeAbiParameters, type Hex, parseAbi, parseAbiParameters } from "viem" import type { AbiAttribute } from "../schema/codec" import type { EncodedExpiry } from "./expiry" import type { predictEntityKey } from "./key" import { OperationType } from "./params" /** * The one external entry point. A transaction is an ordered, **atomic** batch of entity operations: * all of them apply or none do, operation *n+1* observes operation *n*'s effects, and each applied * operation emits one event. */ export const EXECUTE_ABI = parseAbi([ "function execute((uint8 operation, bytes operationData)[] ops) external returns (bytes32[] keys)", ]) /** * The engine's one read-only view: an owner's entity-minting nonce, which is the input * {@link predictEntityKey} needs and the only part of the derivation the caller cannot know. * * It is a `view` on the same address `execute` is called on, so it answers over `eth_call` without * a transaction. */ export const ENTITY_NONCE_ABI = parseAbi([ "function entityNonce(address owner) external view returns (uint64)", ]) /** * The shared attribute shape, used by `create` (attributes) and `patch` (mutations). Written out * once and reused by every payload that carries attributes. */ const ATTRIBUTE_TUPLE = "(bytes32 name, uint8 typeId, bytes value)[]" /** * The payload struct for each operation tag. `operationData` is `abi.encode` of the struct the tag * selects — a tagged union, so a new operation is additive rather than a change to `execute`. */ const PAYLOAD_PARAMS = { [OperationType.Create]: parseAbiParameters( `(uint128 salt, uint64 expiresAt, uint64 minLifetime, uint8 creationFlags, ${ATTRIBUTE_TUPLE} attributes)`, ), [OperationType.Patch]: parseAbiParameters(`(bytes32 entityKey, ${ATTRIBUTE_TUPLE} mutations)`), [OperationType.ExtendExpiry]: parseAbiParameters( "(bytes32 entityKey, uint64 expiresAt, uint64 minLifetime)", ), [OperationType.TransferOwnership]: parseAbiParameters("(bytes32 entityKey, address newOwner)"), [OperationType.Delete]: parseAbiParameters("(bytes32 entityKey)"), } as const /** One entry of the `execute` batch: the operation tag and its ABI-encoded payload. */ export type Operation = { operation: number operationData: Hex } /** Creates an entity. The key is derived by the engine; predict it with `predictEntityKey`. */ export function createOperation({ salt, expiry, creationFlags, attributes, }: { salt: bigint expiry: EncodedExpiry creationFlags: number attributes: AbiAttribute[] }): Operation { return { operation: OperationType.Create, operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.Create], [ { salt, expiresAt: expiry.expiresAt, minLifetime: expiry.minLifetime, creationFlags, attributes, }, ]), } } /** Applies a set of mutations to an existing entity. Tombstones unset attributes. */ export function patchOperation({ entityKey, mutations, }: { entityKey: Hex mutations: AbiAttribute[] }): Operation { return { operation: OperationType.Patch, operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.Patch], [ { entityKey, mutations }, ]), } } /** Pushes an entity's expiry further out. Extending is allowed; shortening reverts. */ export function extendExpiryOperation({ entityKey, expiry, }: { entityKey: Hex expiry: EncodedExpiry }): Operation { return { operation: OperationType.ExtendExpiry, operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.ExtendExpiry], [ { entityKey, expiresAt: expiry.expiresAt, minLifetime: expiry.minLifetime }, ]), } } /** Hands an entity to a new owner. */ export function transferOwnershipOperation({ entityKey, newOwner, }: { entityKey: Hex newOwner: Address }): Operation { return { operation: OperationType.TransferOwnership, operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.TransferOwnership], [ { entityKey, newOwner }, ]), } } /** Deletes an entity before its expiry. */ export function deleteOperation({ entityKey }: { entityKey: Hex }): Operation { return { operation: OperationType.Delete, operationData: encodeAbiParameters(PAYLOAD_PARAMS[OperationType.Delete], [{ entityKey }]), } }