@micro-stacks/client
Version:
Session client for Stacks apps using micro-stacks
338 lines (327 loc) • 15 kB
TypeScript
import { ContractCallTxOptions, FinishedTxData, StxTransferTxOptions, ContractDeployTxOptions, StacksSessionState, SignedOptionsWithOnHandlers, PSBTOptionsWithOnHandlers, PsbtPayload, PsbtData, SignatureData, Profile } from 'micro-stacks/connect';
import * as micro_stacks_network from 'micro-stacks/network';
import { StacksNetwork, ChainID } from 'micro-stacks/network';
import { ClarityValue } from 'micro-stacks/clarity';
import * as micro_stacks_storage from 'micro-stacks/storage';
import { Mutate, StoreApi } from 'zustand/vanilla';
import { EncryptContentOptions } from 'micro-stacks/crypto';
declare type BaseStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
declare const DEFAULT_PREFIX = "micro-stacks";
declare type ClientStorage<V = unknown> = {
getItem: <Value = V>(key: string, defaultValue?: Value | null) => Value | null;
setItem: <Value>(key: string, value: Value | null) => void;
removeItem: (key: string) => void;
};
declare const noopStorage: BaseStorage;
declare const defaultStorage: ClientStorage<unknown>;
declare function createStorage<V = unknown>({ storage, key: prefix, serialize, deserialize, }: {
storage: BaseStorage;
serialize?: any;
deserialize?: any;
key?: string;
}): ClientStorage<V>;
declare enum TxType {
ContractCall = "contract_call",
TokenTransfer = "token_transfer",
ContractDeploy = "contract_deploy"
}
declare enum StatusKeys {
Authentication = "status/Authentication",
TransactionSigning = "status/TransactionSigning",
MessageSigning = "status/MessageSigning",
StructuredMessageSigning = "status/StructuredMessageSigning",
PsbtSigning = "status/PsbtSigning"
}
declare enum Status {
IsLoading = "status/IsLoading",
IsIdle = "status/IsIdle"
}
declare const STORE_KEY = "store";
declare const IS_SSR: boolean;
interface AppDetails {
name: string;
icon: string;
}
declare type ContractCallParams = Omit<ContractCallTxOptions, 'network' | 'privateKey' | 'appDetails' | 'stxAddress'> & {
onFinish?: (payload: FinishedTxData) => void;
onCancel?: (error?: string) => void;
};
declare type StxTransferParams = Omit<StxTransferTxOptions, 'network' | 'privateKey' | 'appDetails' | 'stxAddress'> & {
onFinish?: (payload: FinishedTxData) => void;
onCancel?: (error?: string) => void;
};
declare type ContractDeployParams = Omit<ContractDeployTxOptions, 'network' | 'privateKey' | 'appDetails' | 'stxAddress'> & {
onFinish?: (payload: FinishedTxData) => void;
onCancel?: (error?: string) => void;
};
interface SignTransactionRequest {
(type: TxType.ContractDeploy, params: ContractDeployParams): Promise<FinishedTxData | undefined>;
(type: TxType.ContractCall, params: ContractCallParams): Promise<FinishedTxData | undefined>;
(type: TxType.TokenTransfer, params: StxTransferParams): Promise<FinishedTxData | undefined>;
}
declare type getInitialState = (key: string) => string | undefined;
interface DebugOptions {
disableAppPrivateKey?: boolean;
}
interface ClientConfig {
appName?: string;
appIconUrl?: string;
storage?: ClientStorage;
network?: 'testnet' | 'mainnet' | StacksNetwork;
enableNetworkSwitching?: boolean;
dehydratedState?: string | getInitialState;
onPersistState?: (dehydratedState: string) => void | Promise<void>;
onSignOut?: () => void;
onAuthentication?: (payload: StacksSessionState) => void;
onNoWalletFound?: () => void | Promise<void>;
fetcher?: (input: RequestInfo, init?: RequestInit) => Promise<Response>;
}
interface Account {
appPrivateKey?: string;
address: [version: number, hash: string];
decentralizedID?: string;
profile_url?: string;
}
declare type State = {
appName?: string;
appIconUrl?: string;
statuses: {
[StatusKeys.Authentication]: Status;
[StatusKeys.TransactionSigning]: Status;
[StatusKeys.MessageSigning]: Status;
[StatusKeys.StructuredMessageSigning]: Status;
};
network: StacksNetwork;
currentAccountIndex: number;
accounts: Account[];
onPersistState?: ClientConfig['onPersistState'];
onSignOut?: ClientConfig['onSignOut'];
onAuthentication?: ClientConfig['onAuthentication'];
onNoWalletFound?: ClientConfig['onNoWalletFound'];
};
declare type OpenSignMessageParams = SignedOptionsWithOnHandlers<{
message: string;
}>;
interface StructuredDataDomainTuple {
name?: string;
version?: string;
chainId?: ChainID;
}
declare type OpenSignStructuredMessageParams = SignedOptionsWithOnHandlers<{
message: string | ClarityValue;
domain?: StructuredDataDomainTuple;
}>;
interface SerializedAccount {
appPrivateKey: null | string;
address: string;
profile_url: string;
}
declare type AccountsTuple = [currentAccountIndex: number, accounts: SerializedAccount[]];
declare type DehydratedState = [
network: [chainId: number, apiUrl: string],
accounts: AccountsTuple,
version: number
];
declare type StacksMessageParams = Pick<SignInWithStacksMessage, "domain" | "address" | "statement" | "uri" | "version" | "chainId" | "nonce" | "issuedAt" | "expirationTime" | "notBefore" | "requestId" | "resources">;
interface VerifyParams {
signature: string;
domain?: string;
nonce?: string;
time?: string;
}
interface SiwsResponse {
success: boolean;
error?: SiwsError;
data: SignInWithStacksMessage;
}
declare class SiwsError {
constructor(type: SiwsErrorType, expected?: string, received?: string);
type: SiwsErrorType;
expected?: string;
received?: string;
}
declare enum SiwsErrorType {
EXPIRED_MESSAGE = "Expired message.",
INVALID_DOMAIN = "Invalid domain.",
DOMAIN_MISMATCH = "Domain do not match provided domain for verification.",
NONCE_MISMATCH = "Nonce do not match provided nonce for verification.",
INVALID_ADDRESS = "Invalid address.",
INVALID_URI = "URI does not conform to RFC 3986.",
INVALID_NONCE = "Nonce size smaller then 8 characters or is not alphanumeric.",
NOT_YET_VALID_MESSAGE = "Message is not valid yet.",
INVALID_SIGNATURE = "Signature do not match address of the message.",
INVALID_TIME_FORMAT = "Invalid time format.",
INVALID_MESSAGE_VERSION = "Invalid message version.",
UNABLE_TO_PARSE = "Unable to parse the message."
}
declare class SignInWithStacksMessage {
domain: string;
address: string;
statement?: string;
uri: string;
version: string;
chainId?: number;
nonce: string;
issuedAt?: string;
expirationTime?: string;
notBefore?: string;
requestId?: string;
resources?: string[];
constructor(param: string | StacksMessageParams);
toMessage(): string;
prepareMessage(): string;
verify(params: VerifyParams): Promise<SiwsResponse>;
private validateMessage;
}
declare class MicroStacksClient {
config: ClientConfig;
storage: ClientStorage;
store: Mutate<StoreApi<State>, [
['zustand/subscribeWithSelector', never],
['zustand/persist', State]
]>;
debug?: DebugOptions;
fetcher: (input: RequestInfo, init?: RequestInit) => Promise<Response>;
constructor(initConfig?: ClientConfig);
getState: () => State;
private setState;
private resetState;
get subscribe(): {
(listener: (selectedState: State, previousSelectedState: State) => void): () => void;
<U>(selector: (state: State) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
equalityFn?: ((a: U, b: U) => boolean) | undefined;
fireImmediately?: boolean | undefined;
} | undefined): () => void;
};
private onStorageUpdate;
tabSyncSubscription: (isEnabled?: boolean) => () => void;
private getStacksProvider;
subscribeToStacksProvider(callback: () => void, intervalMs?: number): () => void;
private get storeKey();
private onPersistState;
private get onAuthentication();
private get onNoWalletFound();
private get onSignOut();
setOnPersistState: (onPersistState: (dehydratedState: string) => void | Promise<void>) => void;
setOnNoWalletFound: (onNoWalletFound: () => void | Promise<void>) => void;
setOnSignOut: (onSignOut: ClientConfig['onSignOut']) => void;
setOnAuthentication: (onAuthentication: ClientConfig['onAuthentication']) => void;
persist: () => Promise<void>;
dehydrate(state?: State): string;
hydrate(dehydratedState: string): void;
selectHasSession: (state: State) => boolean;
selectAccounts: (state: State) => Account[];
selectAccount: (state: State) => Account | undefined;
selectNetwork: (state: State) => StacksNetwork;
selectNetworkChain: (state: State) => "mainnet" | "testnet";
selectTestnetStxAddress: (state: State) => string | undefined;
selectMainnetStxAddress: (state: State) => string | undefined;
selectStxAddress: (state: State) => string | undefined;
selectAppDetails: (state: State) => {
name: string;
icon: string;
} | undefined;
selectIdentityAddress: (state: State) => string | undefined;
selectDecentralizedID: (state: State) => string | undefined;
selectStatuses: (state: State) => {
"status/Authentication": Status;
"status/TransactionSigning": Status;
"status/MessageSigning": Status;
"status/StructuredMessageSigning": Status;
};
setStatus(key: StatusKeys, status: Status): void;
setIsRequestPending(key: StatusKeys): void;
setIsIdle(key: StatusKeys): void;
statuses: () => {
"status/Authentication": Status;
"status/TransactionSigning": Status;
"status/MessageSigning": Status;
"status/StructuredMessageSigning": Status;
};
isSignMessageRequestPending: () => Status;
isSignStructuredMessageRequestPending: () => Status;
handleNoStacksProviderFound(): boolean;
authenticate: (params?: {
onFinish?: ((session: Omit<StacksSessionState, 'profile'>) => void) | undefined;
onCancel?: ((error?: Error) => void) | undefined;
} | undefined) => Promise<void>;
signOut: (onSignOut?: (() => void) | (() => Promise<void>)) => Promise<void | undefined>;
getSignInMessage: ({ domain, nonce, version, statement, }: {
domain?: string | undefined;
nonce: string;
version?: string | undefined;
statement?: string | undefined;
}) => SignInWithStacksMessage | undefined;
signTransaction: SignTransactionRequest;
signPSBT: (params: PSBTOptionsWithOnHandlers<Omit<PsbtPayload, 'publicKey'>>) => Promise<PsbtData | undefined>;
signMessage: (params: SignedOptionsWithOnHandlers<{
message: string;
}>) => Promise<SignatureData | undefined>;
signStructuredMessage: (params: SignedOptionsWithOnHandlers<{
message: string | ClarityValue;
domain?: {
name?: string;
version?: string;
chainId?: ChainID;
};
}>) => Promise<SignatureData | undefined>;
setNetwork: (network: 'mainnet' | 'testnet' | StacksNetwork) => void;
selectGaiaHubConfig(state: State): micro_stacks_storage.GaiaHubConfig | undefined;
putFile: (path: string, contents: string | Uint8Array | ArrayBufferView | Blob, { encrypt, sign }: {
encrypt?: boolean | undefined;
sign?: boolean | undefined;
}) => Promise<string> | undefined;
getFile: (path: string, { decrypt, verify }: {
decrypt?: boolean | undefined;
verify?: boolean | undefined;
}) => Promise<string | Uint8Array | null> | undefined;
fetchBNSName(): Promise<string | undefined>;
fetchZoneFile(): Promise<any>;
fetchProfile(): Promise<Profile | undefined>;
encrypt(content: string | Uint8Array, options?: EncryptContentOptions): Promise<string>;
decrypt(content: string, options: {
privateKey: string;
}): Promise<string | Uint8Array>;
}
declare type Client = typeof client;
interface Options$1 {
config?: ClientConfig;
client?: MicroStacksClient;
}
declare let client: MicroStacksClient;
declare function createClient(options?: Options$1): MicroStacksClient;
declare function getClient(options?: Options$1): MicroStacksClient;
declare function cleanDehydratedState(dehydratedState: string): string;
declare function cleanDehydratedState(dehydratedState: null): null;
interface Options {
client: MicroStacksClient;
state?: State;
}
declare const getAccounts: ({ client, state }: Options) => Account[];
declare const getCurrentAccount: ({ client, state }: Options) => Account | undefined;
declare const getStxAddress: ({ client, state }: Options) => string | undefined;
declare const getIdentityAddress: ({ client, state }: Options) => string | undefined;
declare const getDecentralizedID: ({ client, state }: Options) => string | undefined;
declare const getNetwork: ({ client, state }: Options) => micro_stacks_network.StacksNetwork;
declare const getStatus: ({ client, state }: Options) => {
"status/Authentication": Status;
"status/TransactionSigning": Status;
"status/MessageSigning": Status;
"status/StructuredMessageSigning": Status;
};
declare const getAppDetails: ({ client, state }: Options) => {
name: string;
icon: string;
} | undefined;
declare const watchAccounts: (callback: (payload: State['accounts']) => void, client?: MicroStacksClient) => () => void;
declare const watchCurrentAccount: (callback: (payload?: Account) => void, client?: MicroStacksClient) => () => void;
declare const watchStxAddress: (callback: (payload?: string) => void, client?: MicroStacksClient) => () => void;
declare const watchIdentityAddress: (callback: (payload?: string) => void, client?: MicroStacksClient) => () => void;
declare const watchDecentralizedID: (callback: (payload?: string) => void, client?: MicroStacksClient) => () => void;
declare const watchNetwork: (callback: (payload: State['network']) => void, client?: MicroStacksClient) => () => void;
declare const watchStatus: (callback: (payload: State['statuses']) => void, client?: MicroStacksClient) => () => void;
declare const watchAppDetails: (callback: (payload?: {
name?: string;
icon?: string;
}) => void, client?: MicroStacksClient) => () => void;
export { Account, AppDetails, Client, ClientConfig, ClientStorage, ContractCallParams, ContractDeployParams, DEFAULT_PREFIX, DebugOptions, DehydratedState, IS_SSR, MicroStacksClient, OpenSignMessageParams, OpenSignStructuredMessageParams, STORE_KEY, SignInWithStacksMessage, SignTransactionRequest, State, Status, StatusKeys, StructuredDataDomainTuple, StxTransferParams, TxType, cleanDehydratedState, client, createClient, createStorage, defaultStorage, getAccounts, getAppDetails, getClient, getCurrentAccount, getDecentralizedID, getIdentityAddress, getNetwork, getStatus, getStxAddress, noopStorage, watchAccounts, watchAppDetails, watchCurrentAccount, watchDecentralizedID, watchIdentityAddress, watchNetwork, watchStatus, watchStxAddress };