@onekeyfe/cross-inpage-provider-core 0.0.7-alpha.2 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,24 @@
1
+ /// <reference types="node" />
2
+ import EventEmitterBase from '@onekeyfe/cross-inpage-provider-events';
3
+ import type { EventEmitter as INodeEventEmitter } from 'events';
4
+ declare class EventEmitterProxy extends EventEmitterBase implements INodeEventEmitter {
5
+ emit(eventName: string | symbol, ...args: any[]): boolean;
6
+ addListener(eventName: string | symbol, listener: (...args: any[]) => void): this;
7
+ on(eventName: string | symbol, listener: (...args: any[]) => void): this;
8
+ once(eventName: string | symbol, listener: (...args: any[]) => void): this;
9
+ removeListener(eventName: string | symbol, listener: (...args: any[]) => void): this;
10
+ off(eventName: string | symbol, listener: (...args: any[]) => void): this;
11
+ removeAllListeners(event?: string | symbol): this;
12
+ setMaxListeners(n: number): this;
13
+ getMaxListeners(): number;
14
+ listeners(eventName: string | symbol): Function[];
15
+ rawListeners(eventName: string | symbol): Function[];
16
+ listenerCount(eventName: string | symbol): number;
17
+ prependListener(eventName: string | symbol, listener: (...args: any[]) => void): this;
18
+ prependOnceListener(eventName: string | symbol, listener: (...args: any[]) => void): this;
19
+ eventNames(): (string | symbol)[];
20
+ }
21
+ declare class CrossEventEmitter extends EventEmitterProxy {
22
+ emit(type: string, ...args: any[]): boolean;
23
+ }
24
+ export { CrossEventEmitter };
@@ -0,0 +1,125 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access,@typescript-eslint/ban-ts-comment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2
+ */
3
+ // @ts-ignore
4
+ import EventEmitterBase from '@onekeyfe/cross-inpage-provider-events';
5
+ function safeApply(handler, context, args) {
6
+ try {
7
+ Reflect.apply(handler, context, args);
8
+ }
9
+ catch (err) {
10
+ // Throw error after timeout so as not to interrupt the stack
11
+ setTimeout(() => {
12
+ throw err;
13
+ });
14
+ }
15
+ }
16
+ function arrayClone(arr) {
17
+ const n = arr.length;
18
+ const copy = new Array(n);
19
+ for (let i = 0; i < n; i += 1) {
20
+ copy[i] = arr[i];
21
+ }
22
+ return copy;
23
+ }
24
+ class EventEmitterProxy extends EventEmitterBase {
25
+ emit(eventName, ...args) {
26
+ return super.emit(eventName, ...args);
27
+ }
28
+ addListener(eventName, listener) {
29
+ super.addListener(eventName, listener);
30
+ return this;
31
+ }
32
+ on(eventName, listener) {
33
+ super.on(eventName, listener);
34
+ return this;
35
+ }
36
+ once(eventName, listener) {
37
+ super.once(eventName, listener);
38
+ return this;
39
+ }
40
+ removeListener(eventName, listener) {
41
+ super.removeListener(eventName, listener);
42
+ return this;
43
+ }
44
+ off(eventName, listener) {
45
+ super.off(eventName, listener);
46
+ return this;
47
+ }
48
+ removeAllListeners(event) {
49
+ super.removeAllListeners(event);
50
+ return this;
51
+ }
52
+ setMaxListeners(n) {
53
+ super.setMaxListeners(n);
54
+ return this;
55
+ }
56
+ getMaxListeners() {
57
+ return super.getMaxListeners();
58
+ }
59
+ // eslint-disable-next-line @typescript-eslint/ban-types
60
+ listeners(eventName) {
61
+ return super.listeners(eventName);
62
+ }
63
+ // eslint-disable-next-line @typescript-eslint/ban-types
64
+ rawListeners(eventName) {
65
+ return super.rawListeners(eventName);
66
+ }
67
+ listenerCount(eventName) {
68
+ return super.listenerCount(eventName);
69
+ }
70
+ prependListener(eventName, listener) {
71
+ super.prependListener(eventName, listener);
72
+ return this;
73
+ }
74
+ prependOnceListener(eventName, listener) {
75
+ super.prependOnceListener(eventName, listener);
76
+ return this;
77
+ }
78
+ eventNames() {
79
+ return super.eventNames();
80
+ }
81
+ }
82
+ class CrossEventEmitter extends EventEmitterProxy {
83
+ emit(type, ...args) {
84
+ let doError = type === 'error';
85
+ const events = this._events;
86
+ if (events !== undefined) {
87
+ doError = doError && events.error === undefined;
88
+ }
89
+ else if (!doError) {
90
+ return false;
91
+ }
92
+ // If there is no 'error' event listener then throw.
93
+ if (doError) {
94
+ let er;
95
+ if (args.length > 0) {
96
+ [er] = args;
97
+ }
98
+ if (er instanceof Error) {
99
+ // Note: The comments on the `throw` lines are intentional, they show
100
+ // up in Node's output if this results in an unhandled exception.
101
+ throw er; // Unhandled 'error' event
102
+ }
103
+ // At least give some kind of context to the user
104
+ const err = new Error(`Unhandled error.${er ? ` (${er.message})` : ''}`);
105
+ err.context = er;
106
+ throw err; // Unhandled 'error' event
107
+ }
108
+ const handler = events[type];
109
+ if (handler === undefined) {
110
+ return false;
111
+ }
112
+ if (typeof handler === 'function') {
113
+ safeApply(handler, this, args);
114
+ }
115
+ else {
116
+ const len = handler.length;
117
+ const listeners = arrayClone(handler);
118
+ for (let i = 0; i < len; i += 1) {
119
+ safeApply(listeners[i], this, args);
120
+ }
121
+ }
122
+ return true;
123
+ }
124
+ }
125
+ export { CrossEventEmitter };
@@ -1,7 +1,7 @@
1
- import EventEmitter from 'eventemitter3';
1
+ import { CrossEventEmitter } from './CrossEventEmitter';
2
2
  import { IInjectedProviderNamesStrings, IJsBridgeConfig, IJsBridgeMessagePayload, IJsonRpcResponse, IDebugLogger } from '@onekeyfe/cross-inpage-provider-types';
3
3
  declare function isLegacyExtMessage(payload: unknown): boolean;
4
- declare abstract class JsBridgeBase extends EventEmitter {
4
+ declare abstract class JsBridgeBase extends CrossEventEmitter {
5
5
  constructor(config?: IJsBridgeConfig);
6
6
  protected isExtUi: boolean;
7
7
  protected isInjected: boolean;
@@ -18,7 +18,7 @@ declare abstract class JsBridgeBase extends EventEmitter {
18
18
  remoteId?: string | number | null;
19
19
  };
20
20
  private config;
21
- private readonly callbacksExpireTimeout;
21
+ protected callbacksExpireTimeout: number;
22
22
  debugLogger: IDebugLogger;
23
23
  private callbacks;
24
24
  private callbackId;
@@ -7,13 +7,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import EventEmitter from 'eventemitter3';
10
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
11
+ import { CrossEventEmitter } from './CrossEventEmitter';
11
12
  import isPlainObject from 'lodash/isPlainObject';
12
13
  import isString from 'lodash/isString';
13
14
  import { appDebugLogger, consoleErrorInDev } from './loggers';
14
15
  import { IJsBridgeMessageTypes, } from '@onekeyfe/cross-inpage-provider-types';
15
16
  import { web3Errors } from '@onekeyfe/cross-inpage-provider-errors';
16
17
  import versionInfo from './versionInfo';
18
+ function toPlainError(errorInfo) {
19
+ return {
20
+ name: errorInfo.name,
21
+ message: errorInfo.message,
22
+ stack: errorInfo.stack,
23
+ code: errorInfo.code,
24
+ data: errorInfo.data,
25
+ key: errorInfo.key,
26
+ info: errorInfo.info,
27
+ className: errorInfo.className,
28
+ };
29
+ }
17
30
  function isLegacyExtMessage(payload) {
18
31
  const payloadObj = payload;
19
32
  return (Boolean(payloadObj.name) &&
@@ -23,7 +36,8 @@ const BRIDGE_EVENTS = {
23
36
  message: 'message',
24
37
  error: 'error',
25
38
  };
26
- class JsBridgeBase extends EventEmitter {
39
+ let requestPayloadCache = {};
40
+ class JsBridgeBase extends CrossEventEmitter {
27
41
  constructor(config = {}) {
28
42
  var _a, _b;
29
43
  super();
@@ -69,11 +83,14 @@ class JsBridgeBase extends EventEmitter {
69
83
  origin: '',
70
84
  remoteId: '',
71
85
  };
86
+ // TODO increase timeout as hardware sign transaction may take a long time
87
+ // can set timeout for each callback
88
+ this.callbacksExpireTimeout = 10 * 60 * 1000;
72
89
  this.debugLogger = appDebugLogger;
73
90
  this.callbacks = [];
74
91
  this.callbackId = 1;
75
92
  this.config = config;
76
- this.callbacksExpireTimeout = (_a = config.timeout) !== null && _a !== void 0 ? _a : 60 * 1000;
93
+ this.callbacksExpireTimeout = (_a = config.timeout) !== null && _a !== void 0 ? _a : this.callbacksExpireTimeout;
77
94
  this.debugLogger = config.debugLogger || appDebugLogger;
78
95
  this.sendAsString = (_b = config.sendAsString) !== null && _b !== void 0 ? _b : this.sendAsString;
79
96
  if (this.config.receiveHandler) {
@@ -112,12 +129,7 @@ class JsBridgeBase extends EventEmitter {
112
129
  // convert to plain error object which can be stringify
113
130
  if (payload.error) {
114
131
  const errorInfo = payload.error;
115
- payload.error = {
116
- code: errorInfo.code,
117
- message: errorInfo.message,
118
- data: errorInfo.data,
119
- stack: errorInfo.stack,
120
- };
132
+ payload.error = toPlainError(errorInfo);
121
133
  }
122
134
  // delete resolve, reject function which can not be send as string
123
135
  payload === null || payload === void 0 ? true : delete payload.resolve;
@@ -126,7 +138,7 @@ class JsBridgeBase extends EventEmitter {
126
138
  }
127
139
  send({ type, data, error, id, remoteId, sync = false, scope }) {
128
140
  const executor = (resolve, reject) => {
129
- var _a;
141
+ var _a, _b, _c;
130
142
  // TODO check resolve when calling without await
131
143
  // eslint-disable-next-line @typescript-eslint/naming-convention
132
144
  let _id = id;
@@ -148,7 +160,18 @@ class JsBridgeBase extends EventEmitter {
148
160
  if (this.sendAsString) {
149
161
  payloadToSend = JSON.stringify(payload);
150
162
  }
151
- this.debugLogger.jsBridge('send', payload, '\r\n ------> ', payload.data);
163
+ // @ts-ignore
164
+ if ((_b = this.debugLogger.jsBridge) === null || _b === void 0 ? void 0 : _b.enabled) {
165
+ if (payload && payload.id && payload.type === IJsBridgeMessageTypes.REQUEST) {
166
+ requestPayloadCache[payload.id] = payload;
167
+ if (payload.id % 100 === 0) {
168
+ requestPayloadCache = {};
169
+ }
170
+ }
171
+ }
172
+ this.debugLogger.jsBridge('send', payload, '\r\n ------> ', payload.data, '\r\n ------> ',
173
+ // @ts-ignore
174
+ (_c = payload.data) === null || _c === void 0 ? void 0 : _c.result);
152
175
  this.sendPayload(payloadToSend);
153
176
  }
154
177
  catch (error) {
@@ -222,7 +245,7 @@ class JsBridgeBase extends EventEmitter {
222
245
  delete this.callbacks[id];
223
246
  }
224
247
  receive(payloadReceived = '', sender) {
225
- var _a, _b;
248
+ var _a, _b, _c, _d, _e;
226
249
  let payload = {
227
250
  data: null,
228
251
  };
@@ -253,7 +276,8 @@ class JsBridgeBase extends EventEmitter {
253
276
  if (!payload.internal && !payload.scope) {
254
277
  throw new Error('JsBridge ERROR: receive message [payload.scope] is required for non-internal method call.');
255
278
  }
256
- this.debugLogger.jsBridge('receive', payload, { sender }, '\r\n -----> ', (_b = payload.data) === null || _b === void 0 ? void 0 : _b.result, '\r\n -----> ', payload.data);
279
+ const relatedSendPayload = (_c = requestPayloadCache[(_b = payload === null || payload === void 0 ? void 0 : payload.id) !== null && _b !== void 0 ? _b : '']) !== null && _c !== void 0 ? _c : null;
280
+ this.debugLogger.jsBridge('receive', payload, { sender }, '\r\n -----> ', (_e = (_d = payload.data) === null || _d === void 0 ? void 0 : _d.result) !== null && _e !== void 0 ? _e : payload.data, '\r\n <----- ', relatedSendPayload === null || relatedSendPayload === void 0 ? void 0 : relatedSendPayload.data);
257
281
  const { type, id, data, error, origin, remoteId } = payload;
258
282
  this.remoteInfo = {
259
283
  origin,
@@ -4,6 +4,7 @@ declare class JsBridgeSimple extends JsBridgeBase {
4
4
  sendAsString: boolean;
5
5
  isInjected: boolean;
6
6
  private remote;
7
+ callbacksExpireTimeout: number;
7
8
  sendPayload(payload: IJsBridgeMessagePayload | string): void;
8
9
  setRemote(remote: JsBridgeBase): void;
9
10
  }
@@ -5,6 +5,7 @@ class JsBridgeSimple extends JsBridgeBase {
5
5
  this.sendAsString = true;
6
6
  this.isInjected = true;
7
7
  this.remote = null;
8
+ this.callbacksExpireTimeout = 0;
8
9
  }
9
10
  sendPayload(payload) {
10
11
  if (!this.remote) {
@@ -1,4 +1,4 @@
1
- import EventEmitter from 'eventemitter3';
1
+ import { CrossEventEmitter } from './CrossEventEmitter';
2
2
  import { JsBridgeBase } from './JsBridgeBase';
3
3
  import { IInjectedProviderNamesStrings, IJsonRpcResponse, ConsoleLike, IDebugLogger } from '@onekeyfe/cross-inpage-provider-types';
4
4
  export declare type IBridgeRequestCallback = (error: Error | null, result?: IJsonRpcResponse<unknown>) => void;
@@ -6,7 +6,6 @@ export declare type IInpageProviderConfig = {
6
6
  bridge?: JsBridgeBase;
7
7
  logger?: ConsoleLike | null;
8
8
  maxEventListeners?: number;
9
- shouldSendMetadata?: boolean;
10
9
  };
11
10
  export declare type DebugLoggerConfig = {
12
11
  config: string;
@@ -20,7 +19,7 @@ export declare type ConnectWalletInfo = {
20
19
  };
21
20
  providerState: unknown;
22
21
  };
23
- declare abstract class ProviderBase extends EventEmitter {
22
+ declare abstract class ProviderBase extends CrossEventEmitter {
24
23
  constructor(config: IInpageProviderConfig);
25
24
  configDebugLogger(config: DebugLoggerConfig): void;
26
25
  getConnectWalletInfo({ timeout }?: {
@@ -34,6 +33,7 @@ declare abstract class ProviderBase extends EventEmitter {
34
33
  debugLogger: IDebugLogger;
35
34
  readonly logger: ConsoleLike;
36
35
  bridgeRequest(data: unknown, callback?: IBridgeRequestCallback): Promise<unknown>;
36
+ sendSiteMetadataDomReady(): void;
37
37
  sendSiteMetadata(): Promise<unknown>;
38
38
  }
39
39
  export { ProviderBase };
@@ -7,8 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import EventEmitter from 'eventemitter3';
11
10
  import isFunction from 'lodash/isFunction';
11
+ import { CrossEventEmitter } from './CrossEventEmitter';
12
12
  import siteMetadata from './siteMetadata';
13
13
  import { fakeLogger, fakeDebugLogger, consoleErrorInDev } from './loggers';
14
14
  import versionInfo from './versionInfo';
@@ -16,7 +16,7 @@ const METHODS = {
16
16
  wallet_getConnectWalletInfo: 'wallet_getConnectWalletInfo',
17
17
  wallet_sendSiteMetadata: 'wallet_sendSiteMetadata',
18
18
  };
19
- class ProviderBase extends EventEmitter {
19
+ class ProviderBase extends CrossEventEmitter {
20
20
  constructor(config) {
21
21
  var _a, _b, _c;
22
22
  super();
@@ -37,9 +37,9 @@ class ProviderBase extends EventEmitter {
37
37
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
38
38
  this.bridge.attachProviderInstance(this);
39
39
  }, 0);
40
- if (config.shouldSendMetadata) {
41
- void this.sendSiteMetadata();
42
- }
40
+ // call sendSiteMetadataDomReady/getConnectWalletInfo in ProviderPrivate, dont need here
41
+ // void this.sendSiteMetadataDomReady();
42
+ // void this.getConnectWalletInfo();
43
43
  }
44
44
  configDebugLogger(config) {
45
45
  try {
@@ -119,7 +119,8 @@ class ProviderBase extends EventEmitter {
119
119
  const resData = yield this.bridge.request(payload);
120
120
  const result = resData ? resData.result : undefined;
121
121
  if (callback && hasCallback) {
122
- callback(null, result);
122
+ // callback with params: { id, result, jsonrpc }
123
+ callback(null, resData);
123
124
  }
124
125
  this.debugLogger.providerBase('bridgeRequest RETURN:', { req: payload, res: resData }, '\r\n -----> ', payload.data, '\r\n -----> ', result);
125
126
  return result;
@@ -132,6 +133,18 @@ class ProviderBase extends EventEmitter {
132
133
  }
133
134
  });
134
135
  }
136
+ sendSiteMetadataDomReady() {
137
+ if (document.readyState === 'complete') {
138
+ void this.sendSiteMetadata();
139
+ }
140
+ else {
141
+ const domContentLoadedHandler = () => {
142
+ void this.sendSiteMetadata();
143
+ window.removeEventListener('DOMContentLoaded', domContentLoadedHandler);
144
+ };
145
+ window.addEventListener('DOMContentLoaded', domContentLoadedHandler);
146
+ }
147
+ }
135
148
  sendSiteMetadata() {
136
149
  return __awaiter(this, void 0, void 0, function* () {
137
150
  const metadata = yield siteMetadata.getSiteMetadata();
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CrossEventEmitter = void 0;
7
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access,@typescript-eslint/ban-ts-comment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
8
+ */
9
+ // @ts-ignore
10
+ const cross_inpage_provider_events_1 = __importDefault(require("@onekeyfe/cross-inpage-provider-events"));
11
+ function safeApply(handler, context, args) {
12
+ try {
13
+ Reflect.apply(handler, context, args);
14
+ }
15
+ catch (err) {
16
+ // Throw error after timeout so as not to interrupt the stack
17
+ setTimeout(() => {
18
+ throw err;
19
+ });
20
+ }
21
+ }
22
+ function arrayClone(arr) {
23
+ const n = arr.length;
24
+ const copy = new Array(n);
25
+ for (let i = 0; i < n; i += 1) {
26
+ copy[i] = arr[i];
27
+ }
28
+ return copy;
29
+ }
30
+ class EventEmitterProxy extends cross_inpage_provider_events_1.default {
31
+ emit(eventName, ...args) {
32
+ return super.emit(eventName, ...args);
33
+ }
34
+ addListener(eventName, listener) {
35
+ super.addListener(eventName, listener);
36
+ return this;
37
+ }
38
+ on(eventName, listener) {
39
+ super.on(eventName, listener);
40
+ return this;
41
+ }
42
+ once(eventName, listener) {
43
+ super.once(eventName, listener);
44
+ return this;
45
+ }
46
+ removeListener(eventName, listener) {
47
+ super.removeListener(eventName, listener);
48
+ return this;
49
+ }
50
+ off(eventName, listener) {
51
+ super.off(eventName, listener);
52
+ return this;
53
+ }
54
+ removeAllListeners(event) {
55
+ super.removeAllListeners(event);
56
+ return this;
57
+ }
58
+ setMaxListeners(n) {
59
+ super.setMaxListeners(n);
60
+ return this;
61
+ }
62
+ getMaxListeners() {
63
+ return super.getMaxListeners();
64
+ }
65
+ // eslint-disable-next-line @typescript-eslint/ban-types
66
+ listeners(eventName) {
67
+ return super.listeners(eventName);
68
+ }
69
+ // eslint-disable-next-line @typescript-eslint/ban-types
70
+ rawListeners(eventName) {
71
+ return super.rawListeners(eventName);
72
+ }
73
+ listenerCount(eventName) {
74
+ return super.listenerCount(eventName);
75
+ }
76
+ prependListener(eventName, listener) {
77
+ super.prependListener(eventName, listener);
78
+ return this;
79
+ }
80
+ prependOnceListener(eventName, listener) {
81
+ super.prependOnceListener(eventName, listener);
82
+ return this;
83
+ }
84
+ eventNames() {
85
+ return super.eventNames();
86
+ }
87
+ }
88
+ class CrossEventEmitter extends EventEmitterProxy {
89
+ emit(type, ...args) {
90
+ let doError = type === 'error';
91
+ const events = this._events;
92
+ if (events !== undefined) {
93
+ doError = doError && events.error === undefined;
94
+ }
95
+ else if (!doError) {
96
+ return false;
97
+ }
98
+ // If there is no 'error' event listener then throw.
99
+ if (doError) {
100
+ let er;
101
+ if (args.length > 0) {
102
+ [er] = args;
103
+ }
104
+ if (er instanceof Error) {
105
+ // Note: The comments on the `throw` lines are intentional, they show
106
+ // up in Node's output if this results in an unhandled exception.
107
+ throw er; // Unhandled 'error' event
108
+ }
109
+ // At least give some kind of context to the user
110
+ const err = new Error(`Unhandled error.${er ? ` (${er.message})` : ''}`);
111
+ err.context = er;
112
+ throw err; // Unhandled 'error' event
113
+ }
114
+ const handler = events[type];
115
+ if (handler === undefined) {
116
+ return false;
117
+ }
118
+ if (typeof handler === 'function') {
119
+ safeApply(handler, this, args);
120
+ }
121
+ else {
122
+ const len = handler.length;
123
+ const listeners = arrayClone(handler);
124
+ for (let i = 0; i < len; i += 1) {
125
+ safeApply(listeners[i], this, args);
126
+ }
127
+ }
128
+ return true;
129
+ }
130
+ }
131
+ exports.CrossEventEmitter = CrossEventEmitter;
@@ -13,13 +13,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.isLegacyExtMessage = exports.JsBridgeBase = void 0;
16
- const eventemitter3_1 = __importDefault(require("eventemitter3"));
16
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
17
+ const CrossEventEmitter_1 = require("./CrossEventEmitter");
17
18
  const isPlainObject_1 = __importDefault(require("lodash/isPlainObject"));
18
19
  const isString_1 = __importDefault(require("lodash/isString"));
19
20
  const loggers_1 = require("./loggers");
20
21
  const cross_inpage_provider_types_1 = require("@onekeyfe/cross-inpage-provider-types");
21
22
  const cross_inpage_provider_errors_1 = require("@onekeyfe/cross-inpage-provider-errors");
22
23
  const versionInfo_1 = __importDefault(require("./versionInfo"));
24
+ function toPlainError(errorInfo) {
25
+ return {
26
+ name: errorInfo.name,
27
+ message: errorInfo.message,
28
+ stack: errorInfo.stack,
29
+ code: errorInfo.code,
30
+ data: errorInfo.data,
31
+ key: errorInfo.key,
32
+ info: errorInfo.info,
33
+ className: errorInfo.className,
34
+ };
35
+ }
23
36
  function isLegacyExtMessage(payload) {
24
37
  const payloadObj = payload;
25
38
  return (Boolean(payloadObj.name) &&
@@ -30,7 +43,8 @@ const BRIDGE_EVENTS = {
30
43
  message: 'message',
31
44
  error: 'error',
32
45
  };
33
- class JsBridgeBase extends eventemitter3_1.default {
46
+ let requestPayloadCache = {};
47
+ class JsBridgeBase extends CrossEventEmitter_1.CrossEventEmitter {
34
48
  constructor(config = {}) {
35
49
  var _a, _b;
36
50
  super();
@@ -76,11 +90,14 @@ class JsBridgeBase extends eventemitter3_1.default {
76
90
  origin: '',
77
91
  remoteId: '',
78
92
  };
93
+ // TODO increase timeout as hardware sign transaction may take a long time
94
+ // can set timeout for each callback
95
+ this.callbacksExpireTimeout = 10 * 60 * 1000;
79
96
  this.debugLogger = loggers_1.appDebugLogger;
80
97
  this.callbacks = [];
81
98
  this.callbackId = 1;
82
99
  this.config = config;
83
- this.callbacksExpireTimeout = (_a = config.timeout) !== null && _a !== void 0 ? _a : 60 * 1000;
100
+ this.callbacksExpireTimeout = (_a = config.timeout) !== null && _a !== void 0 ? _a : this.callbacksExpireTimeout;
84
101
  this.debugLogger = config.debugLogger || loggers_1.appDebugLogger;
85
102
  this.sendAsString = (_b = config.sendAsString) !== null && _b !== void 0 ? _b : this.sendAsString;
86
103
  if (this.config.receiveHandler) {
@@ -119,12 +136,7 @@ class JsBridgeBase extends eventemitter3_1.default {
119
136
  // convert to plain error object which can be stringify
120
137
  if (payload.error) {
121
138
  const errorInfo = payload.error;
122
- payload.error = {
123
- code: errorInfo.code,
124
- message: errorInfo.message,
125
- data: errorInfo.data,
126
- stack: errorInfo.stack,
127
- };
139
+ payload.error = toPlainError(errorInfo);
128
140
  }
129
141
  // delete resolve, reject function which can not be send as string
130
142
  payload === null || payload === void 0 ? true : delete payload.resolve;
@@ -133,7 +145,7 @@ class JsBridgeBase extends eventemitter3_1.default {
133
145
  }
134
146
  send({ type, data, error, id, remoteId, sync = false, scope }) {
135
147
  const executor = (resolve, reject) => {
136
- var _a;
148
+ var _a, _b, _c;
137
149
  // TODO check resolve when calling without await
138
150
  // eslint-disable-next-line @typescript-eslint/naming-convention
139
151
  let _id = id;
@@ -155,7 +167,18 @@ class JsBridgeBase extends eventemitter3_1.default {
155
167
  if (this.sendAsString) {
156
168
  payloadToSend = JSON.stringify(payload);
157
169
  }
158
- this.debugLogger.jsBridge('send', payload, '\r\n ------> ', payload.data);
170
+ // @ts-ignore
171
+ if ((_b = this.debugLogger.jsBridge) === null || _b === void 0 ? void 0 : _b.enabled) {
172
+ if (payload && payload.id && payload.type === cross_inpage_provider_types_1.IJsBridgeMessageTypes.REQUEST) {
173
+ requestPayloadCache[payload.id] = payload;
174
+ if (payload.id % 100 === 0) {
175
+ requestPayloadCache = {};
176
+ }
177
+ }
178
+ }
179
+ this.debugLogger.jsBridge('send', payload, '\r\n ------> ', payload.data, '\r\n ------> ',
180
+ // @ts-ignore
181
+ (_c = payload.data) === null || _c === void 0 ? void 0 : _c.result);
159
182
  this.sendPayload(payloadToSend);
160
183
  }
161
184
  catch (error) {
@@ -229,7 +252,7 @@ class JsBridgeBase extends eventemitter3_1.default {
229
252
  delete this.callbacks[id];
230
253
  }
231
254
  receive(payloadReceived = '', sender) {
232
- var _a, _b;
255
+ var _a, _b, _c, _d, _e;
233
256
  let payload = {
234
257
  data: null,
235
258
  };
@@ -260,7 +283,8 @@ class JsBridgeBase extends eventemitter3_1.default {
260
283
  if (!payload.internal && !payload.scope) {
261
284
  throw new Error('JsBridge ERROR: receive message [payload.scope] is required for non-internal method call.');
262
285
  }
263
- this.debugLogger.jsBridge('receive', payload, { sender }, '\r\n -----> ', (_b = payload.data) === null || _b === void 0 ? void 0 : _b.result, '\r\n -----> ', payload.data);
286
+ const relatedSendPayload = (_c = requestPayloadCache[(_b = payload === null || payload === void 0 ? void 0 : payload.id) !== null && _b !== void 0 ? _b : '']) !== null && _c !== void 0 ? _c : null;
287
+ this.debugLogger.jsBridge('receive', payload, { sender }, '\r\n -----> ', (_e = (_d = payload.data) === null || _d === void 0 ? void 0 : _d.result) !== null && _e !== void 0 ? _e : payload.data, '\r\n <----- ', relatedSendPayload === null || relatedSendPayload === void 0 ? void 0 : relatedSendPayload.data);
264
288
  const { type, id, data, error, origin, remoteId } = payload;
265
289
  this.remoteInfo = {
266
290
  origin,
@@ -8,6 +8,7 @@ class JsBridgeSimple extends JsBridgeBase_1.JsBridgeBase {
8
8
  this.sendAsString = true;
9
9
  this.isInjected = true;
10
10
  this.remote = null;
11
+ this.callbacksExpireTimeout = 0;
11
12
  }
12
13
  sendPayload(payload) {
13
14
  if (!this.remote) {
@@ -13,8 +13,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.ProviderBase = void 0;
16
- const eventemitter3_1 = __importDefault(require("eventemitter3"));
17
16
  const isFunction_1 = __importDefault(require("lodash/isFunction"));
17
+ const CrossEventEmitter_1 = require("./CrossEventEmitter");
18
18
  const siteMetadata_1 = __importDefault(require("./siteMetadata"));
19
19
  const loggers_1 = require("./loggers");
20
20
  const versionInfo_1 = __importDefault(require("./versionInfo"));
@@ -22,7 +22,7 @@ const METHODS = {
22
22
  wallet_getConnectWalletInfo: 'wallet_getConnectWalletInfo',
23
23
  wallet_sendSiteMetadata: 'wallet_sendSiteMetadata',
24
24
  };
25
- class ProviderBase extends eventemitter3_1.default {
25
+ class ProviderBase extends CrossEventEmitter_1.CrossEventEmitter {
26
26
  constructor(config) {
27
27
  var _a, _b, _c;
28
28
  super();
@@ -43,9 +43,9 @@ class ProviderBase extends eventemitter3_1.default {
43
43
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
44
44
  this.bridge.attachProviderInstance(this);
45
45
  }, 0);
46
- if (config.shouldSendMetadata) {
47
- void this.sendSiteMetadata();
48
- }
46
+ // call sendSiteMetadataDomReady/getConnectWalletInfo in ProviderPrivate, dont need here
47
+ // void this.sendSiteMetadataDomReady();
48
+ // void this.getConnectWalletInfo();
49
49
  }
50
50
  configDebugLogger(config) {
51
51
  try {
@@ -125,7 +125,8 @@ class ProviderBase extends eventemitter3_1.default {
125
125
  const resData = yield this.bridge.request(payload);
126
126
  const result = resData ? resData.result : undefined;
127
127
  if (callback && hasCallback) {
128
- callback(null, result);
128
+ // callback with params: { id, result, jsonrpc }
129
+ callback(null, resData);
129
130
  }
130
131
  this.debugLogger.providerBase('bridgeRequest RETURN:', { req: payload, res: resData }, '\r\n -----> ', payload.data, '\r\n -----> ', result);
131
132
  return result;
@@ -138,6 +139,18 @@ class ProviderBase extends eventemitter3_1.default {
138
139
  }
139
140
  });
140
141
  }
142
+ sendSiteMetadataDomReady() {
143
+ if (document.readyState === 'complete') {
144
+ void this.sendSiteMetadata();
145
+ }
146
+ else {
147
+ const domContentLoadedHandler = () => {
148
+ void this.sendSiteMetadata();
149
+ window.removeEventListener('DOMContentLoaded', domContentLoadedHandler);
150
+ };
151
+ window.addEventListener('DOMContentLoaded', domContentLoadedHandler);
152
+ }
153
+ }
141
154
  sendSiteMetadata() {
142
155
  return __awaiter(this, void 0, void 0, function* () {
143
156
  const metadata = yield siteMetadata_1.default.getSiteMetadata();
package/dist/cjs/index.js CHANGED
@@ -32,6 +32,7 @@ __exportStar(require("./loggers"), exports);
32
32
  __exportStar(require("./injectJsBridge"), exports);
33
33
  __exportStar(require("./injectedProviderReceiveHandler"), exports);
34
34
  __exportStar(require("./JsBridgeSimple"), exports);
35
+ __exportStar(require("./CrossEventEmitter"), exports);
35
36
  const consts = __importStar(require("./consts"));
36
37
  exports.consts = consts;
37
38
  const injectedFactory_1 = __importDefault(require("./injectedFactory"));
@@ -7,6 +7,7 @@ exports.consoleErrorInDev = exports.fakeLogger = exports.appDebugLogger = export
7
7
  // @ts-ignore
8
8
  const debug_1 = __importDefault(require("./debug"));
9
9
  const consts_1 = require("./consts");
10
+ const CrossEventEmitter_1 = require("./CrossEventEmitter");
10
11
  // enable debugLogger:
11
12
  // localStorage.setItem('$$ONEKEY_DEBUG_LOGGER', '*');
12
13
  function consoleErrorInDev(...args) {
@@ -27,8 +28,26 @@ const fakeLogger = {
27
28
  trace: (...args) => undefined,
28
29
  };
29
30
  exports.fakeLogger = fakeLogger;
30
- class FakeDebugLogger {
31
+ var loggerNames;
32
+ (function (loggerNames) {
33
+ loggerNames["jsBridge"] = "jsBridge";
34
+ loggerNames["providerBase"] = "providerBase";
35
+ loggerNames["extInjected"] = "extInjected";
36
+ loggerNames["extContentScripts"] = "extContentScripts";
37
+ loggerNames["webview"] = "webview";
38
+ loggerNames["desktopInjected"] = "desktopInjected";
39
+ loggerNames["ethereum"] = "ethereum";
40
+ })(loggerNames || (loggerNames = {}));
41
+ class FakeDebugLogger extends CrossEventEmitter_1.CrossEventEmitter {
31
42
  constructor() {
43
+ super();
44
+ this.jsBridge = (...args) => null;
45
+ this.providerBase = (...args) => null;
46
+ this.extInjected = (...args) => null;
47
+ this.extContentScripts = (...args) => null;
48
+ this.webview = (...args) => null;
49
+ this.desktopInjected = (...args) => null;
50
+ this.ethereum = (...args) => null;
32
51
  this._debug = {
33
52
  enable(config) {
34
53
  //noop
@@ -36,19 +55,26 @@ class FakeDebugLogger {
36
55
  };
37
56
  this._externalLogger = fakeLogger;
38
57
  this._createExternalLog = (name) => (...args) => {
39
- const _logger = this._externalLogger;
40
- if (_logger) {
41
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
42
- return _logger.log(name, ...args);
43
- }
58
+ var _a, _b;
59
+ this.once('debugReady', () => {
60
+ var _a;
61
+ // @ts-ignore
62
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
63
+ (_a = this[name]) === null || _a === void 0 ? void 0 : _a.call(this, ...args);
64
+ });
65
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
66
+ return (_b = (_a = this._externalLogger) === null || _a === void 0 ? void 0 : _a.log) === null || _b === void 0 ? void 0 : _b.call(_a, name + ' >>> ', ...args);
44
67
  };
45
- this.jsBridge = this._createExternalLog('jsBridge >>');
46
- this.providerBase = this._createExternalLog('providerBase >>');
47
- this.extInjected = this._createExternalLog('extInjected >>');
48
- this.extContentScripts = this._createExternalLog('extContentScripts >>');
49
- this.webview = this._createExternalLog('webview >>');
50
- this.desktopInjected = this._createExternalLog('desktopInjected >>');
51
- this.ethereum = this._createExternalLog('ethereum >>');
68
+ this.initExternalLogInstances();
69
+ }
70
+ initExternalLogInstances() {
71
+ Object.keys(loggerNames).forEach((name) => {
72
+ // @ts-ignore
73
+ this[name] = this._createExternalLog(name);
74
+ });
75
+ }
76
+ isDebugReady() {
77
+ return this._debug && typeof this._debug === 'function';
52
78
  }
53
79
  _attachExternalLogger(logger) {
54
80
  if (logger) {
@@ -63,7 +89,21 @@ class AppDebugLogger extends FakeDebugLogger {
63
89
  constructor() {
64
90
  super();
65
91
  this._debugInstanceCreatedMap = {};
66
- void (0, debug_1.default)().then((debug) => (this._debug = debug));
92
+ // TODO createDebugSync
93
+ void (0, debug_1.default)().then((debug) => {
94
+ this._debug = debug;
95
+ this.initDebugInstances();
96
+ this.emit('debugReady');
97
+ });
98
+ }
99
+ initDebugInstances() {
100
+ if (this.isDebugReady()) {
101
+ Object.keys(loggerNames).forEach((name) => {
102
+ // @ts-ignore
103
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-assignment
104
+ this[name] = this._debug(name);
105
+ });
106
+ }
67
107
  }
68
108
  _createDebugInstance(name) {
69
109
  if (this._debugInstanceCreatedMap[name]) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const version = '0.0.7-alpha.2';
3
+ const version = '0.0.8';
4
4
  const versionBuild = '2020-0101-1';
5
5
  exports.default = {
6
6
  version,
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export * from './loggers';
4
4
  export * from './injectJsBridge';
5
5
  export * from './injectedProviderReceiveHandler';
6
6
  export * from './JsBridgeSimple';
7
+ export * from './CrossEventEmitter';
7
8
  import * as consts from './consts';
8
9
  export { consts };
9
10
  import injectedFactory from './injectedFactory';
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ export * from './loggers';
4
4
  export * from './injectJsBridge';
5
5
  export * from './injectedProviderReceiveHandler';
6
6
  export * from './JsBridgeSimple';
7
+ export * from './CrossEventEmitter';
7
8
  import * as consts from './consts';
8
9
  export { consts };
9
10
  import injectedFactory from './injectedFactory';
package/dist/loggers.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // @ts-ignore
2
2
  import createDebugAsync from './debug';
3
3
  import { DEBUG_LOGGER_STORAGE_KEY } from './consts';
4
+ import { CrossEventEmitter } from './CrossEventEmitter';
4
5
  // enable debugLogger:
5
6
  // localStorage.setItem('$$ONEKEY_DEBUG_LOGGER', '*');
6
7
  function consoleErrorInDev(...args) {
@@ -19,8 +20,26 @@ const fakeLogger = {
19
20
  info: (...args) => undefined,
20
21
  trace: (...args) => undefined,
21
22
  };
22
- class FakeDebugLogger {
23
+ var loggerNames;
24
+ (function (loggerNames) {
25
+ loggerNames["jsBridge"] = "jsBridge";
26
+ loggerNames["providerBase"] = "providerBase";
27
+ loggerNames["extInjected"] = "extInjected";
28
+ loggerNames["extContentScripts"] = "extContentScripts";
29
+ loggerNames["webview"] = "webview";
30
+ loggerNames["desktopInjected"] = "desktopInjected";
31
+ loggerNames["ethereum"] = "ethereum";
32
+ })(loggerNames || (loggerNames = {}));
33
+ class FakeDebugLogger extends CrossEventEmitter {
23
34
  constructor() {
35
+ super();
36
+ this.jsBridge = (...args) => null;
37
+ this.providerBase = (...args) => null;
38
+ this.extInjected = (...args) => null;
39
+ this.extContentScripts = (...args) => null;
40
+ this.webview = (...args) => null;
41
+ this.desktopInjected = (...args) => null;
42
+ this.ethereum = (...args) => null;
24
43
  this._debug = {
25
44
  enable(config) {
26
45
  //noop
@@ -28,19 +47,26 @@ class FakeDebugLogger {
28
47
  };
29
48
  this._externalLogger = fakeLogger;
30
49
  this._createExternalLog = (name) => (...args) => {
31
- const _logger = this._externalLogger;
32
- if (_logger) {
33
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
34
- return _logger.log(name, ...args);
35
- }
50
+ var _a, _b;
51
+ this.once('debugReady', () => {
52
+ var _a;
53
+ // @ts-ignore
54
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
55
+ (_a = this[name]) === null || _a === void 0 ? void 0 : _a.call(this, ...args);
56
+ });
57
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
58
+ return (_b = (_a = this._externalLogger) === null || _a === void 0 ? void 0 : _a.log) === null || _b === void 0 ? void 0 : _b.call(_a, name + ' >>> ', ...args);
36
59
  };
37
- this.jsBridge = this._createExternalLog('jsBridge >>');
38
- this.providerBase = this._createExternalLog('providerBase >>');
39
- this.extInjected = this._createExternalLog('extInjected >>');
40
- this.extContentScripts = this._createExternalLog('extContentScripts >>');
41
- this.webview = this._createExternalLog('webview >>');
42
- this.desktopInjected = this._createExternalLog('desktopInjected >>');
43
- this.ethereum = this._createExternalLog('ethereum >>');
60
+ this.initExternalLogInstances();
61
+ }
62
+ initExternalLogInstances() {
63
+ Object.keys(loggerNames).forEach((name) => {
64
+ // @ts-ignore
65
+ this[name] = this._createExternalLog(name);
66
+ });
67
+ }
68
+ isDebugReady() {
69
+ return this._debug && typeof this._debug === 'function';
44
70
  }
45
71
  _attachExternalLogger(logger) {
46
72
  if (logger) {
@@ -55,7 +81,21 @@ class AppDebugLogger extends FakeDebugLogger {
55
81
  constructor() {
56
82
  super();
57
83
  this._debugInstanceCreatedMap = {};
58
- void createDebugAsync().then((debug) => (this._debug = debug));
84
+ // TODO createDebugSync
85
+ void createDebugAsync().then((debug) => {
86
+ this._debug = debug;
87
+ this.initDebugInstances();
88
+ this.emit('debugReady');
89
+ });
90
+ }
91
+ initDebugInstances() {
92
+ if (this.isDebugReady()) {
93
+ Object.keys(loggerNames).forEach((name) => {
94
+ // @ts-ignore
95
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-assignment
96
+ this[name] = this._debug(name);
97
+ });
98
+ }
59
99
  }
60
100
  _createDebugInstance(name) {
61
101
  if (this._debugInstanceCreatedMap[name]) {
@@ -1,4 +1,4 @@
1
- const version = '0.0.7-alpha.2';
1
+ const version = '0.0.8';
2
2
  const versionBuild = '2020-0101-1';
3
3
  export default {
4
4
  version,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/cross-inpage-provider-core",
3
- "version": "0.0.7-alpha.2",
3
+ "version": "0.0.8",
4
4
  "keywords": [
5
5
  "cross-inpage-provider"
6
6
  ],
@@ -29,11 +29,12 @@
29
29
  "build-version-info": "node ./scripts/buildVersionInfo.js"
30
30
  },
31
31
  "dependencies": {
32
- "@onekeyfe/cross-inpage-provider-errors": "^0.0.7-alpha.2",
33
- "@onekeyfe/cross-inpage-provider-types": "^0.0.7-alpha.2",
34
- "eventemitter3": "^4.0.7",
32
+ "@onekeyfe/cross-inpage-provider-errors": "^0.0.8",
33
+ "@onekeyfe/cross-inpage-provider-events": "^0.0.8",
34
+ "@onekeyfe/cross-inpage-provider-types": "^0.0.8",
35
+ "events": "^3.3.0",
35
36
  "lodash": "^4.17.21",
36
37
  "ms": "^2.1.3"
37
38
  },
38
- "gitHead": "ed05282b43f00a712dae7f62ea12063eb56c8cce"
39
+ "gitHead": "ceff8e9a3a3600e37b98778fd0736d8cee0f8d10"
39
40
  }