UNPKG

tanglepay-sdk

Version:

DApp SDK to interact with TanglePay wallets

155 lines (144 loc) 4.71 kB
import { toInstall } from './service'; import { IotaResponse, SendToScriptParam, WindowSharedContext } from './types'; import { EventEmitter } from 'events'; import {EventCallback, JsonRpcEngine, JsonRpcId, JsonRpcResponse, WindowPostStream} from '@tanglepaysdk/common'; // context objects const context:{ curTanglePayAddress?:string } = {}; const iotaRequests: Record<string, EventCallback> = {}; let _seq = 1; const _rpcVersion = 101; const _stream = new WindowPostStream(); const _rpcEngine = JsonRpcEngine .builder<SendToScriptParam, unknown>() .add(async (req, next)=>{ req.id = _seq++ req.version = _rpcVersion req.params!.cmd = `injectToContent##${req.params!.cmd}`; req.params!.origin = window.location.origin; req.params!.id = req.id return next!(req); }) .add(async (req) => { const { cmd, data, id } = req.params!; _stream.write(req.params!); if (cmd == 'injectToContent##iota_request') { // case request const { method } = data; return new Promise<JsonRpcResponse<unknown>>((resolve, reject)=>{ iotaRequests[`iota_request_${method}_${req.id??0}`] = (res: IotaResponse<any>, code:number) => { if (code === 200) { // cache iota address if (method === 'iota_connect') { const address = res.address || ''; context.curTanglePayAddress = address + '_' + res.nodeId; } resolve({ id, version:100, data: res }); } else { reject(res); } }; }); } else { return { id:req.id!, version:100, data: undefined }; } }) .build(); const IotaSDK = { redirectAppStoreIfNotInstalled: false, isTanglePay: false, tanglePayVersion: '', _events: new EventEmitter(), request: async ({ method, params, timeout = 30000 }:{ method: string, timeout?: number, params: unknown }) => { if (!IotaSDK.isTanglePay) { toInstall(IotaSDK.redirectAppStoreIfNotInstalled); } method = !['eth_sign', 'personal_sign'].includes(method) ? method : 'iota_sign'; // @ts-ignore const res = await _rpcEngine.request({ params:{ cmd: 'iota_request', data: { method, params }, } }); return res.data; }, on: (event: string, callBack : EventCallback) => { const key = `iota_event_${event}`; IotaSDK._events.on(key, callBack); }, removeListener(event: string, callBack: EventCallback) { const key = `iota_event_${event}`; IotaSDK._events.removeListener(event, callBack); }, removeAllListener(event: string) { const key = `iota_event_${event}`; IotaSDK._events.removeAllListeners(event); }, }; // get message from content-script _stream.on('data', (data_?:any)=>{ const cmd = (data_?.cmd || '').replace('contentToInject##', ''); const data = data_?.data; const code = data_?.code; const reqId = data_?.id; switch (cmd) { case 'getTanglePayInfo': IotaSDK.tanglePayVersion = data?.version; window.dispatchEvent(new CustomEvent('iota-ready')); break; case 'iota_request': { const callBack = iotaRequests[`iota_request_${data.method}_${reqId??0}`]; if (callBack) callBack(data.response, code); } break; case 'iota_event': { const event = data.method; const key = `iota_event_${data.method}`; const res:IotaResponse<any> = data.response; if (event === 'accountsChanged') { const address = res.address + '_' + res.nodeId; if (context.curTanglePayAddress !== address) { IotaSDK._events.emit(key, res); } context.curTanglePayAddress = address || ''; } else { IotaSDK._events.emit(key, res); } } break; default: break; } }); let loadNum = 0; const onLoad = () => { const sharedContext = window as unknown as WindowSharedContext; const env = sharedContext.TanglePayEnv; if (!env) { loadNum++; if (loadNum <= 10) { setTimeout(onLoad, 300); return; } } switch (env) { case 'app': case 'chrome': { IotaSDK.isTanglePay = true; _stream.isMobile = env == 'app'; // @ts-ignore _rpcEngine.request({ params:{ cmd: 'getTanglePayInfo', } }); } break; default: { window.dispatchEvent(new CustomEvent('iota-ready')); toInstall(IotaSDK.redirectAppStoreIfNotInstalled); } break; } }; window.addEventListener('load', onLoad); export default IotaSDK;