/** * Data point deletion (tombstone) helpers for DataRegistryV2. * * A deletion is an owner-signed `AddData` for version `current + 1` whose * `dataHash` / `metadataHash` are the protocol-wide tombstone constants below. * The gateway records the tombstone version and marks the row `deletedAt`; * the encrypted blobs in vana-storage are removed afterwards as a best-effort * follow-up. The tombstone is the durable fact; blob removal is cleanup. * * The typed-data definition is exactly {@link ADD_DATA_TYPES} against * {@link dataRegistryDomain} -- the same signature the registration path uses, * so a verifier cannot tell a deletion apart from a registration except by * the hashes. * * @category Protocol */ import { type Account, type Address, type Hex, type TypedDataDefinition } from "viem"; import { ADD_DATA_TYPES, type AddDataMessage, type DataPortabilityGatewayConfig } from "./eip712.js"; import type { DeleteDataPointResult as GatewayDeleteDataPointResult, GatewayClient } from "./gateway.js"; /** UTF-8 preimage of {@link TOMBSTONE_DATA_HASH}. */ export declare const TOMBSTONE_DATA_HASH_PREIMAGE = "vana.data-point.tombstone.v1"; /** UTF-8 preimage of {@link TOMBSTONE_METADATA_HASH}. */ export declare const TOMBSTONE_METADATA_HASH_PREIMAGE = "vana.data-point.tombstone.metadata.v1"; /** * `keccak256(utf8("vana.data-point.tombstone.v1"))` -- the `dataHash` a * deletion AddData carries. Single source of truth shared with the gateway * and Personal Server; never change without a new `.vN` preimage. */ export declare const TOMBSTONE_DATA_HASH: "0x30c45ee72fe56d1927701316925ab7ceacd3b6f9267061735d59396f075c6222"; /** * `keccak256(utf8("vana.data-point.tombstone.metadata.v1"))` -- the * `metadataHash` a deletion AddData carries. */ export declare const TOMBSTONE_METADATA_HASH: "0xc5255a141acd6a2ae55971b62c0a85977c2511989dc114ad2abc2b7644f57d90"; /** * Recompute a tombstone hash from its preimage. Exposed so tests and * downstream services can prove the pinned constants match the contract. */ export declare function computeTombstoneHash(preimage: string): Hex; /** True when the pair of hashes is exactly the tombstone pair. */ export declare function isTombstoneHashes(dataHash: string | undefined, metadataHash: string | undefined): boolean; /** * Detect a deleted data point from any record-shaped value: a non-null * `deletedAt`, or the tombstone hash pair. Accepts `unknown` so read * helpers can run it on a raw JSON body before trusting the payload. */ export declare function isDataPointTombstone(value: unknown): boolean; /** * Read `deletedAt` off any value a gateway or Personal Server might hand * back (a record, an error body, `null`, an array, ...). Returns `null` * unless it is a string, so every `DataPointDeletedError` carries the same * `deletedAt` semantics regardless of which read path raised it. */ export declare function tombstoneDeletedAt(value: unknown): string | null; export type DataPointDeletionTypedData = TypedDataDefinition & { message: AddDataMessage; }; export interface DataPointDeletionSigner { /** The data point owner. Must match `AddData.ownerAddress`. */ address: Address; signTypedData(typedData: DataPointDeletionTypedData): Promise | Hex; } export interface ViemDataPointDeletionWalletClient { account?: Account | Address | null; signTypedData(typedData: DataPointDeletionTypedData & { account?: Account | Address; }): Promise; } export type ViemDataPointDeletionSignerSource = DataPointDeletionSigner | ViemDataPointDeletionWalletClient; export interface BuildDataPointDeletionTypedDataInput { ownerAddress: Address; scope: string; /** * The version the tombstone is written at -- `current + 1`. This is the * `AddData.expectedVersion` field; the gateway rejects with 409 unless it * is strictly greater than the stored version. */ expectedVersion: bigint; config: DataPortabilityGatewayConfig; } export interface BuildDataPointDeletionSignatureInput { signer: DataPointDeletionSigner; scope: string; /** See {@link BuildDataPointDeletionTypedDataInput.expectedVersion}. */ expectedVersion: bigint; config: DataPortabilityGatewayConfig; } export interface DataPointDeletionSignature { signature: Hex; signerAddress: Address; typedData: DataPointDeletionTypedData; } /** * Adapt a viem local account or wallet client to * {@link DataPointDeletionSigner}. Mirrors * `createViemPersonalServerRegistrationSigner`. */ export declare function createViemDataPointDeletionSigner(source: ViemDataPointDeletionSignerSource, options?: { account?: Account | Address; }): DataPointDeletionSigner; /** * Build the exact `AddData` typed data a deletion signs: the tombstone hash * pair at `expectedVersion`, against the DataRegistryV2 domain. */ export declare function buildDataPointDeletionTypedData(input: BuildDataPointDeletionTypedDataInput): DataPointDeletionTypedData; /** Sign a deletion `AddData` with the owner's signer. */ export declare function buildDataPointDeletionSignature(input: BuildDataPointDeletionSignatureInput): Promise; /** * Outcome of a scope-wide blob delete. `VanaStorage.deleteScope` returns a * superset of this shape. */ export interface DataPointBlobDeleteResult { count: number; totalBytes: number; } /** * The storage half of a deletion -- structurally satisfied by `VanaStorage`. * Removes every version's blob under `(owner, scope)`. */ export interface DataPointBlobStore { deleteScope(ownerAddress: Address, scope: string): Promise; } export interface DeleteDataPointInput { /** Gateway client -- only `getDataPoint` and `deleteDataPoint` are used. */ gateway: Pick; /** Blob store for the best-effort cleanup after the tombstone lands. */ storage: DataPointBlobStore; /** Owner signer. `signer.address` is the data point owner. */ signer: DataPointDeletionSigner; scope: string; config: DataPortabilityGatewayConfig; /** * Skip the gateway lookup and treat this as the current version. Use when * the caller already holds a fresh `DataPointRecord.expectedVersion`; * omit to let the SDK fetch it. */ currentVersion?: bigint; } interface DataPointDeletionBase { dataPointId: Hex; ownerAddress: Address; scope: string; /** Decimal-string uint256 of the tombstone version (`current + 1`). */ version: string; signature: Hex; /** The gateway's 200 body for the tombstone. */ tombstone: GatewayDeleteDataPointResult; } /** Both the gateway tombstone and the blob cleanup succeeded. */ export interface DataPointDeletedResult extends DataPointDeletionBase { status: "deleted"; storage: DataPointBlobDeleteResult; } /** * The gateway recorded the tombstone (durable, the data point is deleted) * but the blob cleanup failed. Retry `storage.deleteScope(owner, scope)` * later; the tombstone does not need to be re-signed. */ export interface DataPointDeletionPartialResult extends DataPointDeletionBase { status: "partial"; storageError: Error; } export type DataPointDeletionResult = DataPointDeletedResult | DataPointDeletionPartialResult; /** * Delete a data point end to end. Symmetric with `registerDataPoint`. * * Order, deliberately: * 1. fetch the current version from the gateway (unless supplied), * 2. sign the tombstone `AddData` for `current + 1`, * 3. `DELETE /v1/data/:dataPointId` on the gateway, * 4. delete every blob under `(owner, scope)` in vana-storage. * * Steps 1-3 throw on failure ({@link DataPointNotFoundError}, * {@link DataPointDeletedError}, `DataPointVersionConflictError`, or a * generic gateway error). A step-4 failure does NOT throw: the tombstone is * already the durable fact, so the result comes back with * `status: "partial"` and the storage error attached. */ export declare function deleteDataPoint(input: DeleteDataPointInput): Promise; export {};