Skip to content

Commit

Permalink
✨ Modal builder + interaction token in session storage
Browse files Browse the repository at this point in the history
  • Loading branch information
KONFeature committed Oct 31, 2024
1 parent cfc6d8c commit 0581ab8
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/sdk/src/core/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
34 changes: 33 additions & 1 deletion packages/sdk/src/core/actions/watchWalletStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@ export function watchWalletStatus(
): Promise<WalletStatusReturnType> {
// 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
Expand All @@ -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);
Expand All @@ -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");
}
}
149 changes: 149 additions & 0 deletions packages/sdk/src/core/actions/wrapper/modalBuilder.ts
Original file line number Diff line number Diff line change
@@ -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<Steps extends ModalStepTypes[]> = {
params: DisplayModalParamsType<Steps>;
sendTx: (
options: SendTransactionModalStepType["params"]
) => ModalStepBuilder<[...Steps, SendTransactionModalStepType]>;
reward: (
options?: Omit<FinalModalStepType["params"], "action">
) => ModalStepBuilder<[...Steps, FinalModalStepType]>;
sharing: (
sharingOptions?: Extract<
FinalActionType,
{ key: "sharing" }
>["options"],
options?: Omit<FinalModalStepType["params"], "action">
) => ModalStepBuilder<[...Steps, FinalModalStepType]>;
display: () => Promise<ModalRpcStepsResultType<Steps>>;
};

/**
* Build builder helping to add steps to the modal
* @param client
* @param params
*/
function modalStepsBuilder<CurrentSteps extends ModalStepTypes[]>(
client: NexusClient,
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]>
);
}

// 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,
};
}

0 comments on commit 0581ab8

Please sign in to comment.