Skip to content

Commit

Permalink
Merge branch 'feat/sdk-completion' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
KONFeature committed Oct 31, 2024
2 parents 516bbff + 8fe1ebc commit 92ea6e4
Show file tree
Hide file tree
Showing 12 changed files with 297 additions and 90 deletions.
5 changes: 5 additions & 0 deletions .changeset/orange-cars-worry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@frak-labs/nexus-sdk": patch
---

Add a `modalBuilder` to ease modal creation
30 changes: 16 additions & 14 deletions example/vanilla-js/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import { setupFrakClient } from "./module/setupClient";
import { displayWalletStatus } from "./module/walletStatus";

// Export the setup function and config for use in other files
window.FrakSetup = { frakConfig, frakClient: null, modalShare };
window.FrakSetup = {
frakConfig,
frakClient: null,
modalShare,
modalBuilder: null,
};

document.addEventListener("DOMContentLoaded", () => {
console.log("NexusSDK", window.NexusSDK);
Expand All @@ -16,22 +21,19 @@ document.addEventListener("DOMContentLoaded", () => {
return;
}

const modalStepBuilder = window.NexusSDK.modalBuilder(frakClient, {
metadata: {
lang: "fr",
isDismissible: true,
},
login: loginModalStep,
});

window.FrakSetup.frakClient = frakClient;
window.FrakSetup.modalBuilder = modalStepBuilder;

window.NexusSDK.referralInteraction(frakClient, {
modalConfig: {
steps: {
login: loginModalStep,
openSession: {},
final: {
action: { key: "reward" },
},
},
metadata: {
lang: "fr",
isDismissible: true,
},
},
modalConfig: modalStepBuilder.reward().params,
options: {
alwaysAppendUrl: true,
},
Expand Down
15 changes: 2 additions & 13 deletions example/vanilla-js/src/module/login.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { loginModalStep } from "./config";

export function bindLoginButton() {
const loginButton = document.getElementById("login-button");
loginButton?.addEventListener("click", handleLogin);
Expand All @@ -19,20 +17,11 @@ async function handleLogin() {
loginButton.textContent = "Logging in...";

try {
if (!window.FrakSetup.frakClient) {
if (!window.FrakSetup.modalBuilder) {
console.error("Frak client not initialized");
return;
}
await window.NexusSDK.displayModal(window.FrakSetup.frakClient, {
metadata: {
lang: "fr",
isDismissible: true,
},
steps: {
login: loginModalStep,
openSession: {},
},
});
await window.FrakSetup.modalBuilder.display();
loginButton.textContent = "Logged In";
} catch (error) {
console.error("Login error:", error);
Expand Down
32 changes: 8 additions & 24 deletions example/vanilla-js/src/module/modalShare.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
import { loginModalStep } from "./config";

export function modalShare() {
const finalAction = {
key: "sharing",
options: {
popupTitle: "Share this article with your friends",
text: "Discover this awesome article",
link: typeof window !== "undefined" ? window.location.href : "",
},
} as const;
if (!window.FrakSetup.frakClient) {
if (!window.FrakSetup.modalBuilder) {
console.error("Frak client not initialized");
return;
}
window.NexusSDK.displayModal(window.FrakSetup.frakClient, {
metadata: {
lang: "fr",
isDismissible: true,
},
steps: {
login: loginModalStep,
openSession: {},
final: {
action: finalAction,
},
},
});
window.FrakSetup.modalBuilder
.sharing({
popupTitle: "Share this article with your friends",
text: "Discover this awesome article",
link: typeof window !== "undefined" ? window.location.href : "",
})
.display();
}
4 changes: 4 additions & 0 deletions example/vanilla-js/src/types/globals.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type {
ModalBuilder,
displayModal,
modalBuilder,
referralInteraction,
watchWalletStatus,
} from "@frak-labs/nexus-sdk/actions";
Expand All @@ -18,11 +20,13 @@ declare global {
displayModal: typeof displayModal;
referralInteraction: typeof referralInteraction;
watchWalletStatus: typeof watchWalletStatus;
modalBuilder: typeof modalBuilder;
};
FrakSetup: {
frakConfig: NexusWalletSdkConfig;
frakClient: NexusClient | null;
modalShare: () => void;
modalBuilder: ModalBuilder | null;
};
}
}
8 changes: 7 additions & 1 deletion packages/sdk/src/core/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ export { watchWalletStatus } from "./watchWalletStatus";
export { sendInteraction } from "./sendInteraction";
export { displayModal } from "./displayModal";
export { openSso } from "./openSso";
// Helper to track the purchase status
export { trackPurchaseStatus } from "./trackPurchaseStatus";
// Modal wrappers
export {
siweAuthenticate,
Expand All @@ -11,7 +13,11 @@ export {
sendTransaction,
type SendTransactionParams,
} from "./wrapper/sendTransaction";
export { walletStatus } from "./wrapper/walletStatus";
export {
modalBuilder,
type ModalStepBuilder,
type ModalBuilder,
} from "./wrapper/modalBuilder";
// Referral interaction
export { referralInteraction } from "./referral/referralInteraction";
export { processReferral } from "./referral/processReferral";
4 changes: 2 additions & 2 deletions packages/sdk/src/core/actions/referral/referralInteraction.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Hex } from "viem";
import { walletStatus } from "../";
import { watchWalletStatus } from "../";
import type {
DisplayModalParamsType,
ModalStepTypes,
Expand Down Expand Up @@ -29,7 +29,7 @@ export async function referralInteraction(
});

// Get the current wallet status
const currentWalletStatus = await walletStatus(client);
const currentWalletStatus = await watchWalletStatus(client);

try {
return await processReferral(client, {
Expand Down
31 changes: 31 additions & 0 deletions packages/sdk/src/core/actions/trackPurchaseStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Function used to track the status of a purchase
*/
export async function trackPurchaseStatus(args: {
customerId: string | number;
orderId: string | number;
token: string;
}) {
if (typeof window === "undefined") {
console.warn("[Frak] No window found, can't track purchase");
return;
}
const interactionToken = window.sessionStorage.getItem(
"frak-wallet-interaction-token"
);
if (!interactionToken) {
console.warn("[Frak] No frak session found, skipping purchase check");
return;
}

// Submit the listening request
await fetch("https://backend.frak.id/interactions/listenForPurchase", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"x-wallet-sdk-auth": interactionToken,
},
body: JSON.stringify(args),
});
}
70 changes: 62 additions & 8 deletions packages/sdk/src/core/actions/watchWalletStatus.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { NexusClient } from "../types/client";
import type { WalletStatusReturnType } from "../types/rpc/walletStatus";
import { Deferred } from "../utils";

/**
* Function used to watch the current nexus wallet status
Expand All @@ -8,12 +9,65 @@ import type { WalletStatusReturnType } from "../types/rpc/walletStatus";
*/
export function watchWalletStatus(
client: NexusClient,
callback: (status: WalletStatusReturnType) => void
) {
return client.listenerRequest(
{
method: "frak_listenToWalletStatus",
},
callback
);
callback?: (status: WalletStatusReturnType) => void
): Promise<WalletStatusReturnType> {
// If no callback is provided, just do a request with deferred result
if (!callback) {
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
const firstResult = new Deferred<WalletStatusReturnType>();
let hasResolved = false;

// Start the listening request, and return the first result
return client
.listenerRequest(
{
method: "frak_listenToWalletStatus",
},
(status) => {
// 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);
hasResolved = true;
}
}
)
.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");
}
}
Loading

0 comments on commit 92ea6e4

Please sign in to comment.