Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/lib/StringPay.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,20 @@ export interface StringOptions {
bypassDeviceCheck?: boolean;
}

export interface TransactionResponse {
txID: string;
txUrl: string;
}

export declare class StringPay {
isLoaded: boolean;
payload?: StringPayload;
frame?: HTMLIFrameElement;
container?: Element;
onFrameLoad: () => void;
onFrameClose: () => void;
onFrameLoad: () => void;
onFrameClose: () => void;
onTxSuccess: (req: StringPayload, tx: TransactionResponse) => void;
onTxError: (req: StringPayload, txErr: any) => void;
init(options: StringOptions): void;
loadFrame(payload: StringPayload): void;
}
7 changes: 5 additions & 2 deletions src/lib/StringPay.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createServices, type Services } from "./services";
import type { TransactionResponse } from "./services/apiClient.service";

export interface StringPayload {
assetName: string;
Expand Down Expand Up @@ -61,8 +62,10 @@ export class StringPay {
#services: Services;
private _IFRAME_URL: string;

onFrameLoad = () => {};
onFrameClose = () => {};
onFrameLoad: () => void;
onFrameClose: () => void;
onTxSuccess: (req: StringPayload, tx: TransactionResponse) => void;
onTxError: (req: StringPayload, txErr: any) => void;

init(options: StringOptions) {
const envDetails = ENV_TABLE[options.env];
Expand Down
39 changes: 23 additions & 16 deletions src/lib/services/events.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,14 @@ export function createEventsService(iframeUrl: string, authService: AuthService,

const _handleEvent = async (e: any) => {
if (e.origin !== iframeUrl) return;

const stringPay: StringPay = (<any>window).StringPay;


try {
const payload = JSON.parse(e.data);
const channel = payload.channel;
const event = <StringEvent>payload.event;
if (channel === CHANNEL) {
const handler = eventHandlers[event.eventName];
if (handler) await handler(event, stringPay);
if (handler) await handler(event, window.StringPay);
else console.debug("SDK :: Unhandled event: ", event);
}
} catch (error) {
Expand All @@ -74,12 +72,13 @@ export function createEventsService(iframeUrl: string, authService: AuthService,

function cleanup() {
unregisterEvents();

if ((<any>window).StringPay) {
(<any>window).StringPay.frame?.remove();
(<any>window).StringPay.frame = undefined;
(<any>window).StringPay.isLoaded = false;
(<any>window).StringPay.onFrameClose();
const stringPay = window.StringPay;

if (stringPay) {
stringPay.frame?.remove();
stringPay.frame = undefined;
stringPay.isLoaded = false;
if (stringPay.onFrameClose) stringPay.onFrameClose();
}
}

Expand Down Expand Up @@ -116,7 +115,8 @@ export function createEventsService(iframeUrl: string, authService: AuthService,
const iframePayload = createIframePayload(stringPay.payload, user);
sendEvent(stringPay.frame, Events.LOAD_PAYLOAD, iframePayload);
stringPay.isLoaded = true;
stringPay.onFrameLoad();

if (stringPay.onFrameLoad) stringPay.onFrameLoad();
}

async function onIframeClose() {
Expand Down Expand Up @@ -198,8 +198,8 @@ export function createEventsService(iframeUrl: string, authService: AuthService,
quoteService.stopQuote();
}

async function onConfirmTransaction(event: StringEvent, { frame }: StringPay) {
if (!frame) throw new Error("Iframe not ready");
async function onConfirmTransaction(event: StringEvent, stringPay: StringPay) {
if (!stringPay.frame) throw new Error("Iframe not ready");

try {
const paymentInfo = <PaymentInfo>{};
Expand All @@ -208,10 +208,17 @@ export function createEventsService(iframeUrl: string, authService: AuthService,
const data = <ExecutionRequest>event.data;
data.paymentInfo = paymentInfo;

const txHash = await apiClient.transact(data);
sendEvent(frame, Events.RECEIVE_CONFIRM_TRANSACTION, txHash);
const txRes = await apiClient.transact(data);
sendEvent(stringPay.frame, Events.RECEIVE_CONFIRM_TRANSACTION, txRes);

if (stringPay.onTxSuccess && stringPay.payload) {
stringPay.onTxSuccess(stringPay.payload, txRes);
}
} catch (error: any) {
sendEvent(frame, Events.RECEIVE_CONFIRM_TRANSACTION, {}, error);
sendEvent(stringPay.frame, Events.RECEIVE_CONFIRM_TRANSACTION, {}, error);
if (stringPay.onTxError && stringPay.payload) {
stringPay.onTxError(stringPay.payload, error);
}
}
}

Expand Down
10 changes: 9 additions & 1 deletion src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<script lang="ts">
import { StringPayButton } from "$lib";
import { StringPayButton, type StringPayload } from "$lib";
import { onMount } from "svelte";
import { writable } from "svelte/store";
import { ethers } from "ethers";
import type { TransactionResponse } from "$lib/services/apiClient.service";

const signerAddress = writable("");

Expand Down Expand Up @@ -41,6 +42,13 @@
publicKey: STR_API_KEY,
});

window.StringPay.onTxSuccess = (req: StringPayload, tx: TransactionResponse) => {
console.log(`[String Pay] Transaction Success for ${req.assetName}: ${tx.txUrl}`);
};

window.StringPay.onTxError = (req: StringPayload, txErr: any) => {
console.error(`[String Pay] Transaction Error for ${req.assetName}: ${txErr}`);
};

const accounts = await window.ethereum.request({
method: "eth_requestAccounts",
Expand Down