import { type ConnectionConfig } from "@aa-sdk/core"; import { TurnkeyClient, type TSignedRequest } from "@turnkey/http"; import EventEmitter from "eventemitter3"; import { type Address, type Hex } from "viem"; import type { AlchemySignerClientEvent, AlchemySignerClientEvents, AuthenticatingEventMetadata, CreateAccountParams, RemoveMfaParams, EmailAuthParams, AddMfaParams, AddMfaResult, experimental_CreateApiKeyParams, GetOauthProviderUrlArgs, GetWebAuthnAttestationResult, MfaFactor, JwtParams, JwtResponse, OauthConfig, OauthParams, OtpParams, SignerBody, SignerResponse, SignerRoutes, SignupResponse, User, VerifyMfaParams, SubmitOtpCodeResponse, ValidateMultiFactorsParams, AuthLinkingPrompt, AddOauthProviderParams, CredentialCreationOptionOverrides, OauthProviderInfo, IdTokenOnly, AuthMethods, SmsAuthParams, VerificationOtp } from "./types.js"; export interface BaseSignerClientParams { stamper: TurnkeyClient["stamper"]; connection: ConnectionConfig; rootOrgId?: string; rpId?: string; } export interface ExportPrivateKeyParams { type: "SOLANA" | "ETHEREUM"; client?: TurnkeyClient; orgId?: string; } export interface MultiOwnerExportPrivateKeyParams { type: "SOLANA" | "ETHEREUM"; orgId: string; } export interface ExportPrivateKeyEncryptedResult { exportBundle: string; ciphertext: string; encapsulatedKey: string; } export type ExportWalletStamper = TurnkeyClient["stamper"] & { injectWalletExportBundle(bundle: string, orgId: string): Promise; injectKeyExportBundle(bundle: string, orgId: string): Promise; publicKey(): string | null; }; type LookupUserByAccessKeyParams = { publicKey: string; accountId?: string; }; /** * Base class for all Alchemy Signer clients */ export declare abstract class BaseSignerClient { private _user; private connectionConfig; protected turnkeyClient: TurnkeyClient; protected rootOrg: string; protected eventEmitter: EventEmitter; protected oauthConfig: OauthConfig | undefined; /** * Create a new instance of the Alchemy Signer client * * @param {BaseSignerClientParams} params the parameters required to create the client */ constructor(params: BaseSignerClientParams); /** * Asynchronously fetches and sets the OAuth configuration. * * @returns {Promise} A promise that resolves to the OAuth configuration */ initOauth: () => Promise; protected get user(): User | undefined; protected set user(user: User | undefined); /** * Sets the stamper of the TurnkeyClient. * * @param {TurnkeyClient["stamper"]} stamper the stamper function to set for the TurnkeyClient */ protected setStamper(stamper: TurnkeyClient["stamper"]): void; /** * Authenticates the user by either email or passkey account creation flow. Emits events during the process. * * @param {CreateAccountParams} params The parameters for creating an account, including the type (email or passkey) and additional details. * @returns {Promise} A promise that resolves with the response object containing the account creation result. */ createAccount(params: CreateAccountParams): Promise; abstract initEmailAuth(params: Omit): Promise<{ orgId: string; otpId?: string; multiFactors?: MfaFactor[]; }>; abstract initSmsAuth(params: Omit): Promise<{ orgId: string; otpId?: string; }>; abstract completeAuthWithBundle(params: { bundle: string; orgId: string; connectedEventName: keyof AlchemySignerClientEvents; authenticatingType: AuthenticatingEventMetadata["type"]; idToken?: string; accessToken?: string; }): Promise; abstract oauthWithRedirect(args: Extract): Promise; abstract oauthWithPopup(args: Extract): Promise; abstract submitOtpCode(args: Omit): Promise; abstract submitJwt(args: Omit): Promise; abstract disconnect(): Promise; abstract exportWallet(params: TExportWalletParams): Promise; abstract targetPublicKey(): Promise; protected abstract getOauthConfig(): Promise; protected abstract getWebAuthnAttestation(options?: CredentialCreationOptionOverrides, userDetails?: { username: string; }): Promise; /** * Initializes the session stamper and returns its public key. */ protected abstract initSessionStamper(): Promise; protected abstract initWebauthnStamper(user: User | undefined, options: CredentialCreationOptionOverrides | undefined): Promise; /** * Listen to events emitted by the client * * @param {AlchemySignerClientEvent} event the event you want to listen to * @param {AlchemySignerClientEvents[AlchemySignerClientEvent]} listener the callback function to execute when an event is fired * @returns {() => void} a function that will remove the listener when called */ on: (event: E, listener: AlchemySignerClientEvents[E]) => () => EventEmitter; /** * Sets the email for the authenticated user, allowing them to login with that * email. * * @deprecated You must contact Alchemy to enable this feature for your team, * as there are important security considerations. In particular, you must not * call this without first validating that the user owns this email account. * Recommended to use the email verification flow instead. * * @param {string} email The email to set for the user * @returns {Promise} A promise that resolves to the updated email * @throws {NotAuthenticatedError} If the user is not authenticated */ setEmail(email: string): Promise; /** * Sets the email for the authenticated user, allowing them to login with that * email. Must be called after calling `initOtp` with the email. * * @param {VerificationOtp} otp The OTP verification object including the OTP ID and OTP code * @returns {Promise} A promise that resolves to the updated email * @throws {NotAuthenticatedError} If the user is not authenticated */ setEmail(otp: VerificationOtp): Promise; /** * Removes the email for the authenticated user, disallowing them from login with that email. * * @returns {Promise} A promise that resolves when the email is removed * @throws {NotAuthenticatedError} If the user is not authenticated */ removeEmail: () => Promise; private updateEmail; /** * Updates the phone number for the authenticated user, allowing them to login with that * phone number. Must be called after calling `initOtp` with the phone number. * * @param {VerificationOtp} otp The OTP object including the OTP ID and OTP code * @returns {Promise} A promise that resolves when the phone number is set * @throws {NotAuthenticatedError} If the user is not authenticated */ setPhoneNumber: (otp: VerificationOtp) => Promise; /** * Removes the phone number for the authenticated user, disallowing them from login with that phone number. * * @returns {Promise} A promise that resolves when the phone number is removed * @throws {NotAuthenticatedError} If the user is not authenticated */ removePhoneNumber: () => Promise; private updatePhoneNumber; /** * Initiates an OTP (One-Time Password) verification process for a user contact. * * @param {("email" | "sms")} type - The type of OTP to send, either "email" or "sms" * @param {string} contact - The email address or phone number to send the OTP to * @returns {Promise<{ otpId: string }>} A promise that resolves to an object containing the OTP ID * @throws {NotAuthenticatedError} When no user is currently authenticated */ initOtp: (type: "email" | "sms", contact: string) => Promise<{ otpId: string; }>; /** * Handles the creation of authenticators using WebAuthn attestation and the provided options. Requires the user to be authenticated. * * @param {CredentialCreationOptions} options The options used to create the WebAuthn attestation * @returns {Promise} A promise that resolves to an array of authenticator IDs * @throws {NotAuthenticatedError} If the user is not authenticated */ addPasskey: (options: CredentialCreationOptions) => Promise; /** * Removes a passkey authenticator from the user's account. * * @param {string} authenticatorId The ID of the authenticator to remove. * @returns {Promise} A promise that resolves when the authenticator is removed. * @throws {NotAuthenticatedError} If the user is not authenticated. */ removePasskey: (authenticatorId: string) => Promise; /** * Asynchronously handles the authentication process using WebAuthn Stamper. If a user is provided, sets the user and returns it. Otherwise, retrieves the current user and initializes the WebAuthn stamper. * * @param {User} [user] An optional user object to authenticate * @returns {Promise} A promise that resolves to the authenticated user object */ lookupUserWithPasskey: (user?: User | undefined) => Promise; /** * Retrieves the status of the passkey for the current user. Requires the user to be authenticated. * * @returns {Promise<{ isPasskeyAdded: boolean }>} A promise that resolves to an object containing the passkey status * @throws {NotAuthenticatedError} If the user is not authenticated */ getPasskeyStatus: () => Promise<{ isPasskeyAdded: boolean; }>; /** * Adds an OAuth provider for the authenticated user using the provided parameters. Throws an error if the user is not authenticated. * * @param {AddOauthProviderParams} params The parameters for adding an OAuth provider, including `providerName` and `oidcToken`. * @throws {NotAuthenticatedError} Throws if the user is not authenticated. * @returns {Promise} A Promise that resolves when the OAuth provider is added. */ addOauthProvider: (params: AddOauthProviderParams) => Promise; /** * Deletes a specified OAuth provider for the authenticated user. * * @param {string} providerId The ID of the provider to be deleted * @throws {NotAuthenticatedError} If the user is not authenticated */ removeOauthProvider: (providerId: string) => Promise; /** * Retrieves the list of authentication methods for the current user. * * @returns {Promise} A promise that resolves to the list of authentication methods * @throws {NotAuthenticatedError} If the user is not authenticated */ listAuthMethods: () => Promise; /** * Retrieves the current user or fetches the user information if not already available. * * @param {string} [orgId] optional organization ID, defaults to the user's organization ID * @param {string} idToken an OIDC ID token containing additional user information * @param {string} accessToken an access token which if provided will be added to the user * @returns {Promise} A promise that resolves to the user object * @throws {Error} if no organization ID is provided when there is no current user */ whoami: (orgId?: string | undefined, idToken?: string, accessToken?: string) => Promise; /** * Generates a stamped whoami request for the current user. This request can then be used to call /signer/v1/whoami to get the user information. * This is useful if you want to get the user information in a different context like a server. You can pass the stamped request to the server * and then call our API to get the user information. Using this stamp is the most trusted way to get the user information since a stamp can only * belong to the user who created it. * * @returns {Promise} a promise that resolves to the "whoami" information for the logged in user * @throws {Error} if no organization ID is provided */ stampWhoami: () => Promise; /** * Generates a stamped getOrganization request for the current user. * * @returns {Promise} a promise that resolves to the "getOrganization" information for the logged in user * @throws {Error} if no user is authenticated */ stampGetOrganization: () => Promise; /** * Creates an API key that can take any action on behalf of the current user. * (Note that this method is currently experimental and is subject to change.) * * @param {CreateApiKeyParams} params Parameters for creating the API key. * @param {string} params.name Name of the API key. * @param {string} params.publicKey Public key to be used for the API key. * @param {number} params.expirationSec Number of seconds until the API key expires. * @throws {Error} If there is no authenticated user or the API key creation fails. */ experimental_createApiKey: (params: experimental_CreateApiKeyParams) => Promise; /** * Looks up information based on an email address. * * @param {string} email the email address to look up * @returns {Promise} the result of the lookup request */ lookupUserByEmail: (email: string) => Promise<{ orgId: string | null; }>; /** * Looks up information based on a phone number. * * @param {string} phone the phone number to look up * @returns {Promise} the result of the lookup request */ lookupUserByPhone: (phone: string) => Promise<{ orgId: string | null; }>; /** * Looks up information based on an access key. * * @param {LookupUserByAccessKeyParams} params - The access key parameters * @returns {Promise} The result of the lookup request */ lookupUserByAccessKey: (params: LookupUserByAccessKeyParams) => Promise<{ orgId: string | null; }>; /** * This will sign a message with the user's private key, without doing any transformations on the message. * For SignMessage or SignTypedData, the caller should hash the message before calling this method and pass * that result here. * * @param {Hex} msg the hex representation of the bytes to sign * @param {string} mode specify if signing should happen for solana or ethereum * @returns {Promise} the signature over the raw hex */ signRawMessage: (msg: Hex, mode?: "SOLANA" | "ETHEREUM") => Promise; private experimental_createMultiOwnerStamper; private experimental_createMultiOwnerTurnkeyClient; /** * This will sign on behalf of the multi-owner org, without doing any transformations on the message. * For SignMessage or SignTypedData, the caller should hash the message before calling this method and pass * that result here. * * @param {Hex} msg the hex representation of the bytes to sign * @param {string} orgId orgId of the multi-owner org to sign on behalf of * @param {string} orgAddress address of the multi-owner org to sign on behalf of * @returns {Promise} the signature over the raw hex */ experimental_multiOwnerSignRawMessage: (msg: Hex, orgId: string, orgAddress: string) => Promise<`0x${string}`>; /** * This will create a multi-owner account with the current user and additional specified signers * * @param {Address[]} additionalMembers members to add, aside from the currently authenticated user * @returns {Promise['result']>} created multi-owner account */ experimental_createMultiOwner: (additionalMembers: Address[]) => Promise<{ orgId: string; evmSignerAddress: Address; members: { evmSignerAddress: Address; }[]; }>; /** * This will add additional members to an existing multi-sig account * * @param {string} orgId orgId of the multi-sig to add members to * @param {Address[]} members the addresses of the members to add */ experimental_addToMultiOwner: (orgId: string, members: Address[]) => Promise; /** * This will remove members from an existing multi-sig account * * @param {string} orgId orgId of the multi-sig to remove members from * @param {Address[]} members the addresses of the members to remove */ experimental_deleteFromMultiOwner: (orgId: string, members: Address[]) => Promise; /** * Returns the current user or null if no user is set. * * @returns {User | null} the current user object or null if no user is available */ getUser: () => User | null; /** * Sends a POST request to the given signer route with the specified body and returns the response. * Not intended to be used directly, use the specific methods instead on the client instead. * * @param {SignerRoutes} route The route to which the request should be sent * @param {SignerBody} body The request body containing the data to be sent * @returns {Promise>} A promise that resolves to the response from the signer */ request: (route: R, body: SignerBody) => Promise>; /** * Retrieves the list of MFA factors configured for the current user. * * @returns {Promise<{ multiFactors: MfaFactor[] }>} A promise that resolves to an array of configured MFA factors * @throws {NotAuthenticatedError} If no user is authenticated */ getMfaFactors: () => Promise<{ multiFactors: MfaFactor[]; }>; /** * Initiates the setup of a new MFA factor for the current user. Mfa will need to be verified before it is active. * * @param {AddMfaParams} params The parameters required to enable a new MFA factor * @returns {Promise} A promise that resolves to the factor setup information * @throws {NotAuthenticatedError} If no user is authenticated * @throws {Error} If an unsupported factor type is provided */ addMfa: (params: AddMfaParams) => Promise; /** * Verifies a newly created MFA factor to complete the setup process. * * @param {VerifyMfaParams} params The parameters required to verify the MFA factor * @returns {Promise<{ multiFactors: MfaFactor[] }>} A promise that resolves to the updated list of MFA factors * @throws {NotAuthenticatedError} If no user is authenticated */ verifyMfa: (params: VerifyMfaParams) => Promise<{ multiFactors: MfaFactor[]; }>; /** * Removes existing MFA factors by ID. * * @param {RemoveMfaParams} params The parameters specifying which factors to disable * @returns {Promise<{ multiFactors: MfaFactor[] }>} A promise that resolves to the updated list of MFA factors * @throws {NotAuthenticatedError} If no user is authenticated */ removeMfa: (params: RemoveMfaParams) => Promise<{ multiFactors: MfaFactor[]; }>; /** * Validates multiple MFA factors using the provided encrypted payload and MFA codes. * * @param {ValidateMultiFactorsParams} params The validation parameters * @returns {Promise<{ bundle: string }>} A promise that resolves to an object containing the credential bundle * @throws {Error} If no credential bundle is returned from the server */ validateMultiFactors: (params: ValidateMultiFactorsParams) => Promise<{ bundle: string; }>; /** * Returns the authentication url for the selected OAuth Proivder * * @example * ```ts * * cosnt oauthParams = { * authProviderId: "google", * isCustomProvider: false, * auth0Connection: undefined, * scope: undefined, * claims: undefined, * mode: "redirect", * redirectUrl: "https://your-url-path/oauth-return", * expirationSeconds: 3000 * }; * * const turnkeyPublicKey = await this.initIframeStamper(); * const oauthCallbackUrl = this.oauthCallbackUrl; * const oauthConfig = this.getOauthConfig() // Optional value for OauthConfig() * const usesRelativeUrl = true // Optional value to determine if we use a relative (or absolute) url for the `redirect_url` * * const oauthProviderUrl = getOauthProviderUrl({ * oauthParams, * turnkeyPublicKey, * oauthCallbackUrl * }) * * ``` * @param {GetOauthProviderUrlArgs} args Required. The Oauth provider's auth parameters * * @returns {Promise} returns the Oauth provider's url */ protected getOauthProviderUrl: (args: GetOauthProviderUrlArgs) => Promise; private getOauthConfigForMode; protected pollActivityCompletion: >["activity"]["result"]>(activity: Awaited>["activity"], organizationId: string, resultKey: T) => Promise>["activity"]["result"][T]>>; /** * Turnkey requires the nonce in the id token to be in this format. * * @param {string} turnkeyPublicKey key from a Turnkey iframe * @returns {string} nonce to be used in OIDC */ protected getOauthNonce: (turnkeyPublicKey: string) => string; /** * Exports a private key for a given account encrypted with the provided public key * * @param {ExportPrivateKeyParams} opts the parameters for the export * @returns {Promise} the private key */ exportPrivateKeyEncrypted: (opts: ExportPrivateKeyParams & { encryptWith: string; }) => Promise; /** * Exports a private key for a given account * * @param {ExportPrivateKeyParams} opts the parameters for the export * @returns {Promise} the private key */ exportPrivateKey: (opts: ExportPrivateKeyParams) => Promise; /** * Exports a private key for a given account in a multi-owner org * * @param {MultiOwnerExportPrivateKeyParams} opts the parameters for the export * @returns {Promise} the private key */ experimental_multiOwnerExportPrivateKeyEncrypted: (opts: MultiOwnerExportPrivateKeyParams & { encryptWith: string; }) => Promise; } export {}; //# sourceMappingURL=base.d.ts.map