nft.storage
Version:
A client library for the https://nft.storage/ service. It provides a convenient interface for working with the HTTP API from a web browser or Node.js
364 lines • 12.5 kB
TypeScript
import type { CID } from 'multiformats';
export type { CID };
import type { BlockDecoder } from 'multiformats/block';
export type { BlockDecoder };
import type { CarReader } from '@ipld/car/api';
export type { CarReader };
/**
* Define nominal type of U based on type of T. Similar to Opaque types in Flow
*/
export type Tagged<T, Tag> = T & {
tag?: Tag;
};
export interface Service {
endpoint: URL;
token: string;
did?: string;
rateLimiter?: RateLimiter;
}
export interface PublicService {
endpoint: URL;
rateLimiter?: RateLimiter;
}
export interface FileObject {
name: string;
size: number;
stream: () => AsyncIterable<any>;
}
export type FilesSource = Iterable<File> | Iterable<FileObject> | AsyncIterable<File> | AsyncIterable<FileObject>;
/**
* CID in string representation
*/
export type CIDString = Tagged<string, CID>;
export interface API {
/**
* Encodes the given token and all resources it references (in the form of a
* File or a Blob) along with a metadata JSON as specificed in ERC-1155 to a
* CAR file. The `token.image` must be either a `File` or a `Blob` instance,
* which will be stored and the corresponding content address URL will be
* saved in the metadata JSON file under `image` field.
*
* If `token.properties` contains properties with `File` or `Blob` values,
* those also get stored and their URLs will be saved in the metadata JSON
* file in their place.
*
* Note: URLs for `File` objects will retain file names e.g. in case of
* `new File([bytes], 'cat.png', { type: 'image/png' })` will be transformed
* into a URL that looks like `ipfs://bafy...hash/image/cat.png`. For `Blob`
* objects, the URL will not have a file name name or mime type, instead it
* will be transformed into a URL that looks like
* `ipfs://bafy...hash/image/blob`.
*/
encodeNFT<T extends TokenInput>(input: T): Promise<{
token: Token<T>;
car: CarReader;
}>;
/**
* Encodes a single file to a CAR file and also returns it's root CID.
*/
encodeBlob(service: Service, content: Blob | File): Promise<{
cid: CID;
car: CarReader;
}>;
/**
* Encodes a directory of files to a CAR file and also returns the root CID.
* Provided files **MUST** be within the same directory, otherwise error is
* raised e.g. `foo/bar.png`, `foo/bla/baz.json` is ok but `foo/bar.png`,
* `bla/baz.json` is not.
*/
encodeDirectory(files: Iterable<File>): Promise<{
cid: CID;
car: CarReader;
}>;
/**
* Stores the given token and all resources it references (in the form of a
* File or a Blob) along with a metadata JSON as specificed in ERC-1155. The
* `token.image` must be either a `File` or a `Blob` instance, which will be
* stored and the corresponding content address URL will be saved in the
* metadata JSON file under `image` field.
*
* If `token.properties` contains properties with `File` or `Blob` values,
* those also get stored and their URLs will be saved in the metadata JSON
* file in their place.
*
* Note: URLs for `File` objects will retain file names e.g. in case of
* `new File([bytes], 'cat.png', { type: 'image/png' })` will be transformed
* into a URL that looks like `ipfs://bafy...hash/image/cat.png`. For `Blob`
* objects, the URL will not have a file name name or mime type, instead it
* will be transformed into a URL that looks like
* `ipfs://bafy...hash/image/blob`.
*/
store<T extends TokenInput>(service: Service, token: T, options?: RequestOptions): Promise<Token<T>>;
/**
* Stores a single file and returns it's CID.
*/
storeBlob(service: Service, content: Blob | File, options?: RequestOptions): Promise<CIDString>;
/**
* Stores a CAR file and returns it's root CID.
*/
storeCar(service: Service, content: Blob | CarReader, options?: CarStorerOptions): Promise<CIDString>;
/**
* Stores a directory of files and returns a CID. Provided files **MUST**
* be within the same directory, otherwise error is raised e.g. `foo/bar.png`,
* `foo/bla/baz.json` is ok but `foo/bar.png`, `bla/baz.json` is not.
*/
storeDirectory(service: Service, files: FilesSource, options?: RequestOptions): Promise<CIDString>;
/**
* Returns current status of the stored NFT by its CID. Note the NFT must
* have previously been stored by this account.
*/
status(service: Service, cid: string, options?: RequestOptions): Promise<StatusResult>;
/**
* Removes stored content by its CID from this account. Please note that
* even if content is removed from the service other nodes that have
* replicated it might still continue providing it.
*/
delete(service: Service, cid: string, options?: RequestOptions): Promise<void>;
/**
* Check if a CID of an NFT is being stored by NFT.Storage.
*/
check(service: PublicService, cid: string, options?: RequestOptions): Promise<CheckResult>;
}
export interface RequestOptions {
/**
* A signal that can be used to abort the request.
*/
signal?: AbortSignal;
}
export interface CarStorerOptions extends RequestOptions {
/**
* Callback called after each chunk of data has been uploaded. By default,
* data is split into chunks of around 10MB. It is passed the actual chunk
* size in bytes.
*/
onStoredChunk?: (size: number) => void;
/**
* Maximum times to retry a failed upload. Default: 5
*/
maxRetries?: number;
/**
* Maximum chunk size to upload in bytes. Default: 52,428,800
*/
maxChunkSize?: number;
/**
* Additional IPLD block decoders. Used to interpret the data in the CAR
* file and split it into multiple chunks. Note these are only required if
* the CAR file was not encoded using the default encoders: `dag-pb`,
* `dag-cbor` and `raw`.
*/
decoders?: BlockDecoder<any, any>[];
}
export interface CheckResult {
cid: string;
pin: {
status: PinStatus;
};
deals: Deal[];
}
export interface StatusResult {
cid: string;
size: number;
deals: Deal[];
pin: Pin;
created: Date;
}
export type Deal = QueuedDeal | PendingDeal | FailedDeal | PublishedDeal | FinalizedDeal;
export interface DealInfo {
lastChanged: Date;
/**
* Miner ID
*/
miner: string;
/**
* Filecoin network for this Deal
* TODO this needs to be removed
*/
network?: 'nerpanet' | 'mainnet';
/**
* Piece CID string
*/
pieceCid: CIDString;
/**
* CID string
*/
batchRootCid: CIDString;
}
export interface QueuedDeal {
status: 'queued';
/**
* Timestamp in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format: YYYY-MM-DDTHH:MM:SSZ.
*/
lastChanged: Date;
}
export interface PendingDeal extends DealInfo {
status: 'proposing' | 'accepted';
}
export interface FailedDeal extends DealInfo {
status: 'failed';
/**
* Reason deal failed.
*/
statusText: string;
}
export interface PublishedDeal extends DealInfo {
status: 'published';
/**
* Identifier for the deal stored on chain.
*/
chainDealID: number;
}
export interface FinalizedDeal extends DealInfo {
status: 'active' | 'terminated';
/**
* Identifier for the deal stored on chain.
*/
chainDealID: number;
/**
* Selector for extracting stored data from the batch root.
*/
datamodelSelector: string;
/**
* Deal Activation
*/
dealActivation: Date;
/**
* Deal Expiraction
*/
dealExpiration: Date;
}
export interface Pin {
cid: CIDString;
name?: string;
status: PinStatus;
created: Date;
}
export type PinStatus = 'queued' | 'pinning' | 'pinned' | 'failed';
/**
* This is an input used to construct the Token metadata as per EIP-1155
* @see https://eips.ethereum.org/EIPS/eip-1155#metadata
*/
export interface TokenInput {
/**
* Identifies the asset to which this token represents
*/
name: string;
/**
* Describes the asset to which this token represents
*/
description: string;
/**
* A `File` with mime type `image/*` representing the asset this
* token represents. Consider creating images with width between `320` and
* `1080` pixels and aspect ratio between `1.91:1` and `4:5` inclusive.
*
* If a `File` object is used, the URL in the metadata will include a filename
* e.g. `ipfs://bafy...hash/cat.png`. If a `Blob` is used, the URL in the
* metadata will not include filename or extension e.g. `ipfs://bafy...img/`
*/
image: Blob | File;
/**
* The number of decimal places that the token amount should display - e.g.
* `18`, means to divide the token amount by `1000000000000000000` to get its
* user representation.
*/
decimals?: number;
/**
* Arbitrary properties. Values may be strings, numbers, nested objects or
* arrays of values. It is possible to provide `File` or `Blob` instances
* as property values, which will be stored on IPFS, and metadata will
* contain URLs to them in form of `ipfs://bafy...hash/name.png` or
* `ipfs://bafy...file/` respectively.
*/
properties?: Object;
localization?: Localization;
}
interface Localization {
/**
* The URI pattern to fetch localized data from. This URI should contain the
* substring `{locale}` which will be replaced with the appropriate locale
* value before sending the request.
*/
uri: string;
/**
* The locale of the default data within the base JSON
*/
default: string;
/**
* The list of locales for which data is available. These locales should
* conform to those defined in the Unicode Common Locale Data Repository
* (http://cldr.unicode.org/).
*/
locales: string[];
}
export interface Token<T extends TokenInput> {
/**
* CID for the token that encloses all of the files including metadata.json
* for the stored token.
*/
ipnft: CIDString;
/**
* URL like `ipfs://bafy...hash/meta/data.json` for the stored token metadata.
*/
url: EncodedURL;
/**
* Actual token data in ERC-1155 format. It matches data passed as `token`
* argument except Files/Blobs are substituted with corresponding `ipfs://`
* URLs.
*/
data: Encoded<T, [[Blob, URL]]>;
/**
* Token data just like in `data` field except urls corresponding to
* Files/Blobs are substituted with IPFS gateway URLs so they can be
* embedded in browsers that do not support `ipfs://` protocol.
*/
embed(): Encoded<T, [[Blob, URL]]>;
}
export type EncodedError = {
message: string;
};
export type EncodedURL = Tagged<string, URL>;
export type Result<X, T> = {
ok: true;
value: T;
} | {
ok: false;
error: X;
};
export interface EncodedToken<T extends TokenInput> {
ipnft: CIDString;
url: EncodedURL;
data: Encoded<T, [[Blob, EncodedURL]]>;
}
export type StoreResponse<T extends TokenInput> = Result<EncodedError, EncodedToken<T>>;
/**
* Represents `T` encoded with a given `Format`.
* @example
* ```ts
* type Format = [
* [URL, { type: 'URL', href: string }]
* [CID, { type: 'CID', cid: string }]
* [Blob, { type: 'Blob', href: string }]
* ]
*
* type Response<T> = Encoded<T, Format>
* ```
*/
export type Encoded<T, Format extends Pattern<any, any>[]> = MatchRecord<T, Rule<Format[number]>>;
/**
* Format consists of multiple encoding defines what input type `I` maps to what output type `O`. It
* can be represented via function type or a [I, O] tuple.
*/
type Pattern<I, O> = ((input: I) => O) | [I, O];
export type MatchRecord<T, R extends Rule<any>> = {
[K in keyof T]: MatchRule<T[K], R> extends never ? MatchRecord<T[K], R> : MatchRule<T[K], R>;
};
type MatchRule<T, R extends Rule<any>> = R extends (input: T) => infer O ? O : never;
type Rule<Format extends Pattern<any, any>> = Format extends [infer I, infer O] ? (input: I) => O : Format extends (input: infer I) => infer O ? (input: I) => O : never;
/**
* RateLimiter returns a promise that resolves when it is safe to send a request
* that does not exceed the rate limit.
*/
export interface RateLimiter {
(): Promise<void>;
}
//# sourceMappingURL=interface.d.ts.map