import { InputGenerateTransactionOptions, Aptos, AccountAddress, InputTransactionPluginData, AccountAddressInput, Account, PendingTransactionResponse, InputGenerateTransactionPayloadData } from '@aptos-labs/ts-sdk'; import { BlobName } from '../layout.js'; import { FullObjectMetadata, BlobActivity, BlobEncryption, StorageProviderAck } from '../types/blobs.js'; import { E as ErasureCodingConfig } from '../../clay-codes-DdXABBDx.js'; import { ShelbyIndexerClient } from '../operations/index.js'; import { Blobs_Order_By, Blobs_Bool_Exp, Blob_Activities_Bool_Exp, Blob_Activities_Order_By } from '../operations/generated/sdk.js'; import { ShelbyClientConfig } from './ShelbyClientConfig.js'; import 'zod'; import '@shelby-protocol/clay-codes'; import 'graphql-request'; import 'graphql'; import '../networks.js'; /** * Error thrown when USD sponsorship is configured without a transaction submitter. * USD sponsorship requires a transaction submitter because the sponsored transaction * is a multi-agent transaction that must be co-signed by the sponsor. */ declare class MissingTransactionSubmitterError extends Error { constructor(); } /** * Why `commit_object` rejected a write, mirroring the contract's * `CommitRejectionReason` variants (blob_metadata.move). */ type CommitRejectionReason = "AlreadyExists" | "NoPriorVersion" | "EtagMismatch"; /** * Thrown when `commit_object` rejected a write instead of applying it. The * transaction itself succeeded; the contract tore down the pending blob and * emitted `ObjectCommitRejectedEvent` rather than aborting. */ declare class ObjectCommitRejectedError extends Error { readonly blobName: BlobName; readonly uid: bigint; readonly reason: CommitRejectionReason; constructor(blobName: BlobName, uid: bigint, reason: CommitRejectionReason); } interface BuildOptions { options?: InputGenerateTransactionOptions; withFeePayer?: boolean; } interface UsdSponsorOptions { /** * This should be provided by your gas station provider (e.g. Geomi) after you create * a gas station. */ feePayerAddress: AccountAddress; } interface WriteBlobCommitmentsOptions { build?: BuildOptions; submit?: InputTransactionPluginData; /** * Whereas build.withFeePayer corresponds to regular APT fee sponsorship, this refers * to the Shelby-specific fees in stables. If set, we will use the sponsored variants * of the various entry functions, e.g. register_blob_with_sponsor rather than * register_blob. Aptos right now requires that the payload includes the address of * the second signer when it is initially built, so you must provide the fee payer * address of your gas station. * * These payloads by definition must be signed by the sponsor as well, so you must * also configure a `transactionSubmitter` in your Aptos client's pluginSettings * (via `aptos.pluginSettings.TRANSACTION_SUBMITTER`) that sends the transaction to * an intermediate service (like a gas station) that co-signs the transaction. * * If `usdSponsor` is provided without a transaction submitter configured, an error * will be thrown. */ usdSponsor?: UsdSponsorOptions; chunksetSizeBytes?: number; /** * The location (region) to write the blob to. Authoritative: the write lands there * or aborts on chain (e.g. if the account's location preference is locked to a * different location). */ selectedLocation?: string; /** * Best-effort location hint, typically derived from where the client runs. Honored * only for accounts in the default `FollowHint` preference mode, and overridden by * `selectedLocation`. Defaults to `ShelbyClientConfig.locationHint`. */ locationHint?: string; } interface AckTransactionOptions { build?: BuildOptions; } declare class ShelbyBlobClient { readonly aptos: Aptos; readonly deployer: AccountAddress; readonly indexer: ShelbyIndexerClient; readonly defaultOptions: WriteBlobCommitmentsOptions; private readonly orderless; /** * The ShelbyBlobClient is used to interact with the Shelby contract on the Aptos blockchain. This * includes functions for registering blob commitments and retrieving blob metadata. * * @param config - The client configuration object. * @param config.network - The Shelby network to use. * @param defaultOptions - Optional default options for blob operations. * * @example * ```typescript * const blobClient = new ShelbyBlobClient({ * aptos: { * network: Network.SHELBYNET, * clientConfig: { * API_KEY: "AG-***", * }, * }, * }); * ``` * * @example * ```typescript * // With default options for USD sponsorship * const blobClient = new ShelbyBlobClient( * { * network: Network.SHELBYNET, * aptos: { * pluginSettings: { * TRANSACTION_SUBMITTER: myGasStationSubmitter, * }, * }, * }, * { * usdSponsor: { feePayerAddress: sponsorAddress }, * } * ); * ``` */ constructor(config: ShelbyClientConfig, defaultOptions?: WriteBlobCommitmentsOptions); /** * Merges method-level options with default options, giving precedence to method-level values. */ private mergeOptions; /** * Validates that if USD sponsorship is requested, a transaction submitter is * configured as well. Checks both the client-level and method-level transaction * submitter configurations. Throws MissingTransactionSubmitterError if usdSponsor is * provided without a transaction submitter. */ private validateUsdSponsorConfig; /** * Merges orderless replay protection into transaction options when * `config.orderless` is enabled. If the caller already supplies options * (e.g. custom gas limits), those are preserved and the nonce is injected * alongside them. When orderless mode is off, user options are returned as-is. */ private orderlessTxOptions; /** * Retrieves the blob metadata from the blockchain. If it does not exist, * returns `undefined`. * * @param params.account - The account namespace the blob is stored in (e.g. "0x1") * @param params.name - The name of the blob (e.g. "foo/bar") * @returns The blob metadata. * * @example * ```typescript * const metadata = await client.getFullObjectMetadata({ * account: AccountAddress.fromString("0x1"), * name: "foo/bar.txt", * }); * ``` */ getFullObjectMetadata(params: { account: AccountAddressInput; name: BlobName; }): Promise; /** * Retrieves blob metadata directly by its on-chain UID, including blobs in * the pending (registered-but-not-yet-committed) state that * {@link getFullObjectMetadata} cannot resolve by object name. Returns `undefined` * if no blob has that UID. * * The returned `name`/`blobNameSuffix` are empty: the blob layer is keyed by * UID and carries no object name (a name binding is established only at * commit). `isWritten` reflects whether the blob has been committed. */ getFullObjectMetadataByUid(uid: bigint): Promise; /** * Parse the on-chain `BlobMetadata::V1` view shape into the SDK * {@link FullObjectMetadata}. `uid` / `name` / `isWritten` are supplied by the * caller since they depend on the lookup path (by object name vs by UID). */ private parseBlobMetadata; /** * Retrieves all the blobs and their metadata for an account from the * blockchain. * * @param params.account - The account namespace the blobs are stored in (e.g. "0x1") * @param params.pagination (optional) - The pagination options. * @param params.orderBy (optional) - The order by clause to sort the blobs by. * @returns The blob metadata for all the blobs for the account. * * @example * ```typescript * // FullObjectMetadata[] * const blobs = await client.getAccountBlobs({ * account: AccountAddress.fromString("0x1"), * }); * ``` */ getAccountBlobs(params: { account: AccountAddressInput; pagination?: { limit?: number; offset?: number; }; orderBy?: Blobs_Order_By; where?: Omit; }): Promise; /** * Object-facing default filter: only committed, non-deleted rows. * The blobs table is UID-keyed, so during an atomic overwrite a single * object_name transiently has two non-deleted rows — the currently committed * blob and the new pending (is_committed = "0") blob. Filtering on * is_committed keeps name lookups/listings pinned to the committed object and * avoids returning or duplicating the in-flight pending row. Applied to * getBlobs *and* the getBlobsCount / getTotalBlobsSize aggregates so counts * and sizes agree with the listing mid-overwrite. Callers can override any * key (e.g. is_committed) via their own `where`. */ private activeBlobsWhere; /** * Retrieves blobs and their metadata from the blockchain. * * @param params.where (optional) - The where clause to filter the blobs by. * @param params.pagination (optional) - The pagination options. * @param params.orderBy (optional) - The order by clause to sort the blobs by. * @returns The blob metadata for all the blobs that match the where clause. * * @example * ```typescript * // FullObjectMetadata[] * const blobs = await client.getBlobs({ * where: { owner: { _eq: AccountAddress.fromString("0x1").toString() } }, * }); * ``` */ getBlobs(params?: { where?: Blobs_Bool_Exp; pagination?: { limit?: number; offset?: number; }; orderBy?: Blobs_Order_By; }): Promise; getBlobActivities(params: { where?: Blob_Activities_Bool_Exp; pagination?: { limit?: number; offset?: number; }; orderBy?: Blob_Activities_Order_By; }): Promise; /** * Retrieves the total number of blobs from the blockchain. * * @param params.where (optional) - The where clause to filter the blobs by. * @returns The total number of blobs. * * @example * ```typescript * const count = await client.getBlobsCount(); * ``` */ getBlobsCount(params?: { where?: Blobs_Bool_Exp; }): Promise; /** * Retrieves the total size of blobs from the blockchain. * * @param params.where (optional) - The where clause to filter the blobs by. * @returns The total size of blobs in bytes. * * @example * ```typescript * const size = await client.getTotalBlobsSize(); * ``` */ getTotalBlobsSize(params?: { where?: Blobs_Bool_Exp; }): Promise; /** * Retrieves the total number of blob activities from the blockchain. * * @param params.where (optional) - The where clause to filter the blob activities by. * @returns The total number of blob activities. * * @example * ```typescript * const count = await client.getBlobActivitiesCount(); * ``` */ getBlobActivitiesCount(params: { where?: Blob_Activities_Bool_Exp; }): Promise; /** * Registers a blob on the blockchain by writing its merkle root and metadata. * * @param params.account - The account that is signing and paying for the transaction. * @param params.blobName - The name/path of the blob (e.g. "foo/bar.txt"). * @param params.blobMerkleRoot - The merkle root of the blob commitments. * @param params.size - The size of the blob in bytes. * @param params.options - Optional transaction building options. * @param params.options.chunksetSizeBytes - Custom chunkset size (defaults to DEFAULT_CHUNKSET_SIZE_BYTES). * @param params.options.build - Additional Aptos transaction building options. * * @returns An object containing the pending transaction. * * @example * ```typescript * const provider = await ClayErasureCodingProvider.create(); * const blobCommitments = await generateCommitments(provider, data); * * const { transaction } = await client.registerBlob({ * account: signer, * blobName: "foo/bar.txt", * blobMerkleRoot: blobCommitments.blob_merkle_root, * size: data.length, * }); * ``` */ registerBlob(params: { account: Account; blobName: BlobName; blobMerkleRoot: string; size: number; encryption?: BlobEncryption; config?: ErasureCodingConfig; options?: WriteBlobCommitmentsOptions; }): Promise<{ transaction: PendingTransactionResponse; }>; /** * Deletes a blob on the blockchain. * * @param params.account - The account that is signing and paying for the transaction. * @param params.blobName - The name/path of the blob (e.g. "foo/bar.txt"). * @param params.options - Optional transaction building options. * * @returns An object containing the pending transaction. * * @example * ```typescript * * const { transaction } = await client.deleteObject({ * account: signer, * blobName: "foo/bar.txt", * }); * ``` */ deleteObject(params: { account: Account; blobName: BlobName; options?: InputGenerateTransactionOptions; }): Promise<{ transaction: PendingTransactionResponse; }>; /** * Deletes multiple blobs on the blockchain in a single atomic transaction. * * This operation is atomic: if any blob deletion fails (e.g., blob not found), * the entire transaction fails and no blobs are deleted. * * @param params.account - The account that is signing and paying for the transaction. * @param params.blobNames - Array of blob name suffixes without the account address prefix * (e.g. ["foo/bar.txt", "baz.txt"], NOT ["0x1/foo/bar.txt"]). The account address * prefix is automatically derived from the signer. * @param params.options - Optional transaction building options. * * @returns An object containing the pending transaction. * * @example * ```typescript * * const { transaction } = await client.deleteMultipleObjects({ * account: signer, * blobNames: ["foo/bar.txt", "baz.txt"], * }); * ``` */ deleteMultipleObjects(params: { account: Account; blobNames: BlobName[]; options?: InputGenerateTransactionOptions; }): Promise<{ transaction: PendingTransactionResponse; }>; /** * Registers multiple blobs on the blockchain by writing their merkle roots and metadata. * * @param params.account - The account that is signing and paying for the transaction. * @param params.blobs - The blobs to register. * @param params.blobs.blobName - The name/path of the blob (e.g. "foo/bar.txt"). * @param params.blobs.blobSize - The size of the blob in bytes. * @param params.blobs.blobMerkleRoot - The merkle root of the blob commitments as a hex string. * @param params.options - Optional transaction building options. * @param params.options.chunksetSizeBytes - Custom chunkset size (defaults to DEFAULT_CHUNKSET_SIZE_BYTES). * @param params.options.build - Additional Aptos transaction building options. * * @returns An object containing the pending transaction. * * @example * ```typescript * const provider = await ClayErasureCodingProvider.create(); * const blobCommitments = await generateCommitments(provider, data); * * const { transaction } = await client.batchRegisterBlobs({ * account: signer, * blobs: [ * { * blobName: "foo/bar.txt", * blobSize: data.length, * blobMerkleRoot: blobCommitments.blob_merkle_root, * }, * ], * }); * ``` */ batchRegisterBlobs(params: { account: Account; blobs: { blobName: BlobName; blobSize: number; blobMerkleRoot: string; }[]; encryption?: BlobEncryption; config?: ErasureCodingConfig; options?: WriteBlobCommitmentsOptions; }): Promise<{ transaction: PendingTransactionResponse; }>; /** * Extracts the on-chain UIDs assigned at registration from a committed * register transaction's events. * * `register_blob` / `register_multiple_blobs` create *pending* blobs and emit * one `BlobRegisteredEvent` per blob. The UID is published only on this event * (the blob is not yet in the `objects` map, so it cannot be read back by * name), so callers must parse it here before uploading bytes or committing. * * @param events - The committed transaction's events (from `waitForTransaction`). * @param deployer - The contract deployer address. * @returns One entry per registered blob, keyed by its full object name * (`@/`, matching {@link createBlobKey}). */ static registeredBlobUids(events: ReadonlyArray<{ type: string; data: unknown; }>, deployer: AccountAddress): { objectName: string; uid: bigint; }[]; /** * Detects whether `commit_object` rejected the write for `uid` rather than * applying it. A rejected commit is still a *successful* transaction — the * contract tears down the pending blob and emits `ObjectCommitRejectedEvent` * instead of aborting — so callers must inspect the finalized transaction's * events to tell a durable write apart from a silent no-op. * * @param events - The committed transaction's events (from `waitForTransaction`). * @param deployer - The contract deployer address. * @param uid - The UID passed to `commit_object`. * @returns The rejection reason, or `undefined` if the commit was applied. */ static findObjectCommitRejection(events: ReadonlyArray<{ type: string; data: unknown; }>, deployer: AccountAddress, uid: bigint): CommitRejectionReason | undefined; /** * Creates a transaction payload to register a blob on the blockchain. * This is a static helper method for constructing the Move function call payload. * * @param params.deployer - Optional deployer account address. Defaults to SHELBY_DEPLOYER. * @param params.account - The account that will own the blob. * @param params.blobName - The name/path of the blob (e.g. "foo/bar.txt"). * @param params.blobSize - The size of the blob in bytes. * @param params.blobMerkleRoot - The merkle root of the blob commitments as a hex string. * @param params.numChunksets - The total number of chunksets in the blob. * * @returns An Aptos transaction payload data object for the register_blob Move function. */ static createRegisterBlobPayload(params: { deployer?: AccountAddress; account: AccountAddress; blobName: BlobName; selectedLocation?: string; locationHint?: string; blobSize: number; blobMerkleRoot: string; numChunksets: number; useSponsoredUsdVariant?: boolean; encoding: number; encryption?: BlobEncryption; }): InputGenerateTransactionPayloadData; /** * Creates a transaction payload to register multiple blobs on the blockchain. * This is a static helper method for constructing the Move function call payload. * * @param params.deployer - Optional deployer account address. Defaults to SHELBY_DEPLOYER. * @param params.account - The account that will own the blobs. * @param params.blobs - The blobs to register. * @param params.blobs.blobName - The name/path of the blob (e.g. "foo/bar.txt"). * @param params.blobs.blobSize - The size of the blob in bytes. * @param params.blobs.blobMerkleRoot - The merkle root of the blob commitments as a hex string. * @param params.blobs.numChunksets - The total number of chunksets in the blob. * * @returns An Aptos transaction payload data object for the register_multiple_blobs Move function. */ static createBatchRegisterBlobsPayload(params: { deployer?: AccountAddress; account: AccountAddress; selectedLocation?: string; locationHint?: string; blobs: { blobName: BlobName; blobSize: number; blobMerkleRoot: string; numChunksets: number; }[]; useSponsoredUsdVariant?: boolean; encoding: number; encryption?: BlobEncryption; }): InputGenerateTransactionPayloadData; /** * Creates a transaction payload to delete a blob on the blockchain. * This is a static helper method for constructing the Move function call payload. * * @param params.deployer - Optional deployer account address. Defaults to SHELBY_DEPLOYER. * @param params.blobName - The blob name (e.g. "bar.txt", without the account address prefix). * * @returns An Aptos transaction payload data object for the delete_object Move function. */ static createDeleteObjectPayload(params: { deployer?: AccountAddress; blobName: string; }): InputGenerateTransactionPayloadData; /** * Creates a transaction payload to delete multiple blobs on the blockchain. * This is a static helper method for constructing the Move function call payload. * * This operation is atomic: if any blob deletion fails (e.g., blob not found), * the entire transaction fails and no blobs are deleted. * * @param params.deployer - Optional deployer account address. Defaults to SHELBY_DEPLOYER. * @param params.blobNames - Array of blob name suffixes without the account address prefix * (e.g. ["foo/bar.txt", "baz.txt"], NOT ["0x1/foo/bar.txt"]). The account address * prefix is automatically derived from the transaction sender. * * @returns An Aptos transaction payload data object for the delete_multiple_objects Move function. */ static createDeleteMultipleObjectsPayload(params: { deployer?: AccountAddress; blobNames: string[]; }): InputGenerateTransactionPayloadData; /** * Sort acks by slot and reduce to the `(ack_bits, signatures)` pair the * contract expects: it walks the set bits low-to-high and consumes the * signatures in that same order. */ private static encodeAcks; /** * Payload for `commit_object(uid, object_name_suffix, overwrite, if_match_etag, * ack_bits, signatures)` — binds a written pending blob under its object name, * finalizing the upload. SP acks may be batched in here (the contract applies * them before the `is_written` check), so register → upload → commit needs * only a single finalize transaction. * * @param params.uid - The blob UID returned at registration. * @param params.blobName - The object name suffix the blob was registered under. * @param params.overwrite - Allow replacing an existing binding under this name. * @param params.storageProviderAcks - Acks applied atomically with the commit. */ static createCommitObjectPayload(params: { deployer?: AccountAddress; uid: bigint; blobName: BlobName; overwrite: boolean; storageProviderAcks: StorageProviderAck[]; }): InputGenerateTransactionPayloadData; commitObject(params: { account: Account; uid: bigint; blobName: BlobName; overwrite: boolean; storageProviderAcks: StorageProviderAck[]; options?: AckTransactionOptions; }): Promise<{ transaction: PendingTransactionResponse; }>; } export { type AckTransactionOptions, type BuildOptions, type CommitRejectionReason, MissingTransactionSubmitterError, ObjectCommitRejectedError, ShelbyBlobClient, type UsdSponsorOptions, type WriteBlobCommitmentsOptions };