@frak-labs/core-sdk
Version:
Core SDK of the Frak wallet, low level library to interact directly with the frak ecosystem.
202 lines (192 loc) • 6.15 kB
text/typescript
import type {
DisplayModalParamsType,
FinalActionType,
FinalModalStepType,
FrakClient,
LoginModalStepType,
ModalRpcMetadata,
ModalRpcStepsResultType,
ModalStepTypes,
SendTransactionModalStepType,
} from "../../types";
import { displayModal } from "../displayModal";
/**
* Represent the type of the modal step builder
*/
export type ModalStepBuilder<
Steps extends ModalStepTypes[] = ModalStepTypes[],
> = {
/**
* The current modal params
*/
params: DisplayModalParamsType<Steps>;
/**
* Add a send transaction step to the modal
*/
sendTx: (
options: SendTransactionModalStepType["params"]
) => ModalStepBuilder<[...Steps, SendTransactionModalStepType]>;
/**
* Add a final step of type reward to the modal
*/
reward: (
options?: Omit<FinalModalStepType["params"], "action">
) => ModalStepBuilder<[...Steps, FinalModalStepType]>;
/**
* Add a final step of type sharing to the modal
*/
sharing: (
sharingOptions?: Extract<
FinalActionType,
{ key: "sharing" }
>["options"],
options?: Omit<FinalModalStepType["params"], "action">
) => ModalStepBuilder<[...Steps, FinalModalStepType]>;
/**
* Display the modal
* @param metadataOverride - Function returning optional metadata to override the current modal metadata
* @param placement - Optional placement ID to associate with this modal display
*/
display: (
metadataOverride?: (
current?: ModalRpcMetadata
) => ModalRpcMetadata | undefined,
placement?: string
) => Promise<ModalRpcStepsResultType<Steps>>;
};
/**
* Represent the output type of the modal builder
*/
export type ModalBuilder = ModalStepBuilder<[LoginModalStepType]>;
/**
* Helper to craft Frak modal, and share a base initial config
* @param client - The current Frak Client
* @param args
* @param args.metadata - Common modal metadata (customisation, language etc)
* @param args.login - Login step parameters
*
* @description This function will create a modal builder with the provided metadata and login parameters.
*
* @example
* Here is an example of how to use the `modalBuilder` to create and display a sharing modal:
*
* ```js
* // Create the modal builder
* const modalBuilder = window.FrakSDK.modalBuilder(frakClient, baseModalConfig);
*
* // Configure the information to be shared via the sharing link
* const sharingConfig = {
* popupTitle: "Share this with your friends",
* text: "Discover our product!",
* link: window.location.href,
* };
*
* // Display the sharing modal
* function modalShare() {
* modalBuilder.sharing(sharingConfig).display();
* }
* ```
*
* @see {@link ModalStepTypes} for more info about each modal step types and their parameters
* @see {@link ModalRpcMetadata} for more info about the metadata that can be passed to the modal
* @see {@link ModalRpcStepsResultType} for more info about the result of each modal steps
* @see {@link displayModal} for more info about how the modal is displayed
*/
export function modalBuilder(
client: FrakClient,
{
metadata,
login,
}: {
metadata?: ModalRpcMetadata;
login?: LoginModalStepType["params"];
}
): ModalBuilder {
// Build the initial modal params
const baseParams: DisplayModalParamsType<[LoginModalStepType]> = {
steps: {
login: login ?? {},
},
metadata,
};
// Return the step builder
return modalStepsBuilder(client, baseParams);
}
/**
* Modal step builder, allowing to add new steps to the modal, and to build and display it
*/
function modalStepsBuilder<CurrentSteps extends ModalStepTypes[]>(
client: FrakClient,
params: DisplayModalParamsType<CurrentSteps>
): ModalStepBuilder<CurrentSteps> {
// Function add the send tx step
function sendTx(options: SendTransactionModalStepType["params"]) {
return modalStepsBuilder<
[...CurrentSteps, SendTransactionModalStepType]
>(client, {
...params,
steps: {
...params.steps,
sendTransaction: options,
},
} as DisplayModalParamsType<
[...CurrentSteps, SendTransactionModalStepType]
>);
}
// Function to add a reward step at the end
function reward(options?: Omit<FinalModalStepType["params"], "action">) {
return modalStepsBuilder<[...CurrentSteps, FinalModalStepType]>(
client,
{
...params,
steps: {
...params.steps,
final: {
...options,
action: { key: "reward" },
},
},
} as DisplayModalParamsType<[...CurrentSteps, FinalModalStepType]>
);
}
// Function to add sharing step at the end
function sharing(
sharingOptions?: Extract<
FinalActionType,
{ key: "sharing" }
>["options"],
options?: Omit<FinalModalStepType["params"], "action">
) {
return modalStepsBuilder<[...CurrentSteps, FinalModalStepType]>(
client,
{
...params,
steps: {
...params.steps,
final: {
...options,
action: { key: "sharing", options: sharingOptions },
},
},
} as DisplayModalParamsType<[...CurrentSteps, FinalModalStepType]>
);
}
async function display(
metadataOverride?: (
current?: ModalRpcMetadata
) => ModalRpcMetadata | undefined,
placement?: string
) {
if (metadataOverride) {
params.metadata = metadataOverride(params.metadata ?? {});
}
return await displayModal(client, params, placement);
}
return {
params,
sendTx,
reward,
sharing,
display,
};
}