-
Notifications
You must be signed in to change notification settings - Fork 618
/
core.ts
169 lines (145 loc) · 5.06 KB
/
core.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import { EventEmitter } from "events";
import KeyValueStorage from "@walletconnect/keyvaluestorage";
import { HeartBeat } from "@walletconnect/heartbeat";
import {
generateChildLogger,
getDefaultLoggerOptions,
getLoggerContext,
generatePlatformLogger,
ChunkLoggerController,
} from "@walletconnect/logger";
import { CoreTypes, ICore } from "@walletconnect/types";
import {
Crypto,
Relayer,
Pairing,
JsonRpcHistory,
Expirer,
Verify,
EchoClient,
} from "./controllers";
import {
CORE_CONTEXT,
CORE_DEFAULT,
CORE_PROTOCOL,
CORE_STORAGE_OPTIONS,
CORE_VERSION,
RELAYER_DEFAULT_RELAY_URL,
WALLETCONNECT_CLIENT_ID,
} from "./constants";
export class Core extends ICore {
public readonly protocol = CORE_PROTOCOL;
public readonly version = CORE_VERSION;
public readonly name: ICore["name"] = CORE_CONTEXT;
public readonly relayUrl: ICore["relayUrl"];
public readonly projectId: ICore["projectId"];
public readonly customStoragePrefix: ICore["customStoragePrefix"];
public events: ICore["events"] = new EventEmitter();
public logger: ICore["logger"];
public heartbeat: ICore["heartbeat"];
public relayer: ICore["relayer"];
public crypto: ICore["crypto"];
public storage: ICore["storage"];
public history: ICore["history"];
public expirer: ICore["expirer"];
public pairing: ICore["pairing"];
public verify: ICore["verify"];
public echoClient: ICore["echoClient"];
private initialized = false;
private logChunkController: ChunkLoggerController | null;
static async init(opts?: CoreTypes.Options) {
const core = new Core(opts);
await core.initialize();
const clientId = await core.crypto.getClientId();
await core.storage.setItem(WALLETCONNECT_CLIENT_ID, clientId);
return core;
}
constructor(opts?: CoreTypes.Options) {
super(opts);
this.projectId = opts?.projectId;
this.relayUrl = opts?.relayUrl || RELAYER_DEFAULT_RELAY_URL;
this.customStoragePrefix = opts?.customStoragePrefix ? `:${opts.customStoragePrefix}` : "";
const loggerOptions = getDefaultLoggerOptions({
level: typeof opts?.logger === "string" && opts.logger ? opts.logger : CORE_DEFAULT.logger,
});
const { logger, chunkLoggerController } = generatePlatformLogger({
opts: loggerOptions,
maxSizeInBytes: opts?.maxLogBlobSizeInBytes,
loggerOverride: opts?.logger,
});
this.logChunkController = chunkLoggerController;
if (this.logChunkController?.downloadLogsBlobInBrowser) {
// @ts-ignore
window.downloadLogsBlobInBrowser = async () => {
// Have to null check twice becquse there is no guarantee
// this.logChunkController.downloadLogsBlobInBrowser is always truthy
if (this.logChunkController?.downloadLogsBlobInBrowser) {
this.logChunkController?.downloadLogsBlobInBrowser({
clientId: await this.crypto.getClientId(),
});
}
};
}
this.logger = generateChildLogger(logger, this.name);
this.heartbeat = new HeartBeat();
this.crypto = new Crypto(this, this.logger, opts?.keychain);
this.history = new JsonRpcHistory(this, this.logger);
this.expirer = new Expirer(this, this.logger);
this.storage = opts?.storage
? opts.storage
: new KeyValueStorage({ ...CORE_STORAGE_OPTIONS, ...opts?.storageOptions });
this.relayer = new Relayer({
core: this,
logger: this.logger,
relayUrl: this.relayUrl,
projectId: this.projectId,
});
this.pairing = new Pairing(this, this.logger);
this.verify = new Verify(this.projectId || "", this.logger);
this.echoClient = new EchoClient(this.projectId || "", this.logger);
}
get context() {
return getLoggerContext(this.logger);
}
// ---------- Public ----------------------------------------------- //
public async start() {
if (this.initialized) return;
await this.initialize();
}
public async getLogsBlob() {
return this.logChunkController?.logsToBlob({
clientId: await this.crypto.getClientId(),
});
}
// ---------- Events ----------------------------------------------- //
public on = (name: any, listener: any) => {
return this.events.on(name, listener);
};
public once = (name: any, listener: any) => {
return this.events.once(name, listener);
};
public off = (name: any, listener: any) => {
return this.events.off(name, listener);
};
public removeListener = (name: any, listener: any) => {
return this.events.removeListener(name, listener);
};
// ---------- Private ----------------------------------------------- //
private async initialize() {
this.logger.trace(`Initialized`);
try {
await this.crypto.init();
await this.history.init();
await this.expirer.init();
await this.relayer.init();
await this.heartbeat.init();
await this.pairing.init();
this.initialized = true;
this.logger.info(`Core Initialization Success`);
} catch (error) {
this.logger.warn(`Core Initialization Failure at epoch ${Date.now()}`, error);
this.logger.error((error as any).message);
throw error;
}
}
}