From 0581ab85d3763049fcdba3372376a2bac5b81329 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Thu, 31 Oct 2024 15:56:02 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Modal=20builder=20+=20interaction?= =?UTF-8?q?=20token=20in=20session=20storage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/sdk/src/core/actions/index.ts | 1 + .../sdk/src/core/actions/watchWalletStatus.ts | 34 +++- .../src/core/actions/wrapper/modalBuilder.ts | 149 ++++++++++++++++++ 3 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 packages/sdk/src/core/actions/wrapper/modalBuilder.ts diff --git a/packages/sdk/src/core/actions/index.ts b/packages/sdk/src/core/actions/index.ts index 65d38ef0..622be228 100644 --- a/packages/sdk/src/core/actions/index.ts +++ b/packages/sdk/src/core/actions/index.ts @@ -13,6 +13,7 @@ export { sendTransaction, type SendTransactionParams, } from "./wrapper/sendTransaction"; +export { modalBuilder } from "./wrapper/modalBuilder"; // Referral interaction export { referralInteraction } from "./referral/referralInteraction"; export { processReferral } from "./referral/processReferral"; diff --git a/packages/sdk/src/core/actions/watchWalletStatus.ts b/packages/sdk/src/core/actions/watchWalletStatus.ts index 57552f15..4d799038 100644 --- a/packages/sdk/src/core/actions/watchWalletStatus.ts +++ b/packages/sdk/src/core/actions/watchWalletStatus.ts @@ -13,7 +13,15 @@ export function watchWalletStatus( ): Promise { // If no callback is provided, just do a request with deferred result if (!callback) { - return client.request({ method: "frak_listenToWalletStatus" }); + return client + .request({ method: "frak_listenToWalletStatus" }) + .then((result) => { + // Save the potential interaction token + savePotentialToken(result.interactionToken); + + // Return the result + return result; + }); } // Otherwise, listen to the wallet status and return the first one received @@ -30,6 +38,9 @@ export function watchWalletStatus( // Transmit the status to the callback callback(status); + // Save the potential interaction token + savePotentialToken(status.interactionToken); + // If the promise hasn't resolved yet, resolve it if (!hasResolved) { firstResult.resolve(status); @@ -39,3 +50,24 @@ export function watchWalletStatus( ) .then(() => firstResult.promise); } + +/** + * Helper to save a potential interaction token + * @param interactionToken + */ +function savePotentialToken(interactionToken?: string) { + if (typeof window === "undefined") { + return; + } + + if (interactionToken) { + // If we got an interaction token, save it + window.sessionStorage.setItem( + "frak-wallet-interaction-token", + interactionToken + ); + } else { + // Otherwise, remove it + window.sessionStorage.removeItem("frak.interaction-token"); + } +} diff --git a/packages/sdk/src/core/actions/wrapper/modalBuilder.ts b/packages/sdk/src/core/actions/wrapper/modalBuilder.ts new file mode 100644 index 00000000..7986f57b --- /dev/null +++ b/packages/sdk/src/core/actions/wrapper/modalBuilder.ts @@ -0,0 +1,149 @@ +import type { + DisplayModalParamsType, + FinalActionType, + FinalModalStepType, + LoginModalStepType, + ModalRpcMetadata, + ModalRpcStepsResultType, + ModalStepTypes, + NexusClient, + OpenInteractionSessionModalStepType, + SendTransactionModalStepType, +} from "../../types"; +import { displayModal } from "../displayModal"; + +/** + * Simple modal builder params builder + * @param client + * @param metadata + * @param login + * @param openSession + */ +export function modalBuilder( + client: NexusClient, + { + metadata, + login, + openSession, + }: { + metadata: ModalRpcMetadata; + login?: LoginModalStepType["params"]; + openSession?: OpenInteractionSessionModalStepType["params"]; + } +): ModalStepBuilder<[LoginModalStepType, OpenInteractionSessionModalStepType]> { + // Build the initial modal params + const baseParams: DisplayModalParamsType< + [LoginModalStepType, OpenInteractionSessionModalStepType] + > = { + steps: { + login: login ?? {}, + openSession: openSession ?? {}, + }, + metadata, + }; + + // Return the step builder + return modalStepsBuilder(client, baseParams); +} + +/** + * Represent the type of the modal step builder + */ +type ModalStepBuilder = { + params: DisplayModalParamsType; + sendTx: ( + options: SendTransactionModalStepType["params"] + ) => ModalStepBuilder<[...Steps, SendTransactionModalStepType]>; + reward: ( + options?: Omit + ) => ModalStepBuilder<[...Steps, FinalModalStepType]>; + sharing: ( + sharingOptions?: Extract< + FinalActionType, + { key: "sharing" } + >["options"], + options?: Omit + ) => ModalStepBuilder<[...Steps, FinalModalStepType]>; + display: () => Promise>; +}; + +/** + * Build builder helping to add steps to the modal + * @param client + * @param params + */ +function modalStepsBuilder( + client: NexusClient, + params: DisplayModalParamsType +): ModalStepBuilder { + // 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) { + 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 + ) { + return modalStepsBuilder<[...CurrentSteps, FinalModalStepType]>( + client, + { + ...params, + steps: { + ...params.steps, + final: { + ...options, + action: { key: "sharing", options: sharingOptions }, + }, + }, + } as DisplayModalParamsType<[...CurrentSteps, FinalModalStepType]> + ); + } + + // Function to display it + async function display() { + return await displayModal(client, params); + } + + return { + // Access current modal params + params, + // Function to add new steps + sendTx, + reward, + sharing, + // Display the modal + display, + }; +}