fsl-authorization
Version:
## What id FSL ID
1,148 lines (1,074 loc) • 31.1 kB
text/typescript
import { BigNumber } from 'ethers';
import { omit, pick } from 'lodash';
import { SignatureLike } from '@ethersproject/bytes';
import { verifyMessage, verifyTypedData } from 'ethers/lib/utils';
import { v4 as uuidv4 } from 'uuid';
import {
Transaction,
TransactionInstruction,
VersionedTransaction,
} from '@solana/web3.js';
import {
getAppInfo,
initRequestToken,
logout,
optAutoApproveState,
} from './api';
import { IDomain, ITypes, IMessage } from './defination';
import {
bufferToTransaction,
closeModal,
DEVICE_TYPE,
getUserAgent,
initModal,
showModal,
} from './utils';
import SDKStorage from './store';
const clearLoopObserver = (
clientWindow: Window | null,
handleMessage: (e: any) => void,
) => {
const interval = setInterval(function () {
if (!clientWindow || clientWindow.closed) {
clearInterval(interval);
window.removeEventListener('message', handleMessage);
}
}, 500);
return interval;
};
const checkWindowOpenStatus = (
clientWindow: Window | null,
reject: (reason?: any) => void,
msg: any = 'The pop-up cannot be ejected',
) => {
const id = setTimeout(() => {
clearTimeout(id);
if (!clientWindow) {
reject(msg);
}
}, 2000);
};
const envPromiseCheckWrapper = <T>(
callback: (
res: (value: any | PromiseLike<any>) => void,
rej: (reason?: any) => void,
) => any,
clientWindow: Window | null,
msg?: any,
): Promise<T> => {
return new Promise((resolve, reject) => {
checkWindowOpenStatus(clientWindow, reject, msg);
callback(resolve, reject);
});
};
interface FSLLoginOptions {
responseType: string;
appKey: string;
redirectUri?: string;
scope?: string;
state?: string;
usePopup?: boolean;
useModal?: boolean;
isApp?: boolean;
domain?: string;
uid?: number;
}
class FSLAuthorization {
responseType: string;
appKey: string;
redirectUri?: string;
scope?: string;
state?: string;
usePopup?: boolean;
useModal?: boolean;
domain: string = 'https://id.fsl.com';
isApp?: boolean;
inWhiteList: boolean;
requestToken?: string;
sdkStorage?: SDKStorage;
uid?: number;
handling: boolean;
windowFeatures = `left=${window.screen.width / 2 - 200},top=${
window.screen.height / 2 - 500
},width=500,height=800,popup=1`;
private constructor(opt: FSLLoginOptions) {
const {
responseType,
appKey,
redirectUri,
scope,
state,
useModal,
usePopup,
domain,
isApp,
uid,
} = opt;
this.appKey = appKey;
this.responseType = responseType;
this.redirectUri = redirectUri;
this.scope = scope;
this.usePopup = usePopup;
this.useModal = useModal;
this.state = state;
this.isApp = isApp;
this.inWhiteList = false;
this.uid = uid;
this.handling = false;
if (domain) this.domain = domain;
window.apiOrigin = this.domain;
if (this.uid) {
this.sdkStorage = new SDKStorage(this.uid + '');
const token = this.sdkStorage.getItem('token') as string;
if (token) {
initRequestToken(token);
}
}
}
private receiveLoginMessage = (e: MessageEvent) => {
this.sdkStorage!.setItem('token', e.data.data.requestToken);
this.sdkStorage!.setItem('passkeyHash', e.data.data.passkeyHash);
this.sdkStorage!.setItem('hash', e.data.data.hash);
this.sdkStorage!.setItem('local', e.data.data.local);
this.sdkStorage!.setItem('hasDownload', e.data.data.hasDownload);
this.sdkStorage!.setItem('email', e.data.data.email);
this.sdkStorage!.setItem('ico', e.data.data.ico);
this.sdkStorage!.setItem('refreshToken', e.data.data.refreshToken);
this.sdkStorage!.setItem('pwdKey', e.data.data.pwdKey);
this.sdkStorage!.setItem('accessToken', e.data.data.accessToken);
this.sdkStorage!.setItem('credentialId', e.data.data.credentialId);
e.data.data.requestToken && initRequestToken(e.data.data.requestToken);
};
static async init(opt: FSLLoginOptions) {
const auth = new FSLAuthorization(opt);
let doneCount = 0,
MAX_DONE = 1;
let authResolve!: (a: FSLAuthorization) => void,
authReject!: (e: any) => void;
const authPromise = new Promise<FSLAuthorization>((res, rej) => {
authResolve = res;
authReject = rej;
});
if (opt.useModal) {
try {
const { state } = (await getAppInfo(opt.appKey)) as any;
if (state & 1) {
auth.inWhiteList = true;
// opener initiate wallet
if (window.opener && opt.uid) {
// set maximum number of callback
MAX_DONE = 2;
const handler = (e: MessageEvent) => {
if (e.data.type === 'fsl_login' && opt.uid === +e.data.data.id) {
auth.receiveLoginMessage(e);
window.removeEventListener('message', handler);
doneCount++;
if (doneCount === MAX_DONE) {
authResolve(auth);
}
}
};
window.addEventListener('message', handler, false);
window.opener.postMessage(
{
type: 'fsl_login',
data: 'done',
},
auth.domain,
);
}
initModal(auth.domain);
const childFrame = showModal(auth.domain, true);
const handleMessage = (e: any) => {
if (e.data.type === 'fsl_auth' && e.data.data === 'done') {
childFrame &&
childFrame.contentWindow?.postMessage(
{
type: 'fsl_users',
data: JSON.stringify(SDKStorage.getAllUsers()),
},
auth.domain,
);
window.removeEventListener('message', handleMessage);
doneCount++;
if (doneCount === MAX_DONE) {
authResolve(auth);
}
}
};
window.addEventListener('message', handleMessage, false);
} else {
authResolve(auth);
}
} catch (err: any) {
console.log(err.msg || err.message);
authReject(err);
}
} else {
authResolve(auth);
}
return authPromise;
}
async getApproveDDL() {
return optAutoApproveState(this.appKey);
}
async openAutoApprove() {
return optAutoApproveState(this.appKey, 1);
}
async closeAutoApprove() {
return optAutoApproveState(this.appKey, -1);
}
async signIn(args?: { withState: boolean }) {
const callUrl = new URL(`${this.domain}/login/fslUsers`);
const commonArgs: Record<string, string | undefined> = {
response_type: this.responseType,
appkey: this.appKey,
scope: this.scope,
state: this.state,
is_app: this.isApp ? '1' : undefined,
withState: args?.withState ? '1' : undefined,
};
for (let key in commonArgs) {
if (commonArgs[key]) {
callUrl.searchParams.append(key, commonArgs[key]!);
}
}
if (this.inWhiteList && this.useModal) {
callUrl.searchParams.append('use_modal', '1');
getUserAgent() !== DEVICE_TYPE.PC &&
callUrl.searchParams.append('isMobile', '1');
showModal(callUrl.toString());
return new Promise((resolve) => {
window.handleMessage = (e: any) => {
if (e.data.type === 'fsl_auth') {
resolve(pick(e.data.data, this.responseType, 'token'));
this.uid = +e.data.data.id;
this.sdkStorage = new SDKStorage(e.data.data.id + '');
this.receiveLoginMessage(e);
window.removeEventListener('message', window.handleMessage!);
closeModal();
window.handleMessage = null;
}
};
window.addEventListener('message', window.handleMessage, false);
});
}
if (!this.usePopup) {
callUrl.searchParams.append('redirect_uri', this.redirectUri!);
location.href = callUrl.toString();
return Promise.resolve(null);
} else {
callUrl.searchParams.append('use_popup', '1');
if (this.isApp) {
callUrl.searchParams.append('redirect_uri', this.redirectUri!);
}
const clientWindow = window.open(
callUrl.toString(),
this.isApp ? '_blank' : `signWindow`,
this.windowFeatures,
);
if (this.isApp) {
return Promise.resolve(null);
}
return envPromiseCheckWrapper((resolve) => {
const handleMessage = (e: any) => {
if (e.data.type === 'fsl_auth') {
resolve(e.data.data);
window.removeEventListener('message', handleMessage);
}
};
window.addEventListener('message', handleMessage, false);
clearLoopObserver(clientWindow, handleMessage);
}, clientWindow);
}
}
async signOut() {
this.sdkStorage?.removeItem('token');
return logout();
}
async signInV2() {
return this.signIn({ withState: true });
}
async checkAndAutoHandle<T>(
uid: number | undefined,
callUrl: URL,
params: Record<string, any>,
format?: (data: any) => T,
): Promise<T | any> {
if (this.handling) {
return Promise.reject({
message:
'There is currently one transaction that has not been processed',
});
}
this.handling = true;
let time = 0;
let childFrame: HTMLIFrameElement;
if (
uid &&
(!this.sdkStorage || +(this.sdkStorage.getItem('id') as string) !== uid)
) {
this.sdkStorage = new SDKStorage(uid + '');
const token = this.sdkStorage.getItem('token') as string;
if (token) initRequestToken(token);
}
try {
time = (await this.getApproveDDL()) as unknown as number;
} catch (err) {
this.handling = false;
return err;
}
const terminalType = getUserAgent();
if (time) {
const url = new URL(`${this.domain}/authorization/silent`);
url.search = callUrl.search;
// token && url.searchParams.append('token', token);
childFrame = showModal(url.toString(), true);
} else {
terminalType !== DEVICE_TYPE.PC &&
callUrl.searchParams.append('isMobile', '1');
// token && callUrl.searchParams.append('token', token);
childFrame = showModal(callUrl.toString());
}
return new Promise((resolve, reject) => {
window.handleMessage = (e: any) => {
if (e.data.type === 'fsl_auth') {
if (typeof e.data.data === 'string') {
if (e.data.data === 'done') {
childFrame &&
childFrame.contentWindow?.postMessage(
{
type: 'fsl_params',
data: JSON.stringify(params),
},
this.domain,
);
return;
} else {
resolve(e.data.data);
}
} else if (
typeof e.data.data === 'object' &&
('msg' in e.data.data || 'message' in e.data.data)
) {
reject(e.data.data);
} else {
const data = format ? format(e.data.data) : e.data.data;
resolve(data);
}
window.removeEventListener('message', window.handleMessage!);
closeModal();
window.handleMessage = null;
this.handling = false;
}
};
window.addEventListener('message', window.handleMessage, false);
});
}
static evmVerifyMessage(msg: string, signature: SignatureLike) {
return verifyMessage(msg, signature);
}
static evmVerifyTypedData(
domain: IDomain,
types: ITypes,
message: IMessage,
signature: SignatureLike,
) {
return verifyTypedData(domain, types, message, signature);
}
async callEvmSign(args: {
msg: any;
rpc?: string;
chainId: number;
chain?: string;
domain?: string;
uid?: number;
signDigest?: boolean;
}) {
const { msg, chainId, chain, rpc, signDigest, uid = this.uid } = args;
const callUrl = new URL(`${args.domain || this.domain}/authorization/sign`);
let type: string;
switch (true) {
case msg instanceof Uint8Array:
type = 'unit8Array';
break;
case msg instanceof Uint16Array:
type = 'unit16Array';
break;
case msg instanceof Uint32Array:
type = 'unit32Array';
break;
default:
type = '';
}
const uuid = uuidv4();
callUrl.searchParams.append(
'arguments',
JSON.stringify({
id: uuid,
appKey: this.appKey,
chainId,
chain,
}),
);
if (uid) {
callUrl.searchParams.append('uid', uid + '');
}
if (this.useModal && this.inWhiteList) {
return this.checkAndAutoHandle(uid, callUrl, {
id: uuid,
msg,
type,
rpc,
signDigest: signDigest ? 1 : undefined,
name: 'callEvmSign',
});
}
const url = callUrl.toString();
const clientWindow = window.open(url, `evmSignWindow`, this.windowFeatures);
return envPromiseCheckWrapper((resolve, reject) => {
const handleMessage = (e: any) => {
if (e.data.type === 'fsl_auth') {
if (typeof e.data.data === 'string') {
if (e.data.data === 'done') {
clientWindow &&
clientWindow.postMessage(
{
type: 'fsl_params',
data: JSON.stringify({
id: uuid,
msg,
type,
rpc,
signDigest: signDigest ? 1 : undefined,
}),
},
'*',
);
return;
} else {
resolve(e.data.data);
}
} else {
reject(e.data.data);
}
window.removeEventListener('message', handleMessage);
}
};
window.addEventListener('message', handleMessage, false);
clearLoopObserver(clientWindow, handleMessage);
}, clientWindow);
}
async callEvmSignDigest(args: {
msg: any;
rpc?: string;
chainId: number;
chain?: string;
domain?: string;
uid?: number;
}) {
return this.callEvmSign({ ...args, signDigest: true });
}
async signTypedData(args: {
domain: IDomain;
types: ITypes;
message: IMessage;
chainId: number;
mockDomain?: string;
chain?: string;
uid?: number;
}) {
const {
domain,
types,
message,
mockDomain,
chain,
chainId,
uid = this.uid,
} = args;
const uuid = uuidv4();
const callUrl = new URL(
`${mockDomain || this.domain}/authorization/sign-v4`,
);
callUrl.searchParams.append(
'arguments',
JSON.stringify({
id: uuid,
appKey: this.appKey,
}),
);
if (uid) {
callUrl.searchParams.append('uid', uid + '');
}
if (this.useModal && this.inWhiteList) {
return this.checkAndAutoHandle(uid, callUrl, {
message,
chain,
chainId,
types,
domain,
id: uuid,
name: 'signTypedData',
});
}
const url = callUrl.toString();
const clientWindow = window.open(
url,
`typedSignWindow`,
this.windowFeatures,
);
return envPromiseCheckWrapper((resolve, reject) => {
const handleMessage = (e: any) => {
if (e.data.type === 'fsl_auth') {
if (typeof e.data.data === 'string') {
if (e.data.data === 'done') {
clientWindow &&
clientWindow.postMessage(
{
type: 'fsl_params',
data: JSON.stringify({
message,
chain,
chainId,
types,
domain,
id: uuid,
}),
},
'*',
);
} else {
resolve(e.data.data);
window.removeEventListener('message', handleMessage);
}
} else {
reject(e.data.data);
window.removeEventListener('message', handleMessage);
}
}
};
window.addEventListener('message', handleMessage, false);
clearLoopObserver(clientWindow, handleMessage);
}, clientWindow);
}
async callEvmContractByCallData(args: {
contractAddress: string;
callData: string;
chainId: number;
gasLimit: string;
value?: string;
chain?: string;
rpc?: string;
domain?: string;
nonce?: number;
onlySign?: boolean;
maxPriorityFeePerGasValue?: BigNumber;
maxFeePerGasValue?: BigNumber;
uid?: number;
confirmed?: boolean;
}) {
const uuid = uuidv4();
const {
contractAddress,
callData,
chainId,
gasLimit,
value,
chain,
rpc,
domain,
nonce,
onlySign,
maxPriorityFeePerGasValue,
maxFeePerGasValue,
uid = this.uid,
confirmed = false,
} = args;
const callUrl = new URL(`${domain || this.domain}/authorization/call-data`);
callUrl.searchParams.append(
'arguments',
JSON.stringify({
id: uuid,
appKey: this.appKey,
chainId,
chain,
onlySign: onlySign ? 'onlySign' : undefined,
}),
);
if (uid) {
callUrl.searchParams.append('uid', uid + '');
}
if (this.useModal && this.inWhiteList) {
return this.checkAndAutoHandle(uid, callUrl, {
contractAddress,
callData,
gasLimit,
value,
rpc,
chainId,
chain,
nonce,
onlySign: onlySign ? 'onlySign' : undefined,
maxFeePerGasValue,
maxPriorityFeePerGasValue,
id: uuid,
confirmed,
name: 'callEvmContractByCallData',
});
}
const url = callUrl.toString();
const clientWindow = window.open(
url,
`callDataWindow`,
this.windowFeatures,
);
return envPromiseCheckWrapper((resolve, reject) => {
const handleMessage = (e: any) => {
if (e.data.type === 'fsl_auth') {
if (typeof e.data.data === 'string') {
if (e.data.data === 'done') {
clientWindow &&
clientWindow.postMessage(
{
type: 'fsl_params',
data: JSON.stringify({
contractAddress,
callData,
chainId,
gasLimit,
value,
chain,
rpc,
nonce,
maxFeePerGasValue,
maxPriorityFeePerGasValue,
id: uuid,
confirmed,
}),
},
'*',
);
} else {
resolve(e.data.data);
window.removeEventListener('message', handleMessage);
}
} else if (
typeof e.data.data === 'object' &&
'transactionHash' in e.data.data
) {
resolve(e.data.data);
window.removeEventListener('message', handleMessage);
} else {
reject(e.data.data);
window.removeEventListener('message', handleMessage);
}
}
};
window.addEventListener('message', handleMessage, false);
clearLoopObserver(clientWindow, handleMessage);
}, clientWindow);
}
async signCallDataTransaction(args: {
contractAddress: string;
callData: string;
chainId: number;
gasLimit: string;
value?: string;
chain?: string;
rpc?: string;
domain?: string;
nonce?: number;
maxPriorityFeePerGasValue?: BigNumber;
maxFeePerGasValue?: BigNumber;
uid?: number;
}) {
return this.callEvmContractByCallData({ ...args, onlySign: true });
}
async signSolMessage(args: { msg: string; domain?: string; uid?: number }) {
const { msg, domain, uid = this.uid } = args;
const uuid = uuidv4();
const callUrl = new URL(`${domain || this.domain}/authorization/sol-sign`);
callUrl.searchParams.append(
'arguments',
JSON.stringify({
id: uuid,
appKey: this.appKey,
}),
);
if (uid) {
callUrl.searchParams.append('uid', uid + '');
}
if (this.useModal && this.inWhiteList) {
return this.checkAndAutoHandle(uid, callUrl, {
msg,
id: uuid,
name: 'signSolMessage',
});
}
const url = callUrl.toString();
const clientWindow = window.open(
url,
`signSolMsgWindow`,
this.windowFeatures,
);
return envPromiseCheckWrapper((resolve, reject) => {
const handleMessage = (e: any) => {
if (e.data.type === 'fsl_auth') {
if (typeof e.data.data === 'string') {
if (e.data.data === 'done') {
clientWindow &&
clientWindow.postMessage(
{
type: 'fsl_params',
data: JSON.stringify({
msg,
id: uuid,
}),
},
'*',
);
}
} else if (
e.data.data &&
typeof e.data.data === 'object' &&
'length' in e.data.data
) {
resolve(e.data.data);
} else {
reject(e.data.data);
}
window.removeEventListener('message', handleMessage);
}
};
window.addEventListener('message', handleMessage, false);
clearLoopObserver(clientWindow, handleMessage);
}, clientWindow);
}
async callSolInstructions(args: {
instructions: TransactionInstruction[];
rpc?: string;
unitLimit?: number;
unitPrice?: number;
domain?: string;
onlySign?: boolean;
uid?: number;
}) {
const {
domain,
instructions,
rpc,
unitPrice,
unitLimit,
onlySign,
uid = this.uid,
} = args;
const uuid = uuidv4();
const callUrl = new URL(`${domain || this.domain}/authorization/sol-trade`);
callUrl.searchParams.append(
'arguments',
JSON.stringify({
appKey: this.appKey,
onlySign: onlySign ? 'onlySign' : void 0,
id: uuid,
}),
);
if (uid) {
callUrl.searchParams.append('uid', uid + '');
}
if (this.useModal && this.inWhiteList) {
return this.checkAndAutoHandle(uid, callUrl, {
instructions,
unitLimit,
unitPrice,
id: uuid,
rpc,
onlySign: onlySign ? 'onlySign' : void 0,
name: 'callSolInstructions',
});
}
const url = callUrl.toString();
const clientWindow = window.open(
url,
`signSolCallWindow`,
this.windowFeatures,
);
return envPromiseCheckWrapper((resolve, reject) => {
const handleMessage = async (e: any) => {
if (e.data.type === 'fsl_auth') {
if (typeof e.data.data === 'string') {
if (e.data.data === 'done') {
clientWindow &&
clientWindow.postMessage(
{
type: 'fsl_params',
data: JSON.stringify({
instructions,
unitLimit,
unitPrice,
rpc,
id: uuid,
}),
},
'*',
);
} else {
resolve(e.data.data);
window.removeEventListener('message', handleMessage);
}
} else {
reject(e.data.data);
window.removeEventListener('message', handleMessage);
}
}
};
window.addEventListener('message', handleMessage, false);
clearLoopObserver(clientWindow, handleMessage);
}, clientWindow);
}
async signSolInstructions(args: {
instructions: any[];
rpc?: string;
unitLimit?: number;
unitPrice?: number;
domain?: string;
uid?: number;
}) {
return this.callSolInstructions({ ...args, onlySign: true });
}
async signSolTransaction(args: {
transactions: Array<Transaction> | Array<VersionedTransaction>;
uid?: number;
}): Promise<Array<Transaction> | Array<VersionedTransaction>> {
const { transactions, uid = this.uid } = args;
let bufferStrs: string[] = [];
const versions: Array<'legacy' | 0> = [];
try {
bufferStrs = transactions.map((item: any) => {
if (item.version === 0) {
versions.push(0);
return Buffer.from(
item.serialize({ verifySignatures: false }),
).toString('base64');
} else {
versions.push('legacy');
return item.serialize({ verifySignatures: false }).toString('base64');
}
});
} catch (err: any) {
return Promise.reject(err.message);
}
const uuid = uuidv4();
const callUrl = new URL(`${this.domain}/authorization/sol-transaction`);
callUrl.searchParams.append(
'arguments',
JSON.stringify({
id: uuid,
appKey: this.appKey,
}),
);
if (uid) {
callUrl.searchParams.append('uid', uid + '');
}
if (this.useModal && this.inWhiteList) {
return this.checkAndAutoHandle<
Array<Transaction> | Array<VersionedTransaction>
>(
uid,
callUrl,
{
transactions: bufferStrs,
versions,
id: uuid,
name: 'signSolTransaction',
},
(data: any) => {
let transactions = data;
if (Array.isArray(data)) {
transactions = bufferToTransaction(data, versions);
}
return transactions;
},
);
}
const url = callUrl.toString();
const clientWindow = window.open(
url,
`signSolTrsWindow`,
this.windowFeatures,
);
return envPromiseCheckWrapper((resolve, reject) => {
const handleMessage = async (e: any) => {
if (e.data.type === 'fsl_auth') {
if (typeof e.data.data === 'string') {
if (e.data.data === 'done') {
clientWindow &&
clientWindow.postMessage(
{
type: 'fsl_params',
data: JSON.stringify({
transactions: bufferStrs,
versions,
id: uuid,
}),
},
'*',
);
}
return;
} else if (Array.isArray(e.data.data)) {
const transactions = bufferToTransaction(e.data.data, versions);
resolve(transactions);
} else {
reject(e.data.data);
}
window.removeEventListener('message', handleMessage);
}
};
window.addEventListener('message', handleMessage, false);
clearLoopObserver(clientWindow, handleMessage);
}, clientWindow);
}
async callEvmContract(args: {
contractAddress: string;
methodName: string;
abi?: any;
chainId: number;
chain?: string;
value?: string;
gasLimit: string;
params?: any[];
to?: string;
rpc?: string;
domain?: string;
nonce?: number;
maxPriorityFeePerGasValue?: BigNumber;
maxFeePerGasValue?: BigNumber;
onlySign?: boolean;
uid?: number;
}) {
const {
contractAddress,
methodName,
abi,
chainId,
chain,
value,
gasLimit,
params,
to,
rpc,
domain,
nonce,
maxPriorityFeePerGasValue,
maxFeePerGasValue,
onlySign,
uid = this.uid,
} = args;
const id = uuidv4();
const callUrl = new URL(`${domain || this.domain}/authorization/trade-v2`);
callUrl.searchParams.append(
'arguments',
JSON.stringify({
appKey: this.appKey,
onlySign: onlySign ? 'onlySign' : undefined,
chainId,
chain,
id,
}),
);
if (uid) {
callUrl.searchParams.append('uid', uid + '');
}
const url = callUrl.toString();
if (this.useModal && this.inWhiteList) {
return this.checkAndAutoHandle(uid, callUrl, {
contractAddress,
methodName,
abi,
value,
gasLimit,
params,
to,
nonce,
maxPriorityFeePerGasValue,
maxFeePerGasValue,
id,
rpc,
onlySign: onlySign ? 'onlySign' : undefined,
name: 'callEvmContract',
});
}
const clientWindow = window.open(
url,
`evmContractWindow`,
this.windowFeatures,
);
return envPromiseCheckWrapper((resolve, reject) => {
const handleMessage = (e: any) => {
if (e.data.type === 'fsl_auth') {
if (typeof e.data.data === 'string') {
if (e.data.data === 'done') {
clientWindow &&
clientWindow.postMessage(
{
type: 'fsl_params',
data: JSON.stringify({
contractAddress,
methodName,
abi,
value,
gasLimit,
params,
to,
nonce,
maxPriorityFeePerGasValue,
maxFeePerGasValue,
id,
rpc,
}),
},
'*',
);
} else {
resolve(e.data.data);
window.removeEventListener('message', handleMessage);
}
} else if (
e.data.data &&
typeof e.data.data === 'object' &&
'transactionHash' in e.data.data
) {
resolve(e.data.data);
window.removeEventListener('message', handleMessage);
} else {
reject(e.data.data);
window.removeEventListener('message', handleMessage);
}
}
};
window.addEventListener('message', handleMessage, false);
clearLoopObserver(clientWindow, handleMessage);
}, clientWindow);
}
async signEvmContract(args: {
contractAddress: string;
methodName: string;
abi?: any;
chainId: number;
chain?: string;
value?: string;
gasLimit: string;
params?: any[];
to?: string;
rpc?: string;
domain?: string;
nonce?: number;
maxPriorityFeePerGasValue?: BigNumber;
maxFeePerGasValue?: BigNumber;
uid?: number;
}) {
return this.callEvmContract({ ...args, onlySign: true });
}
}
export default FSLAuthorization;