@tonconnect/sdk 3.3.1 → 3.4.0-beta.1
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.
- package/README.md +54 -0
- package/dist/tonconnect-sdk.min.js +1 -1
- package/dist/tonconnect-sdk.min.js.map +1 -1
- package/lib/cjs/index.cjs +1090 -201
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/esm/index.mjs +1085 -202
- package/lib/esm/index.mjs.map +1 -1
- package/lib/types/index.d.ts +336 -50
- package/package.json +3 -3
package/lib/cjs/index.cjs
CHANGED
|
@@ -169,6 +169,14 @@ class WalletMissingRequiredFeaturesError extends TonConnectError {
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
class WalletWrongNetworkError extends TonConnectError {
|
|
173
|
+
constructor(message, options) {
|
|
174
|
+
super(message, options);
|
|
175
|
+
this.name = 'WalletWrongNetworkError';
|
|
176
|
+
Object.setPrototypeOf(this, WalletWrongNetworkError.prototype);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
172
180
|
function isWalletConnectionSourceJS(value) {
|
|
173
181
|
return 'jsBridgeKey' in value;
|
|
174
182
|
}
|
|
@@ -395,6 +403,12 @@ function isTelegramUrl(link) {
|
|
|
395
403
|
const url = new URL(link);
|
|
396
404
|
return url.protocol === 'tg:' || url.hostname === 't.me';
|
|
397
405
|
}
|
|
406
|
+
function isConnectUrl(link) {
|
|
407
|
+
if (!link) {
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
return link.includes('ton_addr') || link.includes('ton--5Faddr');
|
|
411
|
+
}
|
|
398
412
|
function encodeTelegramUrlParameters(parameters) {
|
|
399
413
|
return parameters
|
|
400
414
|
.replaceAll('.', '%2E')
|
|
@@ -404,6 +418,15 @@ function encodeTelegramUrlParameters(parameters) {
|
|
|
404
418
|
.replaceAll('=', '__')
|
|
405
419
|
.replaceAll('%', '--');
|
|
406
420
|
}
|
|
421
|
+
function decodeTelegramUrlParameters(parameters) {
|
|
422
|
+
return parameters
|
|
423
|
+
.replaceAll('--', '%')
|
|
424
|
+
.replaceAll('__', '=')
|
|
425
|
+
.replaceAll('-', '&')
|
|
426
|
+
.replaceAll('%5F', '_')
|
|
427
|
+
.replaceAll('%2D', '-')
|
|
428
|
+
.replaceAll('%2E', '.');
|
|
429
|
+
}
|
|
407
430
|
|
|
408
431
|
/**
|
|
409
432
|
* Delays the execution of code for a specified number of milliseconds.
|
|
@@ -638,7 +661,7 @@ class BridgeGateway {
|
|
|
638
661
|
const eventSource = this.eventSource.current();
|
|
639
662
|
return (eventSource === null || eventSource === void 0 ? void 0 : eventSource.readyState) === EventSource.CONNECTING;
|
|
640
663
|
}
|
|
641
|
-
constructor(storage, bridgeUrl, sessionId, listener, errorsListener) {
|
|
664
|
+
constructor(storage, bridgeUrl, sessionId, listener, errorsListener, analyticsManager) {
|
|
642
665
|
this.bridgeUrl = bridgeUrl;
|
|
643
666
|
this.sessionId = sessionId;
|
|
644
667
|
this.listener = listener;
|
|
@@ -649,7 +672,7 @@ class BridgeGateway {
|
|
|
649
672
|
this.defaultTtl = 300;
|
|
650
673
|
this.defaultReconnectDelay = 2000;
|
|
651
674
|
this.defaultResendDelay = 5000;
|
|
652
|
-
this.eventSource = createResource((signal, openingDeadlineMS) => __awaiter(this, void 0, void 0, function* () {
|
|
675
|
+
this.eventSource = createResource((signal, openingDeadlineMS, traceId) => __awaiter(this, void 0, void 0, function* () {
|
|
653
676
|
const eventSourceConfig = {
|
|
654
677
|
bridgeUrl: this.bridgeUrl,
|
|
655
678
|
ssePath: this.ssePath,
|
|
@@ -658,17 +681,41 @@ class BridgeGateway {
|
|
|
658
681
|
errorHandler: this.errorsHandler.bind(this),
|
|
659
682
|
messageHandler: this.messagesHandler.bind(this),
|
|
660
683
|
signal: signal,
|
|
661
|
-
openingDeadlineMS: openingDeadlineMS
|
|
684
|
+
openingDeadlineMS: openingDeadlineMS,
|
|
685
|
+
traceId
|
|
662
686
|
};
|
|
663
687
|
return yield createEventSource(eventSourceConfig);
|
|
664
688
|
}), (resource) => __awaiter(this, void 0, void 0, function* () {
|
|
665
689
|
resource.close();
|
|
666
690
|
}));
|
|
667
691
|
this.bridgeGatewayStorage = new HttpBridgeGatewayStorage(storage, bridgeUrl);
|
|
692
|
+
this.analytics = analyticsManager === null || analyticsManager === void 0 ? void 0 : analyticsManager.scoped({
|
|
693
|
+
bridge_url: bridgeUrl,
|
|
694
|
+
client_id: sessionId
|
|
695
|
+
});
|
|
668
696
|
}
|
|
669
697
|
registerSession(options) {
|
|
670
698
|
return __awaiter(this, void 0, void 0, function* () {
|
|
671
|
-
|
|
699
|
+
var _a, _b, _c;
|
|
700
|
+
try {
|
|
701
|
+
(_a = this.analytics) === null || _a === void 0 ? void 0 : _a.emitBridgeClientConnectStarted({
|
|
702
|
+
trace_id: options === null || options === void 0 ? void 0 : options.traceId
|
|
703
|
+
});
|
|
704
|
+
const connectionStarted = Date.now();
|
|
705
|
+
yield this.eventSource.create(options === null || options === void 0 ? void 0 : options.signal, options === null || options === void 0 ? void 0 : options.openingDeadlineMS, options === null || options === void 0 ? void 0 : options.traceId);
|
|
706
|
+
const bridgeConnectDuration = Date.now() - connectionStarted;
|
|
707
|
+
(_b = this.analytics) === null || _b === void 0 ? void 0 : _b.emitBridgeClientConnectEstablished({
|
|
708
|
+
bridge_connect_duration: bridgeConnectDuration,
|
|
709
|
+
trace_id: options === null || options === void 0 ? void 0 : options.traceId
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
catch (error) {
|
|
713
|
+
(_c = this.analytics) === null || _c === void 0 ? void 0 : _c.emitBridgeClientConnectError({
|
|
714
|
+
trace_id: options === null || options === void 0 ? void 0 : options.traceId,
|
|
715
|
+
error_message: String(error)
|
|
716
|
+
});
|
|
717
|
+
throw error;
|
|
718
|
+
}
|
|
672
719
|
});
|
|
673
720
|
}
|
|
674
721
|
send(message, receiver, topic, ttlOrOptions) {
|
|
@@ -683,12 +730,16 @@ class BridgeGateway {
|
|
|
683
730
|
options.ttl = ttlOrOptions === null || ttlOrOptions === void 0 ? void 0 : ttlOrOptions.ttl;
|
|
684
731
|
options.signal = ttlOrOptions === null || ttlOrOptions === void 0 ? void 0 : ttlOrOptions.signal;
|
|
685
732
|
options.attempts = ttlOrOptions === null || ttlOrOptions === void 0 ? void 0 : ttlOrOptions.attempts;
|
|
733
|
+
options.traceId = ttlOrOptions === null || ttlOrOptions === void 0 ? void 0 : ttlOrOptions.traceId;
|
|
686
734
|
}
|
|
687
735
|
const url = new URL(addPathToUrl(this.bridgeUrl, this.postPath));
|
|
688
736
|
url.searchParams.append('client_id', this.sessionId);
|
|
689
737
|
url.searchParams.append('to', receiver);
|
|
690
738
|
url.searchParams.append('ttl', ((options === null || options === void 0 ? void 0 : options.ttl) || this.defaultTtl).toString());
|
|
691
739
|
url.searchParams.append('topic', topic);
|
|
740
|
+
if (options === null || options === void 0 ? void 0 : options.traceId) {
|
|
741
|
+
url.searchParams.append('trace_id', options.traceId);
|
|
742
|
+
}
|
|
692
743
|
const body = protocol.Base64.encode(message);
|
|
693
744
|
yield callForSuccess((options) => __awaiter(this, void 0, void 0, function* () {
|
|
694
745
|
const response = yield this.post(url, body, options.signal);
|
|
@@ -767,7 +818,12 @@ class BridgeGateway {
|
|
|
767
818
|
}
|
|
768
819
|
let bridgeIncomingMessage;
|
|
769
820
|
try {
|
|
770
|
-
|
|
821
|
+
const bridgeIncomingMessageRaw = JSON.parse(e.data);
|
|
822
|
+
bridgeIncomingMessage = {
|
|
823
|
+
message: bridgeIncomingMessageRaw.message,
|
|
824
|
+
from: bridgeIncomingMessageRaw.from,
|
|
825
|
+
traceId: bridgeIncomingMessageRaw.trace_id
|
|
826
|
+
};
|
|
771
827
|
}
|
|
772
828
|
catch (_) {
|
|
773
829
|
throw new TonConnectError(`Bridge message parse failed, message ${e.data}`);
|
|
@@ -796,6 +852,9 @@ function createEventSource(config) {
|
|
|
796
852
|
if (lastEventId) {
|
|
797
853
|
url.searchParams.append('last_event_id', lastEventId);
|
|
798
854
|
}
|
|
855
|
+
if (config.traceId) {
|
|
856
|
+
url.searchParams.append('trace_id', config.traceId);
|
|
857
|
+
}
|
|
799
858
|
if (signal.aborted) {
|
|
800
859
|
reject(new TonConnectError('Bridge connection aborted'));
|
|
801
860
|
return;
|
|
@@ -1021,20 +1080,189 @@ class BridgeConnectionStorage {
|
|
|
1021
1080
|
|
|
1022
1081
|
const PROTOCOL_VERSION = 2;
|
|
1023
1082
|
|
|
1083
|
+
/**
|
|
1084
|
+
* The MIT License (MIT)
|
|
1085
|
+
*
|
|
1086
|
+
* Copyright (c) 2010-2020 Robert Kieffer and other contributors
|
|
1087
|
+
*
|
|
1088
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
1089
|
+
*
|
|
1090
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
1091
|
+
*
|
|
1092
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
1093
|
+
*/
|
|
1094
|
+
// Unique ID creation requires a high quality random # generator. In the browser we therefore
|
|
1095
|
+
// require the crypto API and do not support built-in fallback to lower quality random number
|
|
1096
|
+
// generators (like Math.random()).
|
|
1097
|
+
let getRandomValues;
|
|
1098
|
+
const rnds8 = new Uint8Array(16);
|
|
1099
|
+
function rng() {
|
|
1100
|
+
// lazy load so that environments that need to polyfill have a chance to do so
|
|
1101
|
+
if (!getRandomValues) {
|
|
1102
|
+
if (typeof crypto === 'undefined' || !crypto.getRandomValues) {
|
|
1103
|
+
throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
|
|
1104
|
+
}
|
|
1105
|
+
getRandomValues = crypto.getRandomValues.bind(crypto);
|
|
1106
|
+
}
|
|
1107
|
+
return getRandomValues(rnds8);
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* The MIT License (MIT)
|
|
1112
|
+
*
|
|
1113
|
+
* Copyright (c) 2010-2020 Robert Kieffer and other contributors
|
|
1114
|
+
*
|
|
1115
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
1116
|
+
*
|
|
1117
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
1118
|
+
*
|
|
1119
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
1120
|
+
*/
|
|
1121
|
+
/**
|
|
1122
|
+
* Convert array of 16 byte values to UUID string format of the form:
|
|
1123
|
+
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
|
1124
|
+
*/
|
|
1125
|
+
const byteToHex = [];
|
|
1126
|
+
for (let i = 0; i < 256; ++i) {
|
|
1127
|
+
byteToHex.push((i + 0x100).toString(16).slice(1));
|
|
1128
|
+
}
|
|
1129
|
+
function unsafeStringify(arr, offset = 0) {
|
|
1130
|
+
// Note: Be careful editing this code! It's been tuned for performance
|
|
1131
|
+
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
|
|
1132
|
+
//
|
|
1133
|
+
// Note to future-self: No, you can't remove the `toLowerCase()` call.
|
|
1134
|
+
// REF: https://github.com/uuidjs/uuid/pull/677#issuecomment-1757351351
|
|
1135
|
+
return (byteToHex[arr[offset + 0]] +
|
|
1136
|
+
byteToHex[arr[offset + 1]] +
|
|
1137
|
+
byteToHex[arr[offset + 2]] +
|
|
1138
|
+
byteToHex[arr[offset + 3]] +
|
|
1139
|
+
'-' +
|
|
1140
|
+
byteToHex[arr[offset + 4]] +
|
|
1141
|
+
byteToHex[arr[offset + 5]] +
|
|
1142
|
+
'-' +
|
|
1143
|
+
byteToHex[arr[offset + 6]] +
|
|
1144
|
+
byteToHex[arr[offset + 7]] +
|
|
1145
|
+
'-' +
|
|
1146
|
+
byteToHex[arr[offset + 8]] +
|
|
1147
|
+
byteToHex[arr[offset + 9]] +
|
|
1148
|
+
'-' +
|
|
1149
|
+
byteToHex[arr[offset + 10]] +
|
|
1150
|
+
byteToHex[arr[offset + 11]] +
|
|
1151
|
+
byteToHex[arr[offset + 12]] +
|
|
1152
|
+
byteToHex[arr[offset + 13]] +
|
|
1153
|
+
byteToHex[arr[offset + 14]] +
|
|
1154
|
+
byteToHex[arr[offset + 15]]).toLowerCase();
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
/**
|
|
1158
|
+
* The MIT License (MIT)
|
|
1159
|
+
*
|
|
1160
|
+
* Copyright (c) 2010-2020 Robert Kieffer and other contributors
|
|
1161
|
+
*
|
|
1162
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
1163
|
+
*
|
|
1164
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
1165
|
+
*
|
|
1166
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
1167
|
+
*/
|
|
1168
|
+
const _state = {};
|
|
1169
|
+
function UUIDv7(options, buf, offset) {
|
|
1170
|
+
var _a, _b, _c;
|
|
1171
|
+
let bytes;
|
|
1172
|
+
if (options) {
|
|
1173
|
+
// With options: Make UUID independent of internal state
|
|
1174
|
+
bytes = v7Bytes((_c = (_a = options.random) !== null && _a !== void 0 ? _a : (_b = options.rng) === null || _b === void 0 ? void 0 : _b.call(options)) !== null && _c !== void 0 ? _c : rng(), options.msecs, options.seq, buf, offset);
|
|
1175
|
+
}
|
|
1176
|
+
else {
|
|
1177
|
+
// No options: Use internal state
|
|
1178
|
+
const now = Date.now();
|
|
1179
|
+
const rnds = rng();
|
|
1180
|
+
updateV7State(_state, now, rnds);
|
|
1181
|
+
bytes = v7Bytes(rnds, _state.msecs, _state.seq, buf, offset);
|
|
1182
|
+
}
|
|
1183
|
+
return buf !== null && buf !== void 0 ? buf : unsafeStringify(bytes);
|
|
1184
|
+
}
|
|
1185
|
+
// (Private!) Do not use. This method is only exported for testing purposes
|
|
1186
|
+
// and may change without notice.
|
|
1187
|
+
function updateV7State(state, now, rnds) {
|
|
1188
|
+
var _a, _b;
|
|
1189
|
+
(_a = state.msecs) !== null && _a !== void 0 ? _a : (state.msecs = -Infinity);
|
|
1190
|
+
(_b = state.seq) !== null && _b !== void 0 ? _b : (state.seq = 0);
|
|
1191
|
+
if (now > state.msecs) {
|
|
1192
|
+
// Time has moved on! Pick a new random sequence number
|
|
1193
|
+
state.seq = (rnds[6] << 23) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9];
|
|
1194
|
+
state.msecs = now;
|
|
1195
|
+
}
|
|
1196
|
+
else {
|
|
1197
|
+
// Bump sequence counter w/ 32-bit rollover
|
|
1198
|
+
state.seq = (state.seq + 1) | 0;
|
|
1199
|
+
// In case of rollover, bump timestamp to preserve monotonicity. This is
|
|
1200
|
+
// allowed by the RFC and should self-correct as the system clock catches
|
|
1201
|
+
// up. See https://www.rfc-editor.org/rfc/rfc9562.html#section-6.2-9.4
|
|
1202
|
+
if (state.seq === 0) {
|
|
1203
|
+
state.msecs++;
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
return state;
|
|
1207
|
+
}
|
|
1208
|
+
function v7Bytes(rnds, msecs, seq, buf, offset = 0) {
|
|
1209
|
+
if (rnds.length < 16) {
|
|
1210
|
+
throw new Error('Random bytes length must be >= 16');
|
|
1211
|
+
}
|
|
1212
|
+
if (!buf) {
|
|
1213
|
+
buf = new Uint8Array(16);
|
|
1214
|
+
offset = 0;
|
|
1215
|
+
}
|
|
1216
|
+
else {
|
|
1217
|
+
if (offset < 0 || offset + 16 > buf.length) {
|
|
1218
|
+
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
// Defaults
|
|
1222
|
+
msecs !== null && msecs !== void 0 ? msecs : (msecs = Date.now());
|
|
1223
|
+
seq !== null && seq !== void 0 ? seq : (seq = ((rnds[6] * 0x7f) << 24) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9]);
|
|
1224
|
+
// byte 0-5: timestamp (48 bits)
|
|
1225
|
+
buf[offset++] = (msecs / 0x10000000000) & 0xff;
|
|
1226
|
+
buf[offset++] = (msecs / 0x100000000) & 0xff;
|
|
1227
|
+
buf[offset++] = (msecs / 0x1000000) & 0xff;
|
|
1228
|
+
buf[offset++] = (msecs / 0x10000) & 0xff;
|
|
1229
|
+
buf[offset++] = (msecs / 0x100) & 0xff;
|
|
1230
|
+
buf[offset++] = msecs & 0xff;
|
|
1231
|
+
// byte 6: `version` (4 bits) | sequence bits 28-31 (4 bits)
|
|
1232
|
+
buf[offset++] = 0x70 | ((seq >>> 28) & 0x0f);
|
|
1233
|
+
// byte 7: sequence bits 20-27 (8 bits)
|
|
1234
|
+
buf[offset++] = (seq >>> 20) & 0xff;
|
|
1235
|
+
// byte 8: `variant` (2 bits) | sequence bits 14-19 (6 bits)
|
|
1236
|
+
buf[offset++] = 0x80 | ((seq >>> 14) & 0x3f);
|
|
1237
|
+
// byte 9: sequence bits 6-13 (8 bits)
|
|
1238
|
+
buf[offset++] = (seq >>> 6) & 0xff;
|
|
1239
|
+
// byte 10: sequence bits 0-5 (6 bits) | random (2 bits)
|
|
1240
|
+
buf[offset++] = ((seq << 2) & 0xff) | (rnds[10] & 0x03);
|
|
1241
|
+
// bytes 11-15: random (40 bits)
|
|
1242
|
+
buf[offset++] = rnds[11];
|
|
1243
|
+
buf[offset++] = rnds[12];
|
|
1244
|
+
buf[offset++] = rnds[13];
|
|
1245
|
+
buf[offset++] = rnds[14];
|
|
1246
|
+
buf[offset++] = rnds[15];
|
|
1247
|
+
return buf;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1024
1250
|
class BridgeProvider {
|
|
1025
|
-
static fromStorage(storage) {
|
|
1251
|
+
static fromStorage(storage, analyticsManager) {
|
|
1026
1252
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1027
1253
|
const bridgeConnectionStorage = new BridgeConnectionStorage(storage);
|
|
1028
1254
|
const connection = yield bridgeConnectionStorage.getHttpConnection();
|
|
1029
1255
|
if (isPendingConnectionHttp(connection)) {
|
|
1030
|
-
return new BridgeProvider(storage, connection.connectionSource);
|
|
1256
|
+
return new BridgeProvider(storage, connection.connectionSource, analyticsManager);
|
|
1031
1257
|
}
|
|
1032
|
-
return new BridgeProvider(storage, { bridgeUrl: connection.session.bridgeUrl });
|
|
1258
|
+
return new BridgeProvider(storage, { bridgeUrl: connection.session.bridgeUrl }, analyticsManager);
|
|
1033
1259
|
});
|
|
1034
1260
|
}
|
|
1035
|
-
constructor(storage, walletConnectionSource) {
|
|
1261
|
+
constructor(storage, walletConnectionSource, analyticsManager) {
|
|
1262
|
+
var _a;
|
|
1036
1263
|
this.storage = storage;
|
|
1037
1264
|
this.walletConnectionSource = walletConnectionSource;
|
|
1265
|
+
this.analyticsManager = analyticsManager;
|
|
1038
1266
|
this.type = 'http';
|
|
1039
1267
|
this.standardUniversalLink = 'tc://';
|
|
1040
1268
|
this.pendingRequests = new Map();
|
|
@@ -1045,11 +1273,13 @@ class BridgeProvider {
|
|
|
1045
1273
|
this.defaultOpeningDeadlineMS = 12000;
|
|
1046
1274
|
this.defaultRetryTimeoutMS = 2000;
|
|
1047
1275
|
this.connectionStorage = new BridgeConnectionStorage(storage);
|
|
1276
|
+
this.analytics = (_a = this.analyticsManager) === null || _a === void 0 ? void 0 : _a.scoped();
|
|
1048
1277
|
}
|
|
1049
1278
|
connect(message, options) {
|
|
1050
|
-
var _a;
|
|
1279
|
+
var _a, _b;
|
|
1280
|
+
const traceId = (_a = options === null || options === void 0 ? void 0 : options.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
1051
1281
|
const abortController = createAbortController(options === null || options === void 0 ? void 0 : options.signal);
|
|
1052
|
-
(
|
|
1282
|
+
(_b = this.abortController) === null || _b === void 0 ? void 0 : _b.abort();
|
|
1053
1283
|
this.abortController = abortController;
|
|
1054
1284
|
this.closeGateways();
|
|
1055
1285
|
const sessionCrypto = new protocol.SessionCrypto();
|
|
@@ -1073,7 +1303,8 @@ class BridgeProvider {
|
|
|
1073
1303
|
var _a;
|
|
1074
1304
|
return this.openGateways(sessionCrypto, {
|
|
1075
1305
|
openingDeadlineMS: (_a = options === null || options === void 0 ? void 0 : options.openingDeadlineMS) !== null && _a !== void 0 ? _a : this.defaultOpeningDeadlineMS,
|
|
1076
|
-
signal: _options === null || _options === void 0 ? void 0 : _options.signal
|
|
1306
|
+
signal: _options === null || _options === void 0 ? void 0 : _options.signal,
|
|
1307
|
+
traceId
|
|
1077
1308
|
});
|
|
1078
1309
|
}, {
|
|
1079
1310
|
attempts: Number.MAX_SAFE_INTEGER,
|
|
@@ -1085,13 +1316,14 @@ class BridgeProvider {
|
|
|
1085
1316
|
this.walletConnectionSource.universalLink
|
|
1086
1317
|
? this.walletConnectionSource.universalLink
|
|
1087
1318
|
: this.standardUniversalLink;
|
|
1088
|
-
return this.generateUniversalLink(universalLink, message);
|
|
1319
|
+
return this.generateUniversalLink(universalLink, message, { traceId });
|
|
1089
1320
|
}
|
|
1090
1321
|
restoreConnection(options) {
|
|
1091
1322
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1092
|
-
var _a, _b;
|
|
1323
|
+
var _a, _b, _c;
|
|
1324
|
+
const traceId = (_a = options === null || options === void 0 ? void 0 : options.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
1093
1325
|
const abortController = createAbortController(options === null || options === void 0 ? void 0 : options.signal);
|
|
1094
|
-
(
|
|
1326
|
+
(_b = this.abortController) === null || _b === void 0 ? void 0 : _b.abort();
|
|
1095
1327
|
this.abortController = abortController;
|
|
1096
1328
|
if (abortController.signal.aborted) {
|
|
1097
1329
|
return;
|
|
@@ -1104,7 +1336,7 @@ class BridgeProvider {
|
|
|
1104
1336
|
if (abortController.signal.aborted) {
|
|
1105
1337
|
return;
|
|
1106
1338
|
}
|
|
1107
|
-
const openingDeadlineMS = (
|
|
1339
|
+
const openingDeadlineMS = (_c = options === null || options === void 0 ? void 0 : options.openingDeadlineMS) !== null && _c !== void 0 ? _c : this.defaultOpeningDeadlineMS;
|
|
1108
1340
|
if (isPendingConnectionHttp(storedConnection)) {
|
|
1109
1341
|
this.session = {
|
|
1110
1342
|
sessionCrypto: storedConnection.sessionCrypto,
|
|
@@ -1114,7 +1346,8 @@ class BridgeProvider {
|
|
|
1114
1346
|
};
|
|
1115
1347
|
return yield this.openGateways(storedConnection.sessionCrypto, {
|
|
1116
1348
|
openingDeadlineMS: openingDeadlineMS,
|
|
1117
|
-
signal: abortController === null || abortController === void 0 ? void 0 : abortController.signal
|
|
1349
|
+
signal: abortController === null || abortController === void 0 ? void 0 : abortController.signal,
|
|
1350
|
+
traceId: options === null || options === void 0 ? void 0 : options.traceId
|
|
1118
1351
|
});
|
|
1119
1352
|
}
|
|
1120
1353
|
if (Array.isArray(this.walletConnectionSource)) {
|
|
@@ -1125,17 +1358,18 @@ class BridgeProvider {
|
|
|
1125
1358
|
logDebug('Gateway is already opened, closing previous gateway');
|
|
1126
1359
|
yield this.gateway.close();
|
|
1127
1360
|
}
|
|
1128
|
-
this.gateway = new BridgeGateway(this.storage, this.walletConnectionSource.bridgeUrl, storedConnection.session.sessionCrypto.sessionId, this.gatewayListener.bind(this), this.gatewayErrorsListener.bind(this));
|
|
1361
|
+
this.gateway = new BridgeGateway(this.storage, this.walletConnectionSource.bridgeUrl, storedConnection.session.sessionCrypto.sessionId, this.gatewayListener.bind(this), this.gatewayErrorsListener.bind(this), this.analyticsManager);
|
|
1129
1362
|
if (abortController.signal.aborted) {
|
|
1130
1363
|
return;
|
|
1131
1364
|
}
|
|
1132
1365
|
// notify listeners about stored connection
|
|
1133
|
-
this.listeners.forEach(listener => listener(storedConnection.connectEvent));
|
|
1366
|
+
this.listeners.forEach(listener => listener(Object.assign(Object.assign({}, storedConnection.connectEvent), { traceId })));
|
|
1134
1367
|
// wait for the connection to be opened
|
|
1135
1368
|
try {
|
|
1136
1369
|
yield callForSuccess(options => this.gateway.registerSession({
|
|
1137
1370
|
openingDeadlineMS: openingDeadlineMS,
|
|
1138
|
-
signal: options.signal
|
|
1371
|
+
signal: options.signal,
|
|
1372
|
+
traceId
|
|
1139
1373
|
}), {
|
|
1140
1374
|
attempts: Number.MAX_SAFE_INTEGER,
|
|
1141
1375
|
delayMs: this.defaultRetryTimeoutMS,
|
|
@@ -1143,12 +1377,13 @@ class BridgeProvider {
|
|
|
1143
1377
|
});
|
|
1144
1378
|
}
|
|
1145
1379
|
catch (e) {
|
|
1146
|
-
yield this.disconnect({ signal: abortController.signal });
|
|
1380
|
+
yield this.disconnect({ signal: abortController.signal, traceId });
|
|
1147
1381
|
return;
|
|
1148
1382
|
}
|
|
1149
1383
|
});
|
|
1150
1384
|
}
|
|
1151
1385
|
sendRequest(request, optionsOrOnRequestSent) {
|
|
1386
|
+
var _a;
|
|
1152
1387
|
// TODO: remove deprecated method
|
|
1153
1388
|
const options = {};
|
|
1154
1389
|
if (typeof optionsOrOnRequestSent === 'function') {
|
|
@@ -1158,9 +1393,11 @@ class BridgeProvider {
|
|
|
1158
1393
|
options.onRequestSent = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.onRequestSent;
|
|
1159
1394
|
options.signal = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.signal;
|
|
1160
1395
|
options.attempts = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.attempts;
|
|
1396
|
+
options.traceId = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.traceId;
|
|
1161
1397
|
}
|
|
1398
|
+
(_a = options.traceId) !== null && _a !== void 0 ? _a : (options.traceId = UUIDv7());
|
|
1162
1399
|
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
1163
|
-
var _a;
|
|
1400
|
+
var _a, _b;
|
|
1164
1401
|
if (!this.gateway || !this.session || !('walletPublicKey' in this.session)) {
|
|
1165
1402
|
throw new TonConnectError('Trying to send bridge request without session');
|
|
1166
1403
|
}
|
|
@@ -1169,8 +1406,20 @@ class BridgeProvider {
|
|
|
1169
1406
|
logDebug('Send http-bridge request:', Object.assign(Object.assign({}, request), { id }));
|
|
1170
1407
|
const encodedRequest = this.session.sessionCrypto.encrypt(JSON.stringify(Object.assign(Object.assign({}, request), { id })), protocol.hexToByteArray(this.session.walletPublicKey));
|
|
1171
1408
|
try {
|
|
1172
|
-
|
|
1173
|
-
|
|
1409
|
+
(_a = this.analytics) === null || _a === void 0 ? void 0 : _a.emitBridgeClientMessageSent({
|
|
1410
|
+
bridge_url: this.gateway.bridgeUrl,
|
|
1411
|
+
client_id: this.session.sessionCrypto.sessionId,
|
|
1412
|
+
wallet_id: this.session.walletPublicKey,
|
|
1413
|
+
message_id: id,
|
|
1414
|
+
request_type: request.method,
|
|
1415
|
+
trace_id: options.traceId
|
|
1416
|
+
});
|
|
1417
|
+
yield this.gateway.send(encodedRequest, this.session.walletPublicKey, request.method, {
|
|
1418
|
+
attempts: options === null || options === void 0 ? void 0 : options.attempts,
|
|
1419
|
+
signal: options === null || options === void 0 ? void 0 : options.signal,
|
|
1420
|
+
traceId: options.traceId
|
|
1421
|
+
});
|
|
1422
|
+
(_b = options === null || options === void 0 ? void 0 : options.onRequestSent) === null || _b === void 0 ? void 0 : _b.call(options);
|
|
1174
1423
|
this.pendingRequests.set(id.toString(), resolve);
|
|
1175
1424
|
}
|
|
1176
1425
|
catch (e) {
|
|
@@ -1186,6 +1435,8 @@ class BridgeProvider {
|
|
|
1186
1435
|
}
|
|
1187
1436
|
disconnect(options) {
|
|
1188
1437
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1438
|
+
var _a;
|
|
1439
|
+
const traceId = (_a = options === null || options === void 0 ? void 0 : options.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
1189
1440
|
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
|
1190
1441
|
let called = false;
|
|
1191
1442
|
let timeoutId = null;
|
|
@@ -1204,7 +1455,8 @@ class BridgeProvider {
|
|
|
1204
1455
|
yield this.sendRequest({ method: 'disconnect', params: [] }, {
|
|
1205
1456
|
onRequestSent: onRequestSent,
|
|
1206
1457
|
signal: abortController.signal,
|
|
1207
|
-
attempts: 1
|
|
1458
|
+
attempts: 1,
|
|
1459
|
+
traceId
|
|
1208
1460
|
});
|
|
1209
1461
|
}
|
|
1210
1462
|
catch (e) {
|
|
@@ -1260,8 +1512,32 @@ class BridgeProvider {
|
|
|
1260
1512
|
}
|
|
1261
1513
|
gatewayListener(bridgeIncomingMessage) {
|
|
1262
1514
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1263
|
-
|
|
1515
|
+
var _a, _b, _c;
|
|
1516
|
+
const traceId = (_a = bridgeIncomingMessage.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
1517
|
+
let walletMessage;
|
|
1518
|
+
try {
|
|
1519
|
+
walletMessage = JSON.parse(this.session.sessionCrypto.decrypt(protocol.Base64.decode(bridgeIncomingMessage.message).toUint8Array(), protocol.hexToByteArray(bridgeIncomingMessage.from)));
|
|
1520
|
+
}
|
|
1521
|
+
catch (err) {
|
|
1522
|
+
(_b = this.analytics) === null || _b === void 0 ? void 0 : _b.emitBridgeClientMessageDecodeError({
|
|
1523
|
+
bridge_url: this.session.bridgeUrl,
|
|
1524
|
+
client_id: this.session.sessionCrypto.sessionId,
|
|
1525
|
+
wallet_id: bridgeIncomingMessage.from,
|
|
1526
|
+
error_message: String(err),
|
|
1527
|
+
trace_id: bridgeIncomingMessage === null || bridgeIncomingMessage === void 0 ? void 0 : bridgeIncomingMessage.traceId
|
|
1528
|
+
});
|
|
1529
|
+
throw err;
|
|
1530
|
+
}
|
|
1264
1531
|
logDebug('Wallet message received:', walletMessage);
|
|
1532
|
+
const requestType = 'event' in walletMessage ? walletMessage.event : '';
|
|
1533
|
+
(_c = this.analytics) === null || _c === void 0 ? void 0 : _c.emitBridgeClientMessageReceived({
|
|
1534
|
+
bridge_url: this.session.bridgeUrl,
|
|
1535
|
+
client_id: this.session.sessionCrypto.sessionId,
|
|
1536
|
+
wallet_id: bridgeIncomingMessage.from,
|
|
1537
|
+
message_id: String(walletMessage.id),
|
|
1538
|
+
request_type: requestType,
|
|
1539
|
+
trace_id: bridgeIncomingMessage === null || bridgeIncomingMessage === void 0 ? void 0 : bridgeIncomingMessage.traceId
|
|
1540
|
+
});
|
|
1265
1541
|
if (!('event' in walletMessage)) {
|
|
1266
1542
|
const id = walletMessage.id.toString();
|
|
1267
1543
|
const resolve = this.pendingRequests.get(id);
|
|
@@ -1269,7 +1545,7 @@ class BridgeProvider {
|
|
|
1269
1545
|
logDebug(`Response id ${id} doesn't match any request's id`);
|
|
1270
1546
|
return;
|
|
1271
1547
|
}
|
|
1272
|
-
resolve(walletMessage);
|
|
1548
|
+
resolve(Object.assign(Object.assign({}, walletMessage), { traceId }));
|
|
1273
1549
|
this.pendingRequests.delete(id);
|
|
1274
1550
|
return;
|
|
1275
1551
|
}
|
|
@@ -1292,7 +1568,7 @@ class BridgeProvider {
|
|
|
1292
1568
|
logDebug(`Removing bridge and session: received disconnect event`);
|
|
1293
1569
|
yield this.removeBridgeAndSession();
|
|
1294
1570
|
}
|
|
1295
|
-
listeners.forEach(listener => listener(walletMessage));
|
|
1571
|
+
listeners.forEach(listener => listener(Object.assign(Object.assign({}, walletMessage), { traceId })));
|
|
1296
1572
|
});
|
|
1297
1573
|
}
|
|
1298
1574
|
gatewayErrorsListener(e) {
|
|
@@ -1320,21 +1596,22 @@ class BridgeProvider {
|
|
|
1320
1596
|
yield this.connectionStorage.removeConnection();
|
|
1321
1597
|
});
|
|
1322
1598
|
}
|
|
1323
|
-
generateUniversalLink(universalLink, message) {
|
|
1599
|
+
generateUniversalLink(universalLink, message, options) {
|
|
1324
1600
|
if (isTelegramUrl(universalLink)) {
|
|
1325
|
-
return this.generateTGUniversalLink(universalLink, message);
|
|
1601
|
+
return this.generateTGUniversalLink(universalLink, message, options);
|
|
1326
1602
|
}
|
|
1327
|
-
return this.generateRegularUniversalLink(universalLink, message);
|
|
1603
|
+
return this.generateRegularUniversalLink(universalLink, message, options);
|
|
1328
1604
|
}
|
|
1329
|
-
generateRegularUniversalLink(universalLink, message) {
|
|
1605
|
+
generateRegularUniversalLink(universalLink, message, options) {
|
|
1330
1606
|
const url = new URL(universalLink);
|
|
1331
1607
|
url.searchParams.append('v', PROTOCOL_VERSION.toString());
|
|
1332
1608
|
url.searchParams.append('id', this.session.sessionCrypto.sessionId);
|
|
1609
|
+
url.searchParams.append('trace_id', options.traceId);
|
|
1333
1610
|
url.searchParams.append('r', JSON.stringify(message));
|
|
1334
1611
|
return url.toString();
|
|
1335
1612
|
}
|
|
1336
|
-
generateTGUniversalLink(universalLink, message) {
|
|
1337
|
-
const urlToWrap = this.generateRegularUniversalLink('about:blank', message);
|
|
1613
|
+
generateTGUniversalLink(universalLink, message, options) {
|
|
1614
|
+
const urlToWrap = this.generateRegularUniversalLink('about:blank', message, options);
|
|
1338
1615
|
const linkParams = urlToWrap.split('?')[1];
|
|
1339
1616
|
const startapp = 'tonconnect-' + encodeTelegramUrlParameters(linkParams);
|
|
1340
1617
|
// TODO: Remove this line after all dApps and the wallets-list.json have been updated
|
|
@@ -1354,12 +1631,14 @@ class BridgeProvider {
|
|
|
1354
1631
|
}
|
|
1355
1632
|
openGateways(sessionCrypto, options) {
|
|
1356
1633
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1634
|
+
var _a;
|
|
1635
|
+
const traceId = (_a = options === null || options === void 0 ? void 0 : options.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
1357
1636
|
if (Array.isArray(this.walletConnectionSource)) {
|
|
1358
1637
|
// close all gateways before opening new ones
|
|
1359
1638
|
this.pendingGateways.map(bridge => bridge.close().catch());
|
|
1360
1639
|
// open new gateways
|
|
1361
1640
|
this.pendingGateways = this.walletConnectionSource.map(source => {
|
|
1362
|
-
const gateway = new BridgeGateway(this.storage, source.bridgeUrl, sessionCrypto.sessionId, () => { }, () => { });
|
|
1641
|
+
const gateway = new BridgeGateway(this.storage, source.bridgeUrl, sessionCrypto.sessionId, () => { }, () => { }, this.analyticsManager);
|
|
1363
1642
|
gateway.setListener(message => this.pendingGatewaysListener(gateway, source.bridgeUrl, message));
|
|
1364
1643
|
return gateway;
|
|
1365
1644
|
});
|
|
@@ -1370,7 +1649,8 @@ class BridgeProvider {
|
|
|
1370
1649
|
}
|
|
1371
1650
|
return bridge.registerSession({
|
|
1372
1651
|
openingDeadlineMS: (_a = options === null || options === void 0 ? void 0 : options.openingDeadlineMS) !== null && _a !== void 0 ? _a : this.defaultOpeningDeadlineMS,
|
|
1373
|
-
signal: _options.signal
|
|
1652
|
+
signal: _options.signal,
|
|
1653
|
+
traceId
|
|
1374
1654
|
});
|
|
1375
1655
|
}, {
|
|
1376
1656
|
attempts: Number.MAX_SAFE_INTEGER,
|
|
@@ -1384,10 +1664,11 @@ class BridgeProvider {
|
|
|
1384
1664
|
logDebug(`Gateway is already opened, closing previous gateway`);
|
|
1385
1665
|
yield this.gateway.close();
|
|
1386
1666
|
}
|
|
1387
|
-
this.gateway = new BridgeGateway(this.storage, this.walletConnectionSource.bridgeUrl, sessionCrypto.sessionId, this.gatewayListener.bind(this), this.gatewayErrorsListener.bind(this));
|
|
1667
|
+
this.gateway = new BridgeGateway(this.storage, this.walletConnectionSource.bridgeUrl, sessionCrypto.sessionId, this.gatewayListener.bind(this), this.gatewayErrorsListener.bind(this), this.analyticsManager);
|
|
1388
1668
|
return yield this.gateway.registerSession({
|
|
1389
1669
|
openingDeadlineMS: options === null || options === void 0 ? void 0 : options.openingDeadlineMS,
|
|
1390
|
-
signal: options === null || options === void 0 ? void 0 : options.signal
|
|
1670
|
+
signal: options === null || options === void 0 ? void 0 : options.signal,
|
|
1671
|
+
traceId
|
|
1391
1672
|
});
|
|
1392
1673
|
}
|
|
1393
1674
|
});
|
|
@@ -1490,6 +1771,15 @@ function getWebPageManifest() {
|
|
|
1490
1771
|
}
|
|
1491
1772
|
return '';
|
|
1492
1773
|
}
|
|
1774
|
+
function getOriginWithPath() {
|
|
1775
|
+
var _a, _b, _c, _d;
|
|
1776
|
+
const origin = (_b = (_a = getWindow()) === null || _a === void 0 ? void 0 : _a.location) === null || _b === void 0 ? void 0 : _b.origin;
|
|
1777
|
+
const path = (_d = (_c = getWindow()) === null || _c === void 0 ? void 0 : _c.location) === null || _d === void 0 ? void 0 : _d.pathname;
|
|
1778
|
+
if (origin && path) {
|
|
1779
|
+
return origin + path;
|
|
1780
|
+
}
|
|
1781
|
+
return '';
|
|
1782
|
+
}
|
|
1493
1783
|
/**
|
|
1494
1784
|
* Returns `localStorage` if it is available. In Safari's private mode, it returns `InMemoryStorage`. In Node.js, it throws an error.
|
|
1495
1785
|
*/
|
|
@@ -1559,11 +1849,11 @@ function getWindowEntries() {
|
|
|
1559
1849
|
}
|
|
1560
1850
|
|
|
1561
1851
|
class InjectedProvider {
|
|
1562
|
-
static fromStorage(storage) {
|
|
1852
|
+
static fromStorage(storage, analyticsManager) {
|
|
1563
1853
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1564
1854
|
const bridgeConnectionStorage = new BridgeConnectionStorage(storage);
|
|
1565
1855
|
const connection = yield bridgeConnectionStorage.getInjectedConnection();
|
|
1566
|
-
return new InjectedProvider(storage, connection.jsBridgeKey);
|
|
1856
|
+
return new InjectedProvider(storage, connection.jsBridgeKey, analyticsManager);
|
|
1567
1857
|
});
|
|
1568
1858
|
}
|
|
1569
1859
|
static isWalletInjected(injectedWalletKey) {
|
|
@@ -1600,7 +1890,7 @@ class InjectedProvider {
|
|
|
1600
1890
|
typeof window[injectedWalletKey] === 'object' &&
|
|
1601
1891
|
'tonconnect' in window[injectedWalletKey]);
|
|
1602
1892
|
}
|
|
1603
|
-
constructor(storage, injectedWalletKey) {
|
|
1893
|
+
constructor(storage, injectedWalletKey, analyticsManager) {
|
|
1604
1894
|
this.injectedWalletKey = injectedWalletKey;
|
|
1605
1895
|
this.type = 'injected';
|
|
1606
1896
|
this.unsubscribeCallback = null;
|
|
@@ -1612,25 +1902,49 @@ class InjectedProvider {
|
|
|
1612
1902
|
}
|
|
1613
1903
|
this.connectionStorage = new BridgeConnectionStorage(storage);
|
|
1614
1904
|
this.injectedWallet = window[injectedWalletKey].tonconnect;
|
|
1905
|
+
if (analyticsManager) {
|
|
1906
|
+
this.analytics = analyticsManager.scoped({
|
|
1907
|
+
bridge_key: injectedWalletKey,
|
|
1908
|
+
wallet_app_name: this.injectedWallet.deviceInfo.appName,
|
|
1909
|
+
wallet_app_version: this.injectedWallet.deviceInfo.appVersion
|
|
1910
|
+
});
|
|
1911
|
+
}
|
|
1615
1912
|
}
|
|
1616
|
-
connect(message) {
|
|
1617
|
-
this._connect(PROTOCOL_VERSION, message);
|
|
1913
|
+
connect(message, options) {
|
|
1914
|
+
this._connect(PROTOCOL_VERSION, message, options);
|
|
1618
1915
|
}
|
|
1619
|
-
restoreConnection() {
|
|
1916
|
+
restoreConnection(options) {
|
|
1620
1917
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1918
|
+
var _a, _b, _c, _d;
|
|
1919
|
+
const traceId = (_a = options === null || options === void 0 ? void 0 : options.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
1621
1920
|
try {
|
|
1622
1921
|
logDebug(`Injected Provider restoring connection...`);
|
|
1623
|
-
|
|
1922
|
+
(_b = this.analytics) === null || _b === void 0 ? void 0 : _b.emitJsBridgeCall({
|
|
1923
|
+
js_bridge_method: 'restoreConnection',
|
|
1924
|
+
trace_id: traceId
|
|
1925
|
+
});
|
|
1926
|
+
const connectEvent = yield this.injectedWallet.restoreConnection({
|
|
1927
|
+
traceId
|
|
1928
|
+
});
|
|
1929
|
+
(_c = this.analytics) === null || _c === void 0 ? void 0 : _c.emitJsBridgeResponse({
|
|
1930
|
+
js_bridge_method: 'restoreConnection',
|
|
1931
|
+
trace_id: traceId
|
|
1932
|
+
});
|
|
1624
1933
|
logDebug('Injected Provider restoring connection response', connectEvent);
|
|
1625
1934
|
if (connectEvent.event === 'connect') {
|
|
1626
|
-
this.makeSubscriptions();
|
|
1627
|
-
this.listeners.forEach(listener => listener(connectEvent));
|
|
1935
|
+
this.makeSubscriptions({ traceId });
|
|
1936
|
+
this.listeners.forEach(listener => listener(Object.assign(Object.assign({}, connectEvent), { traceId })));
|
|
1628
1937
|
}
|
|
1629
1938
|
else {
|
|
1630
1939
|
yield this.connectionStorage.removeConnection();
|
|
1631
1940
|
}
|
|
1632
1941
|
}
|
|
1633
1942
|
catch (e) {
|
|
1943
|
+
(_d = this.analytics) === null || _d === void 0 ? void 0 : _d.emitJsBridgeError({
|
|
1944
|
+
js_bridge_method: 'restoreConnection',
|
|
1945
|
+
error_message: String(e),
|
|
1946
|
+
trace_id: traceId
|
|
1947
|
+
});
|
|
1634
1948
|
yield this.connectionStorage.removeConnection();
|
|
1635
1949
|
console.error(e);
|
|
1636
1950
|
}
|
|
@@ -1642,8 +1956,10 @@ class InjectedProvider {
|
|
|
1642
1956
|
}
|
|
1643
1957
|
this.closeAllListeners();
|
|
1644
1958
|
}
|
|
1645
|
-
disconnect() {
|
|
1959
|
+
disconnect(options) {
|
|
1646
1960
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1961
|
+
var _a;
|
|
1962
|
+
const traceId = (_a = options === null || options === void 0 ? void 0 : options.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
1647
1963
|
return new Promise(resolve => {
|
|
1648
1964
|
const onRequestSent = () => {
|
|
1649
1965
|
this.closeAllListeners();
|
|
@@ -1658,7 +1974,7 @@ class InjectedProvider {
|
|
|
1658
1974
|
this.sendRequest({
|
|
1659
1975
|
method: 'disconnect',
|
|
1660
1976
|
params: []
|
|
1661
|
-
}, onRequestSent);
|
|
1977
|
+
}, { onRequestSent, traceId });
|
|
1662
1978
|
}
|
|
1663
1979
|
});
|
|
1664
1980
|
});
|
|
@@ -1675,38 +1991,76 @@ class InjectedProvider {
|
|
|
1675
1991
|
}
|
|
1676
1992
|
sendRequest(request, optionsOrOnRequestSent) {
|
|
1677
1993
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1678
|
-
var _a;
|
|
1994
|
+
var _a, _b, _c;
|
|
1679
1995
|
// TODO: remove deprecated method
|
|
1680
1996
|
const options = {};
|
|
1681
1997
|
if (typeof optionsOrOnRequestSent === 'function') {
|
|
1682
1998
|
options.onRequestSent = optionsOrOnRequestSent;
|
|
1999
|
+
options.traceId = UUIDv7();
|
|
1683
2000
|
}
|
|
1684
2001
|
else {
|
|
1685
2002
|
options.onRequestSent = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.onRequestSent;
|
|
1686
2003
|
options.signal = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.signal;
|
|
2004
|
+
options.attempts = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.attempts;
|
|
2005
|
+
options.traceId = (_a = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
1687
2006
|
}
|
|
1688
2007
|
const id = (yield this.connectionStorage.getNextRpcRequestId()).toString();
|
|
1689
2008
|
yield this.connectionStorage.increaseNextRpcRequestId();
|
|
1690
2009
|
logDebug('Send injected-bridge request:', Object.assign(Object.assign({}, request), { id }));
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
2010
|
+
(_b = this.analytics) === null || _b === void 0 ? void 0 : _b.emitJsBridgeCall({
|
|
2011
|
+
js_bridge_method: 'send'
|
|
2012
|
+
});
|
|
2013
|
+
const result = this.injectedWallet.send(Object.assign(Object.assign({}, request), { id }), {
|
|
2014
|
+
traceId: options.traceId
|
|
2015
|
+
});
|
|
2016
|
+
result
|
|
2017
|
+
.then(response => {
|
|
2018
|
+
var _a;
|
|
2019
|
+
(_a = this.analytics) === null || _a === void 0 ? void 0 : _a.emitJsBridgeResponse({
|
|
2020
|
+
js_bridge_method: 'send'
|
|
2021
|
+
});
|
|
2022
|
+
logDebug('Wallet message received:', response);
|
|
2023
|
+
})
|
|
2024
|
+
.catch(error => {
|
|
2025
|
+
var _a;
|
|
2026
|
+
(_a = this.analytics) === null || _a === void 0 ? void 0 : _a.emitJsBridgeError({
|
|
2027
|
+
js_bridge_method: 'send',
|
|
2028
|
+
error_message: String(error)
|
|
2029
|
+
});
|
|
2030
|
+
});
|
|
2031
|
+
(_c = options === null || options === void 0 ? void 0 : options.onRequestSent) === null || _c === void 0 ? void 0 : _c.call(options);
|
|
1694
2032
|
return result;
|
|
1695
2033
|
});
|
|
1696
2034
|
}
|
|
1697
|
-
_connect(protocolVersion, message) {
|
|
2035
|
+
_connect(protocolVersion, message, options) {
|
|
1698
2036
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2037
|
+
var _a, _b, _c, _d;
|
|
2038
|
+
const traceId = (_a = options === null || options === void 0 ? void 0 : options.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
1699
2039
|
try {
|
|
1700
2040
|
logDebug(`Injected Provider connect request: protocolVersion: ${protocolVersion}, message:`, message);
|
|
1701
|
-
|
|
2041
|
+
(_b = this.analytics) === null || _b === void 0 ? void 0 : _b.emitJsBridgeCall({
|
|
2042
|
+
js_bridge_method: 'connect',
|
|
2043
|
+
trace_id: traceId
|
|
2044
|
+
});
|
|
2045
|
+
const connectEvent = yield this.injectedWallet.connect(protocolVersion, message, {
|
|
2046
|
+
traceId
|
|
2047
|
+
});
|
|
2048
|
+
(_c = this.analytics) === null || _c === void 0 ? void 0 : _c.emitJsBridgeResponse({
|
|
2049
|
+
js_bridge_method: 'connect'
|
|
2050
|
+
});
|
|
1702
2051
|
logDebug('Injected Provider connect response:', connectEvent);
|
|
1703
2052
|
if (connectEvent.event === 'connect') {
|
|
1704
2053
|
yield this.updateSession();
|
|
1705
|
-
this.makeSubscriptions();
|
|
2054
|
+
this.makeSubscriptions({ traceId });
|
|
1706
2055
|
}
|
|
1707
|
-
this.listeners.forEach(listener => listener(connectEvent));
|
|
2056
|
+
this.listeners.forEach(listener => listener(Object.assign(Object.assign({}, connectEvent), { traceId })));
|
|
1708
2057
|
}
|
|
1709
2058
|
catch (e) {
|
|
2059
|
+
(_d = this.analytics) === null || _d === void 0 ? void 0 : _d.emitJsBridgeError({
|
|
2060
|
+
js_bridge_method: 'connect',
|
|
2061
|
+
error_message: String(e),
|
|
2062
|
+
trace_id: traceId
|
|
2063
|
+
});
|
|
1710
2064
|
logDebug('Injected Provider connect error:', e);
|
|
1711
2065
|
const connectEventError = {
|
|
1712
2066
|
event: 'connect_error',
|
|
@@ -1715,21 +2069,42 @@ class InjectedProvider {
|
|
|
1715
2069
|
message: e === null || e === void 0 ? void 0 : e.toString()
|
|
1716
2070
|
}
|
|
1717
2071
|
};
|
|
1718
|
-
this.listeners.forEach(listener => listener(connectEventError));
|
|
2072
|
+
this.listeners.forEach(listener => listener(Object.assign(Object.assign({}, connectEventError), { traceId })));
|
|
1719
2073
|
}
|
|
1720
2074
|
});
|
|
1721
2075
|
}
|
|
1722
|
-
makeSubscriptions() {
|
|
2076
|
+
makeSubscriptions(options) {
|
|
2077
|
+
var _a, _b, _c;
|
|
1723
2078
|
this.listenSubscriptions = true;
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
this.listeners.forEach(listener => listener(e));
|
|
1728
|
-
}
|
|
1729
|
-
if (e.event === 'disconnect') {
|
|
1730
|
-
this.disconnect();
|
|
1731
|
-
}
|
|
2079
|
+
(_a = this.analytics) === null || _a === void 0 ? void 0 : _a.emitJsBridgeCall({
|
|
2080
|
+
js_bridge_method: 'listen',
|
|
2081
|
+
trace_id: options.traceId
|
|
1732
2082
|
});
|
|
2083
|
+
try {
|
|
2084
|
+
this.unsubscribeCallback = this.injectedWallet.listen(e => {
|
|
2085
|
+
var _a;
|
|
2086
|
+
const traceId = (_a = e.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
2087
|
+
logDebug('Wallet message received:', e);
|
|
2088
|
+
if (this.listenSubscriptions) {
|
|
2089
|
+
this.listeners.forEach(listener => listener(Object.assign(Object.assign({}, e), { traceId })));
|
|
2090
|
+
}
|
|
2091
|
+
if (e.event === 'disconnect') {
|
|
2092
|
+
this.disconnect({ traceId });
|
|
2093
|
+
}
|
|
2094
|
+
});
|
|
2095
|
+
(_b = this.analytics) === null || _b === void 0 ? void 0 : _b.emitJsBridgeResponse({
|
|
2096
|
+
js_bridge_method: 'listen',
|
|
2097
|
+
trace_id: options.traceId
|
|
2098
|
+
});
|
|
2099
|
+
}
|
|
2100
|
+
catch (err) {
|
|
2101
|
+
(_c = this.analytics) === null || _c === void 0 ? void 0 : _c.emitJsBridgeError({
|
|
2102
|
+
js_bridge_method: 'listen',
|
|
2103
|
+
error_message: String(err),
|
|
2104
|
+
trace_id: options.traceId
|
|
2105
|
+
});
|
|
2106
|
+
throw err;
|
|
2107
|
+
}
|
|
1733
2108
|
}
|
|
1734
2109
|
updateSession() {
|
|
1735
2110
|
return this.connectionStorage.storeConnection({
|
|
@@ -2974,77 +3349,91 @@ function createVersionInfo(version) {
|
|
|
2974
3349
|
ton_connect_ui_lib: version.ton_connect_ui_lib
|
|
2975
3350
|
};
|
|
2976
3351
|
}
|
|
2977
|
-
|
|
2978
|
-
|
|
3352
|
+
// eslint-disable-next-line complexity
|
|
3353
|
+
function createConnectionInfo(version, wallet, sessionInfo) {
|
|
3354
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
2979
3355
|
const isTonProof = ((_a = wallet === null || wallet === void 0 ? void 0 : wallet.connectItems) === null || _a === void 0 ? void 0 : _a.tonProof) && 'proof' in wallet.connectItems.tonProof;
|
|
2980
3356
|
const authType = isTonProof ? 'ton_proof' : 'ton_addr';
|
|
2981
3357
|
return {
|
|
2982
3358
|
wallet_address: (_c = (_b = wallet === null || wallet === void 0 ? void 0 : wallet.account) === null || _b === void 0 ? void 0 : _b.address) !== null && _c !== void 0 ? _c : null,
|
|
2983
|
-
|
|
2984
|
-
|
|
3359
|
+
wallet_state_init: (_d = wallet === null || wallet === void 0 ? void 0 : wallet.account.walletStateInit) !== null && _d !== void 0 ? _d : null,
|
|
3360
|
+
wallet_type: (_e = wallet === null || wallet === void 0 ? void 0 : wallet.device.appName) !== null && _e !== void 0 ? _e : null,
|
|
3361
|
+
wallet_version: (_f = wallet === null || wallet === void 0 ? void 0 : wallet.device.appVersion) !== null && _f !== void 0 ? _f : null,
|
|
2985
3362
|
auth_type: authType,
|
|
2986
|
-
custom_data: Object.assign({
|
|
3363
|
+
custom_data: Object.assign({ client_id: (_g = sessionInfo === null || sessionInfo === void 0 ? void 0 : sessionInfo.clientId) !== null && _g !== void 0 ? _g : null, wallet_id: (_h = sessionInfo === null || sessionInfo === void 0 ? void 0 : sessionInfo.walletId) !== null && _h !== void 0 ? _h : null, chain_id: (_k = (_j = wallet === null || wallet === void 0 ? void 0 : wallet.account) === null || _j === void 0 ? void 0 : _j.chain) !== null && _k !== void 0 ? _k : null, provider: (_l = wallet === null || wallet === void 0 ? void 0 : wallet.provider) !== null && _l !== void 0 ? _l : null }, createVersionInfo(version))
|
|
2987
3364
|
};
|
|
2988
3365
|
}
|
|
2989
3366
|
/**
|
|
2990
3367
|
* Create a connection init event.
|
|
2991
3368
|
*/
|
|
2992
|
-
function createConnectionStartedEvent(version) {
|
|
3369
|
+
function createConnectionStartedEvent(version, traceId) {
|
|
2993
3370
|
return {
|
|
2994
3371
|
type: 'connection-started',
|
|
2995
|
-
custom_data: createVersionInfo(version)
|
|
3372
|
+
custom_data: createVersionInfo(version),
|
|
3373
|
+
trace_id: traceId !== null && traceId !== void 0 ? traceId : null
|
|
2996
3374
|
};
|
|
2997
3375
|
}
|
|
2998
3376
|
/**
|
|
2999
3377
|
* Create a connection completed event.
|
|
3000
3378
|
* @param version
|
|
3001
3379
|
* @param wallet
|
|
3380
|
+
* @param sessionInfo
|
|
3381
|
+
* @param traceId
|
|
3002
3382
|
*/
|
|
3003
|
-
function createConnectionCompletedEvent(version, wallet) {
|
|
3004
|
-
return Object.assign({ type: 'connection-completed', is_success: true }, createConnectionInfo(version, wallet));
|
|
3383
|
+
function createConnectionCompletedEvent(version, wallet, sessionInfo, traceId) {
|
|
3384
|
+
return Object.assign({ type: 'connection-completed', is_success: true, trace_id: traceId !== null && traceId !== void 0 ? traceId : null }, createConnectionInfo(version, wallet, sessionInfo));
|
|
3005
3385
|
}
|
|
3006
3386
|
/**
|
|
3007
3387
|
* Create a connection error event.
|
|
3008
3388
|
* @param version
|
|
3009
3389
|
* @param error_message
|
|
3010
3390
|
* @param errorCode
|
|
3391
|
+
* @param sessionInfo
|
|
3392
|
+
* @param traceId
|
|
3011
3393
|
*/
|
|
3012
|
-
function createConnectionErrorEvent(version, error_message, errorCode) {
|
|
3394
|
+
function createConnectionErrorEvent(version, error_message, errorCode, sessionInfo, traceId) {
|
|
3395
|
+
var _a, _b;
|
|
3013
3396
|
return {
|
|
3014
3397
|
type: 'connection-error',
|
|
3015
3398
|
is_success: false,
|
|
3016
3399
|
error_message: error_message,
|
|
3017
3400
|
error_code: errorCode !== null && errorCode !== void 0 ? errorCode : null,
|
|
3018
|
-
|
|
3401
|
+
trace_id: traceId !== null && traceId !== void 0 ? traceId : null,
|
|
3402
|
+
custom_data: Object.assign({ client_id: (_a = sessionInfo === null || sessionInfo === void 0 ? void 0 : sessionInfo.clientId) !== null && _a !== void 0 ? _a : null, wallet_id: (_b = sessionInfo === null || sessionInfo === void 0 ? void 0 : sessionInfo.walletId) !== null && _b !== void 0 ? _b : null }, createVersionInfo(version))
|
|
3019
3403
|
};
|
|
3020
3404
|
}
|
|
3021
3405
|
/**
|
|
3022
3406
|
* Create a connection restoring started event.
|
|
3023
3407
|
*/
|
|
3024
|
-
function createConnectionRestoringStartedEvent(version) {
|
|
3408
|
+
function createConnectionRestoringStartedEvent(version, traceId) {
|
|
3025
3409
|
return {
|
|
3026
3410
|
type: 'connection-restoring-started',
|
|
3027
|
-
custom_data: createVersionInfo(version)
|
|
3411
|
+
custom_data: createVersionInfo(version),
|
|
3412
|
+
trace_id: traceId !== null && traceId !== void 0 ? traceId : null
|
|
3028
3413
|
};
|
|
3029
3414
|
}
|
|
3030
3415
|
/**
|
|
3031
3416
|
* Create a connection restoring completed event.
|
|
3032
3417
|
* @param version
|
|
3033
3418
|
* @param wallet
|
|
3419
|
+
* @param sessionInfo
|
|
3420
|
+
* @param traceId
|
|
3034
3421
|
*/
|
|
3035
|
-
function createConnectionRestoringCompletedEvent(version, wallet) {
|
|
3036
|
-
return Object.assign({ type: 'connection-restoring-completed', is_success: true }, createConnectionInfo(version, wallet));
|
|
3422
|
+
function createConnectionRestoringCompletedEvent(version, wallet, sessionInfo, traceId) {
|
|
3423
|
+
return Object.assign({ type: 'connection-restoring-completed', is_success: true, trace_id: traceId !== null && traceId !== void 0 ? traceId : null }, createConnectionInfo(version, wallet, sessionInfo));
|
|
3037
3424
|
}
|
|
3038
3425
|
/**
|
|
3039
3426
|
* Create a connection restoring error event.
|
|
3040
3427
|
* @param version
|
|
3041
3428
|
* @param errorMessage
|
|
3429
|
+
* @param traceId
|
|
3042
3430
|
*/
|
|
3043
|
-
function createConnectionRestoringErrorEvent(version, errorMessage) {
|
|
3431
|
+
function createConnectionRestoringErrorEvent(version, errorMessage, traceId) {
|
|
3044
3432
|
return {
|
|
3045
3433
|
type: 'connection-restoring-error',
|
|
3046
3434
|
is_success: false,
|
|
3047
3435
|
error_message: errorMessage,
|
|
3436
|
+
trace_id: traceId !== null && traceId !== void 0 ? traceId : null,
|
|
3048
3437
|
custom_data: createVersionInfo(version)
|
|
3049
3438
|
};
|
|
3050
3439
|
}
|
|
@@ -3062,14 +3451,32 @@ function createTransactionInfo(wallet, transaction) {
|
|
|
3062
3451
|
})
|
|
3063
3452
|
};
|
|
3064
3453
|
}
|
|
3454
|
+
function createTransactionFullInfo(wallet, transaction) {
|
|
3455
|
+
var _a, _b, _c, _d;
|
|
3456
|
+
return {
|
|
3457
|
+
valid_until: (_a = String(transaction.validUntil)) !== null && _a !== void 0 ? _a : null,
|
|
3458
|
+
from: (_d = (_b = transaction.from) !== null && _b !== void 0 ? _b : (_c = wallet === null || wallet === void 0 ? void 0 : wallet.account) === null || _c === void 0 ? void 0 : _c.address) !== null && _d !== void 0 ? _d : null,
|
|
3459
|
+
messages: transaction.messages.map(message => {
|
|
3460
|
+
var _a, _b, _c, _d;
|
|
3461
|
+
return ({
|
|
3462
|
+
address: (_a = message.address) !== null && _a !== void 0 ? _a : null,
|
|
3463
|
+
amount: (_b = message.amount) !== null && _b !== void 0 ? _b : null,
|
|
3464
|
+
payload: (_c = message.payload) !== null && _c !== void 0 ? _c : null,
|
|
3465
|
+
state_init: (_d = message.stateInit) !== null && _d !== void 0 ? _d : null
|
|
3466
|
+
});
|
|
3467
|
+
})
|
|
3468
|
+
};
|
|
3469
|
+
}
|
|
3065
3470
|
/**
|
|
3066
3471
|
* Create a transaction init event.
|
|
3067
3472
|
* @param version
|
|
3068
3473
|
* @param wallet
|
|
3069
3474
|
* @param transaction
|
|
3475
|
+
* @param sessionInfo
|
|
3476
|
+
* @param traceId
|
|
3070
3477
|
*/
|
|
3071
|
-
function createTransactionSentForSignatureEvent(version, wallet, transaction) {
|
|
3072
|
-
return Object.assign(Object.assign({ type: 'transaction-sent-for-signature' }, createConnectionInfo(version, wallet)), createTransactionInfo(wallet, transaction));
|
|
3478
|
+
function createTransactionSentForSignatureEvent(version, wallet, transaction, sessionInfo, traceId) {
|
|
3479
|
+
return Object.assign(Object.assign({ type: 'transaction-sent-for-signature', trace_id: traceId !== null && traceId !== void 0 ? traceId : null }, createConnectionInfo(version, wallet, sessionInfo)), createTransactionInfo(wallet, transaction));
|
|
3073
3480
|
}
|
|
3074
3481
|
/**
|
|
3075
3482
|
* Create a transaction signed event.
|
|
@@ -3077,9 +3484,11 @@ function createTransactionSentForSignatureEvent(version, wallet, transaction) {
|
|
|
3077
3484
|
* @param wallet
|
|
3078
3485
|
* @param transaction
|
|
3079
3486
|
* @param signedTransaction
|
|
3487
|
+
* @param sessionInfo
|
|
3488
|
+
* @param traceId
|
|
3080
3489
|
*/
|
|
3081
|
-
function createTransactionSignedEvent(version, wallet, transaction, signedTransaction) {
|
|
3082
|
-
return Object.assign(Object.assign({ type: 'transaction-signed', is_success: true, signed_transaction: signedTransaction.boc }, createConnectionInfo(version, wallet)), createTransactionInfo(wallet, transaction));
|
|
3490
|
+
function createTransactionSignedEvent(version, wallet, transaction, signedTransaction, sessionInfo, traceId) {
|
|
3491
|
+
return Object.assign(Object.assign({ type: 'transaction-signed', is_success: true, signed_transaction: signedTransaction.boc, trace_id: traceId !== null && traceId !== void 0 ? traceId : null }, createConnectionInfo(version, wallet, sessionInfo)), createTransactionInfo(wallet, transaction));
|
|
3083
3492
|
}
|
|
3084
3493
|
/**
|
|
3085
3494
|
* Create a transaction error event.
|
|
@@ -3088,71 +3497,50 @@ function createTransactionSignedEvent(version, wallet, transaction, signedTransa
|
|
|
3088
3497
|
* @param transaction
|
|
3089
3498
|
* @param errorMessage
|
|
3090
3499
|
* @param errorCode
|
|
3500
|
+
* @param sessionInfo
|
|
3501
|
+
* @param traceId
|
|
3091
3502
|
*/
|
|
3092
|
-
function createTransactionSigningFailedEvent(version, wallet, transaction, errorMessage, errorCode) {
|
|
3093
|
-
return Object.assign(Object.assign({ type: 'transaction-signing-failed', is_success: false, error_message: errorMessage, error_code: errorCode !== null && errorCode !== void 0 ? errorCode : null }, createConnectionInfo(version, wallet)),
|
|
3503
|
+
function createTransactionSigningFailedEvent(version, wallet, transaction, errorMessage, errorCode, sessionInfo, traceId) {
|
|
3504
|
+
return Object.assign(Object.assign({ type: 'transaction-signing-failed', is_success: false, error_message: errorMessage, error_code: errorCode !== null && errorCode !== void 0 ? errorCode : null, trace_id: traceId !== null && traceId !== void 0 ? traceId : null }, createConnectionInfo(version, wallet, sessionInfo)), createTransactionFullInfo(wallet, transaction));
|
|
3094
3505
|
}
|
|
3095
|
-
function createDataSentForSignatureEvent(version, wallet, data) {
|
|
3096
|
-
return Object.assign({ type: 'sign-data-request-initiated', data }, createConnectionInfo(version, wallet));
|
|
3506
|
+
function createDataSentForSignatureEvent(version, wallet, data, sessionInfo, traceId) {
|
|
3507
|
+
return Object.assign({ type: 'sign-data-request-initiated', data, trace_id: traceId !== null && traceId !== void 0 ? traceId : null }, createConnectionInfo(version, wallet, sessionInfo));
|
|
3097
3508
|
}
|
|
3098
|
-
function createDataSignedEvent(version, wallet, data, signedData) {
|
|
3099
|
-
return Object.assign({ type: 'sign-data-request-completed', is_success: true, data, signed_data: signedData }, createConnectionInfo(version, wallet));
|
|
3509
|
+
function createDataSignedEvent(version, wallet, data, signedData, sessionInfo, traceId) {
|
|
3510
|
+
return Object.assign({ type: 'sign-data-request-completed', is_success: true, data, signed_data: signedData, trace_id: traceId !== null && traceId !== void 0 ? traceId : null }, createConnectionInfo(version, wallet, sessionInfo));
|
|
3100
3511
|
}
|
|
3101
|
-
function createDataSigningFailedEvent(version, wallet, data, errorMessage, errorCode) {
|
|
3102
|
-
return Object.assign({ type: 'sign-data-request-failed', is_success: false, data, error_message: errorMessage, error_code: errorCode !== null && errorCode !== void 0 ? errorCode : null }, createConnectionInfo(version, wallet));
|
|
3512
|
+
function createDataSigningFailedEvent(version, wallet, data, errorMessage, errorCode, sessionInfo, traceId) {
|
|
3513
|
+
return Object.assign({ type: 'sign-data-request-failed', is_success: false, data, error_message: errorMessage, error_code: errorCode !== null && errorCode !== void 0 ? errorCode : null, trace_id: traceId !== null && traceId !== void 0 ? traceId : null }, createConnectionInfo(version, wallet, sessionInfo));
|
|
3103
3514
|
}
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
* @param version
|
|
3107
|
-
* @param wallet
|
|
3108
|
-
* @param scope
|
|
3109
|
-
* @returns
|
|
3110
|
-
*/
|
|
3111
|
-
function createDisconnectionEvent(version, wallet, scope) {
|
|
3112
|
-
return Object.assign({ type: 'disconnection', scope: scope }, createConnectionInfo(version, wallet));
|
|
3515
|
+
function createDisconnectionEvent(version, wallet, scope, sessionInfo, traceId) {
|
|
3516
|
+
return Object.assign({ type: 'disconnection', scope: scope, trace_id: traceId !== null && traceId !== void 0 ? traceId : null }, createConnectionInfo(version, wallet, sessionInfo));
|
|
3113
3517
|
}
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
* @param eventName - The name of the event to dispatch.
|
|
3129
|
-
* @param eventDetails - The details of the event to dispatch.
|
|
3130
|
-
* @returns A promise that resolves when the event has been dispatched.
|
|
3131
|
-
*/
|
|
3132
|
-
dispatchEvent(eventName, eventDetails) {
|
|
3133
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3134
|
-
var _a;
|
|
3135
|
-
const event = new CustomEvent(eventName, { detail: eventDetails });
|
|
3136
|
-
(_a = this.window) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
|
|
3137
|
-
});
|
|
3138
|
-
}
|
|
3139
|
-
/**
|
|
3140
|
-
* Adds an event listener to the browser window.
|
|
3141
|
-
* @param eventName - The name of the event to listen for.
|
|
3142
|
-
* @param listener - The listener to add.
|
|
3143
|
-
* @param options - The options for the listener.
|
|
3144
|
-
* @returns A function that removes the listener.
|
|
3145
|
-
*/
|
|
3146
|
-
addEventListener(eventName, listener, options) {
|
|
3147
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3148
|
-
var _a;
|
|
3149
|
-
(_a = this.window) === null || _a === void 0 ? void 0 : _a.addEventListener(eventName, listener, options);
|
|
3150
|
-
return () => {
|
|
3151
|
-
var _a;
|
|
3152
|
-
return (_a = this.window) === null || _a === void 0 ? void 0 : _a.removeEventListener(eventName, listener);
|
|
3153
|
-
};
|
|
3154
|
-
});
|
|
3518
|
+
function createWalletModalOpenedEvent(version, visibleWallets, clientId, traceId) {
|
|
3519
|
+
return {
|
|
3520
|
+
type: 'wallet-modal-opened',
|
|
3521
|
+
visible_wallets: visibleWallets,
|
|
3522
|
+
client_id: clientId !== null && clientId !== void 0 ? clientId : null,
|
|
3523
|
+
custom_data: version,
|
|
3524
|
+
trace_id: traceId !== null && traceId !== void 0 ? traceId : null
|
|
3525
|
+
};
|
|
3526
|
+
}
|
|
3527
|
+
function createSelectedWalletEvent(version, visibleWallets, lastSelectedWallet, walletsMenu, redirectLink, redirectLinkType, clientId, traceId) {
|
|
3528
|
+
var _a;
|
|
3529
|
+
let walletRedirectMethod = redirectLinkType;
|
|
3530
|
+
if (!walletRedirectMethod && redirectLink) {
|
|
3531
|
+
walletRedirectMethod = isTelegramUrl(redirectLink) ? 'tg_link' : 'external_link';
|
|
3155
3532
|
}
|
|
3533
|
+
return {
|
|
3534
|
+
type: 'selected-wallet',
|
|
3535
|
+
wallets_menu: walletsMenu,
|
|
3536
|
+
visible_wallets: visibleWallets,
|
|
3537
|
+
client_id: clientId !== null && clientId !== void 0 ? clientId : null,
|
|
3538
|
+
custom_data: version,
|
|
3539
|
+
trace_id: traceId !== null && traceId !== void 0 ? traceId : null,
|
|
3540
|
+
wallet_redirect_method: walletRedirectMethod,
|
|
3541
|
+
wallet_redirect_link: redirectLink || undefined,
|
|
3542
|
+
wallet_type: (_a = lastSelectedWallet === null || lastSelectedWallet === void 0 ? void 0 : lastSelectedWallet.appName) !== null && _a !== void 0 ? _a : null
|
|
3543
|
+
};
|
|
3156
3544
|
}
|
|
3157
3545
|
|
|
3158
3546
|
/**
|
|
@@ -3193,7 +3581,6 @@ class TonConnectTracker {
|
|
|
3193
3581
|
});
|
|
3194
3582
|
}
|
|
3195
3583
|
constructor(options) {
|
|
3196
|
-
var _a;
|
|
3197
3584
|
/**
|
|
3198
3585
|
* Event prefix for user actions.
|
|
3199
3586
|
* @private
|
|
@@ -3203,7 +3590,7 @@ class TonConnectTracker {
|
|
|
3203
3590
|
* TonConnect UI version.
|
|
3204
3591
|
*/
|
|
3205
3592
|
this.tonConnectUiVersion = null;
|
|
3206
|
-
this.eventDispatcher =
|
|
3593
|
+
this.eventDispatcher = options === null || options === void 0 ? void 0 : options.eventDispatcher;
|
|
3207
3594
|
this.tonConnectSdkVersion = options.tonConnectSdkVersion;
|
|
3208
3595
|
this.init().catch();
|
|
3209
3596
|
}
|
|
@@ -3407,7 +3794,7 @@ class TonConnectTracker {
|
|
|
3407
3794
|
}
|
|
3408
3795
|
}
|
|
3409
3796
|
|
|
3410
|
-
const tonConnectSdkVersion = "3.
|
|
3797
|
+
const tonConnectSdkVersion = "3.4.0-beta.1";
|
|
3411
3798
|
|
|
3412
3799
|
const bounceableTag = 0x11;
|
|
3413
3800
|
const noBounceableTag = 0x51;
|
|
@@ -3906,6 +4293,403 @@ function normalizeBase64(data) {
|
|
|
3906
4293
|
return data.replace(/-/g, '+').replace(/_/g, '/').padEnd(paddedLength, '=');
|
|
3907
4294
|
}
|
|
3908
4295
|
|
|
4296
|
+
/**
|
|
4297
|
+
* Converts a PascalCase (or camelCase) string to kebab-case.
|
|
4298
|
+
*
|
|
4299
|
+
* For example:
|
|
4300
|
+
* - "PascalCase" → "pascal-case"
|
|
4301
|
+
* - "camelCaseExample" → "camel-case-example"
|
|
4302
|
+
*
|
|
4303
|
+
* @param value - The input string in PascalCase or camelCase format.
|
|
4304
|
+
* @returns The converted kebab-case string.
|
|
4305
|
+
*/
|
|
4306
|
+
function pascalToKebab(value) {
|
|
4307
|
+
return value.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
4308
|
+
}
|
|
4309
|
+
|
|
4310
|
+
class AnalyticsManager {
|
|
4311
|
+
constructor(options = {}) {
|
|
4312
|
+
var _a, _b, _c, _d, _e;
|
|
4313
|
+
this.events = [];
|
|
4314
|
+
this.timeoutId = null;
|
|
4315
|
+
this.isProcessing = false;
|
|
4316
|
+
this.backoff = 1;
|
|
4317
|
+
this.shouldSend = true;
|
|
4318
|
+
this.batchTimeoutMs = (_a = options.batchTimeoutMs) !== null && _a !== void 0 ? _a : 2000;
|
|
4319
|
+
this.currentBatchTimeoutMs = this.batchTimeoutMs;
|
|
4320
|
+
this.maxBatchSize = (_b = options.maxBatchSize) !== null && _b !== void 0 ? _b : 100;
|
|
4321
|
+
this.analyticsUrl = (_c = options.analyticsUrl) !== null && _c !== void 0 ? _c : 'https://analytics.ton.org/events';
|
|
4322
|
+
this.enabled = (_d = options.enabled) !== null && _d !== void 0 ? _d : true;
|
|
4323
|
+
this.baseEvent = {
|
|
4324
|
+
subsystem: 'dapp-sdk',
|
|
4325
|
+
version: tonConnectSdkVersion,
|
|
4326
|
+
client_environment: (_e = options.environment) === null || _e === void 0 ? void 0 : _e.getClientEnvironment()
|
|
4327
|
+
};
|
|
4328
|
+
this.addWindowFocusAndBlurSubscriptions();
|
|
4329
|
+
}
|
|
4330
|
+
scoped(sharedData) {
|
|
4331
|
+
return new Proxy(this, {
|
|
4332
|
+
get(target, prop) {
|
|
4333
|
+
const propName = prop.toString();
|
|
4334
|
+
if (propName.startsWith('emit')) {
|
|
4335
|
+
const eventNamePascal = propName.replace('emit', '');
|
|
4336
|
+
const eventNameKebab = pascalToKebab(eventNamePascal);
|
|
4337
|
+
return function (event) {
|
|
4338
|
+
const executedData = Object.fromEntries(Object.entries(sharedData !== null && sharedData !== void 0 ? sharedData : {}).map(([key, value]) => [
|
|
4339
|
+
key,
|
|
4340
|
+
typeof value === 'function' ? value() : value
|
|
4341
|
+
]));
|
|
4342
|
+
return target.emit(Object.assign(Object.assign({ event_name: eventNameKebab }, executedData), event));
|
|
4343
|
+
};
|
|
4344
|
+
}
|
|
4345
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4346
|
+
return target[prop];
|
|
4347
|
+
}
|
|
4348
|
+
});
|
|
4349
|
+
}
|
|
4350
|
+
emit(event) {
|
|
4351
|
+
var _a;
|
|
4352
|
+
if (!this.enabled) {
|
|
4353
|
+
return;
|
|
4354
|
+
}
|
|
4355
|
+
const traceId = (_a = event.trace_id) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
4356
|
+
const enhancedEvent = Object.assign(Object.assign(Object.assign({}, this.baseEvent), event), { event_id: UUIDv7(), client_timestamp: Math.floor(Date.now() / 1000), trace_id: traceId });
|
|
4357
|
+
if (isQaModeEnabled()) {
|
|
4358
|
+
logDebug(enhancedEvent);
|
|
4359
|
+
}
|
|
4360
|
+
this.events.push(enhancedEvent);
|
|
4361
|
+
if (this.events.length >= this.maxBatchSize) {
|
|
4362
|
+
void this.flush();
|
|
4363
|
+
return;
|
|
4364
|
+
}
|
|
4365
|
+
this.startTimeout();
|
|
4366
|
+
}
|
|
4367
|
+
startTimeout() {
|
|
4368
|
+
if (this.timeoutId || this.isProcessing) {
|
|
4369
|
+
return;
|
|
4370
|
+
}
|
|
4371
|
+
this.timeoutId = setTimeout(() => {
|
|
4372
|
+
void this.flush();
|
|
4373
|
+
}, this.currentBatchTimeoutMs);
|
|
4374
|
+
}
|
|
4375
|
+
flush() {
|
|
4376
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4377
|
+
if (this.isProcessing || this.events.length === 0 || !this.shouldSend) {
|
|
4378
|
+
return;
|
|
4379
|
+
}
|
|
4380
|
+
this.clearTimeout();
|
|
4381
|
+
this.isProcessing = true;
|
|
4382
|
+
const eventsToSend = this.extractEventsToSend();
|
|
4383
|
+
try {
|
|
4384
|
+
yield this.processEventsBatch(eventsToSend);
|
|
4385
|
+
logDebug('Analytics events sent successfully');
|
|
4386
|
+
}
|
|
4387
|
+
catch (error) {
|
|
4388
|
+
this.restoreEvents(eventsToSend);
|
|
4389
|
+
logError('Failed to send analytics events:', error);
|
|
4390
|
+
}
|
|
4391
|
+
finally {
|
|
4392
|
+
this.isProcessing = false;
|
|
4393
|
+
this.scheduleNextFlushIfNeeded();
|
|
4394
|
+
}
|
|
4395
|
+
});
|
|
4396
|
+
}
|
|
4397
|
+
clearTimeout() {
|
|
4398
|
+
if (this.timeoutId) {
|
|
4399
|
+
clearTimeout(this.timeoutId);
|
|
4400
|
+
this.timeoutId = null;
|
|
4401
|
+
}
|
|
4402
|
+
}
|
|
4403
|
+
extractEventsToSend() {
|
|
4404
|
+
const eventsToSend = this.events.slice(0, this.maxBatchSize);
|
|
4405
|
+
this.events = this.events.slice(this.maxBatchSize);
|
|
4406
|
+
return eventsToSend;
|
|
4407
|
+
}
|
|
4408
|
+
processEventsBatch(eventsToSend) {
|
|
4409
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4410
|
+
logDebug('Sending analytics events...', eventsToSend.length);
|
|
4411
|
+
try {
|
|
4412
|
+
const response = yield this.sendEvents(eventsToSend);
|
|
4413
|
+
this.handleResponse(response);
|
|
4414
|
+
}
|
|
4415
|
+
catch (err) {
|
|
4416
|
+
this.handleUnknownError(err);
|
|
4417
|
+
}
|
|
4418
|
+
});
|
|
4419
|
+
}
|
|
4420
|
+
handleResponse(response) {
|
|
4421
|
+
const { status, statusText } = response;
|
|
4422
|
+
if (this.isTooManyRequests(status)) {
|
|
4423
|
+
this.handleTooManyRequests(status, statusText);
|
|
4424
|
+
}
|
|
4425
|
+
else if (this.isClientError(status)) {
|
|
4426
|
+
this.handleClientError(status, statusText);
|
|
4427
|
+
}
|
|
4428
|
+
else if (this.isServerError(status)) {
|
|
4429
|
+
this.handleUnknownError({ status, statusText });
|
|
4430
|
+
}
|
|
4431
|
+
}
|
|
4432
|
+
restoreEvents(eventsToSend) {
|
|
4433
|
+
this.events.unshift(...eventsToSend);
|
|
4434
|
+
}
|
|
4435
|
+
scheduleNextFlushIfNeeded() {
|
|
4436
|
+
if (this.events.length > 0) {
|
|
4437
|
+
this.startTimeout();
|
|
4438
|
+
}
|
|
4439
|
+
}
|
|
4440
|
+
sendEvents(events) {
|
|
4441
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4442
|
+
return yield fetch(this.analyticsUrl, {
|
|
4443
|
+
method: 'POST',
|
|
4444
|
+
headers: {
|
|
4445
|
+
'Content-Type': 'application/json',
|
|
4446
|
+
'X-Client-Timestamp': Math.floor(Date.now() / 1000).toString()
|
|
4447
|
+
},
|
|
4448
|
+
body: JSON.stringify(events)
|
|
4449
|
+
});
|
|
4450
|
+
});
|
|
4451
|
+
}
|
|
4452
|
+
isClientError(status) {
|
|
4453
|
+
return (status >= AnalyticsManager.HTTP_STATUS.CLIENT_ERROR_START &&
|
|
4454
|
+
status < AnalyticsManager.HTTP_STATUS.SERVER_ERROR_START);
|
|
4455
|
+
}
|
|
4456
|
+
isServerError(status) {
|
|
4457
|
+
return status >= AnalyticsManager.HTTP_STATUS.SERVER_ERROR_START;
|
|
4458
|
+
}
|
|
4459
|
+
isTooManyRequests(status) {
|
|
4460
|
+
return status === AnalyticsManager.HTTP_STATUS.TOO_MANY_REQUESTS;
|
|
4461
|
+
}
|
|
4462
|
+
handleClientError(status, statusText) {
|
|
4463
|
+
// Don't retry
|
|
4464
|
+
logError('Failed to send analytics events:', new TonConnectError(`Analytics API error: ${status} ${statusText}`));
|
|
4465
|
+
}
|
|
4466
|
+
handleUnknownError(error) {
|
|
4467
|
+
if (this.backoff < AnalyticsManager.MAX_BACKOFF_ATTEMPTS) {
|
|
4468
|
+
this.backoff++;
|
|
4469
|
+
this.currentBatchTimeoutMs *= AnalyticsManager.BACKOFF_MULTIPLIER;
|
|
4470
|
+
throw new TonConnectError(`Unknown analytics API error: ${error}`);
|
|
4471
|
+
}
|
|
4472
|
+
else {
|
|
4473
|
+
this.currentBatchTimeoutMs = this.batchTimeoutMs;
|
|
4474
|
+
this.backoff = 1;
|
|
4475
|
+
return; // Don't retry
|
|
4476
|
+
}
|
|
4477
|
+
}
|
|
4478
|
+
handleTooManyRequests(status, statusText) {
|
|
4479
|
+
throw new TonConnectError(`Analytics API error: ${status} ${statusText}`);
|
|
4480
|
+
}
|
|
4481
|
+
addWindowFocusAndBlurSubscriptions() {
|
|
4482
|
+
const document = getDocument();
|
|
4483
|
+
if (!document) {
|
|
4484
|
+
return;
|
|
4485
|
+
}
|
|
4486
|
+
try {
|
|
4487
|
+
document.addEventListener('visibilitychange', () => {
|
|
4488
|
+
if (document.hidden) {
|
|
4489
|
+
this.clearTimeout();
|
|
4490
|
+
this.shouldSend = false;
|
|
4491
|
+
}
|
|
4492
|
+
else {
|
|
4493
|
+
this.shouldSend = true;
|
|
4494
|
+
this.scheduleNextFlushIfNeeded();
|
|
4495
|
+
}
|
|
4496
|
+
});
|
|
4497
|
+
}
|
|
4498
|
+
catch (e) {
|
|
4499
|
+
logError('Cannot subscribe to the document.visibilitychange: ', e);
|
|
4500
|
+
}
|
|
4501
|
+
}
|
|
4502
|
+
setEnabled(enabled) {
|
|
4503
|
+
this.enabled = enabled;
|
|
4504
|
+
}
|
|
4505
|
+
isEnabled() {
|
|
4506
|
+
return this.enabled;
|
|
4507
|
+
}
|
|
4508
|
+
getPendingEventsCount() {
|
|
4509
|
+
return this.events.length;
|
|
4510
|
+
}
|
|
4511
|
+
}
|
|
4512
|
+
AnalyticsManager.HTTP_STATUS = {
|
|
4513
|
+
TOO_MANY_REQUESTS: 429,
|
|
4514
|
+
CLIENT_ERROR_START: 400,
|
|
4515
|
+
SERVER_ERROR_START: 500
|
|
4516
|
+
};
|
|
4517
|
+
AnalyticsManager.MAX_BACKOFF_ATTEMPTS = 5;
|
|
4518
|
+
AnalyticsManager.BACKOFF_MULTIPLIER = 2;
|
|
4519
|
+
|
|
4520
|
+
/**
|
|
4521
|
+
* A concrete implementation of EventDispatcher that dispatches events to the browser window.
|
|
4522
|
+
*/
|
|
4523
|
+
class BrowserEventDispatcher {
|
|
4524
|
+
constructor() {
|
|
4525
|
+
/**
|
|
4526
|
+
* The window object, possibly undefined in a server environment.
|
|
4527
|
+
* @private
|
|
4528
|
+
*/
|
|
4529
|
+
this.window = getWindow();
|
|
4530
|
+
}
|
|
4531
|
+
/**
|
|
4532
|
+
* Dispatches an event with the given name and details to the browser window.
|
|
4533
|
+
* @param eventName - The name of the event to dispatch.
|
|
4534
|
+
* @param eventDetails - The details of the event to dispatch.
|
|
4535
|
+
* @returns A promise that resolves when the event has been dispatched.
|
|
4536
|
+
*/
|
|
4537
|
+
dispatchEvent(eventName, eventDetails) {
|
|
4538
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4539
|
+
var _a;
|
|
4540
|
+
const event = new CustomEvent(eventName, { detail: eventDetails });
|
|
4541
|
+
(_a = this.window) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
|
|
4542
|
+
});
|
|
4543
|
+
}
|
|
4544
|
+
/**
|
|
4545
|
+
* Adds an event listener to the browser window.
|
|
4546
|
+
* @param eventName - The name of the event to listen for.
|
|
4547
|
+
* @param listener - The listener to add.
|
|
4548
|
+
* @param options - The options for the listener.
|
|
4549
|
+
* @returns A function that removes the listener.
|
|
4550
|
+
*/
|
|
4551
|
+
addEventListener(eventName, listener, options) {
|
|
4552
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4553
|
+
var _a;
|
|
4554
|
+
(_a = this.window) === null || _a === void 0 ? void 0 : _a.addEventListener(eventName, listener, options);
|
|
4555
|
+
return () => {
|
|
4556
|
+
var _a;
|
|
4557
|
+
return (_a = this.window) === null || _a === void 0 ? void 0 : _a.removeEventListener(eventName, listener);
|
|
4558
|
+
};
|
|
4559
|
+
});
|
|
4560
|
+
}
|
|
4561
|
+
}
|
|
4562
|
+
|
|
4563
|
+
function buildVersionInfo(version) {
|
|
4564
|
+
return {
|
|
4565
|
+
'@tonconnect/sdk': version.ton_connect_sdk_lib || '',
|
|
4566
|
+
'@tonconnect/ui': version.ton_connect_ui_lib || ''
|
|
4567
|
+
};
|
|
4568
|
+
}
|
|
4569
|
+
function buildTonConnectEvent(detail) {
|
|
4570
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
4571
|
+
return {
|
|
4572
|
+
versions: buildVersionInfo(detail.custom_data),
|
|
4573
|
+
network_id: (_a = detail.custom_data.chain_id) !== null && _a !== void 0 ? _a : '',
|
|
4574
|
+
client_id: (_b = detail.custom_data.client_id) !== null && _b !== void 0 ? _b : '',
|
|
4575
|
+
wallet_id: (_c = detail.custom_data.wallet_id) !== null && _c !== void 0 ? _c : '',
|
|
4576
|
+
wallet_address: (_d = detail.wallet_address) !== null && _d !== void 0 ? _d : '',
|
|
4577
|
+
wallet_app_name: (_e = detail.wallet_type) !== null && _e !== void 0 ? _e : '',
|
|
4578
|
+
wallet_app_version: (_f = detail.wallet_version) !== null && _f !== void 0 ? _f : '',
|
|
4579
|
+
wallet_state_init: (_g = detail.wallet_state_init) !== null && _g !== void 0 ? _g : '',
|
|
4580
|
+
trace_id: (_h = detail.trace_id) !== null && _h !== void 0 ? _h : undefined
|
|
4581
|
+
};
|
|
4582
|
+
}
|
|
4583
|
+
function bindEventsTo(eventDispatcher, analytics) {
|
|
4584
|
+
eventDispatcher.addEventListener('ton-connect-ui-wallet-modal-opened', event => {
|
|
4585
|
+
var _a;
|
|
4586
|
+
const { detail } = event;
|
|
4587
|
+
analytics.emitConnectionStarted({
|
|
4588
|
+
client_id: detail.client_id || '',
|
|
4589
|
+
versions: buildVersionInfo(detail.custom_data),
|
|
4590
|
+
main_screen: detail.visible_wallets,
|
|
4591
|
+
trace_id: (_a = detail.trace_id) !== null && _a !== void 0 ? _a : undefined
|
|
4592
|
+
});
|
|
4593
|
+
});
|
|
4594
|
+
eventDispatcher.addEventListener('ton-connect-ui-selected-wallet', event => {
|
|
4595
|
+
var _a, _b;
|
|
4596
|
+
const { detail } = event;
|
|
4597
|
+
analytics.emitConnectionSelectedWallet({
|
|
4598
|
+
client_id: detail.client_id || '',
|
|
4599
|
+
versions: buildVersionInfo(detail.custom_data),
|
|
4600
|
+
main_screen: detail.visible_wallets,
|
|
4601
|
+
wallets_menu: detail.wallets_menu,
|
|
4602
|
+
trace_id: (_a = detail.trace_id) !== null && _a !== void 0 ? _a : undefined,
|
|
4603
|
+
wallet_app_name: (_b = detail.wallet_type) !== null && _b !== void 0 ? _b : '',
|
|
4604
|
+
wallet_redirect_method: detail.wallet_redirect_method,
|
|
4605
|
+
wallet_redirect_link: detail.wallet_redirect_link
|
|
4606
|
+
});
|
|
4607
|
+
});
|
|
4608
|
+
eventDispatcher.addEventListener('ton-connect-connection-completed', event => {
|
|
4609
|
+
const { detail } = event;
|
|
4610
|
+
analytics.emitConnectionCompleted(buildTonConnectEvent(detail));
|
|
4611
|
+
});
|
|
4612
|
+
eventDispatcher.addEventListener('ton-connect-connection-error', event => {
|
|
4613
|
+
var _a, _b;
|
|
4614
|
+
const { detail } = event;
|
|
4615
|
+
analytics.emitConnectionError({
|
|
4616
|
+
client_id: detail.custom_data.client_id || '',
|
|
4617
|
+
wallet_id: detail.custom_data.wallet_id || '',
|
|
4618
|
+
error_code: (_a = detail.error_code) !== null && _a !== void 0 ? _a : 0,
|
|
4619
|
+
error_message: detail.error_message,
|
|
4620
|
+
trace_id: (_b = detail.trace_id) !== null && _b !== void 0 ? _b : undefined
|
|
4621
|
+
});
|
|
4622
|
+
});
|
|
4623
|
+
eventDispatcher.addEventListener('ton-connect-disconnection', event => {
|
|
4624
|
+
const { detail } = event;
|
|
4625
|
+
analytics.emitDisconnection(buildTonConnectEvent(detail));
|
|
4626
|
+
});
|
|
4627
|
+
eventDispatcher.addEventListener('ton-connect-transaction-sent-for-signature', event => {
|
|
4628
|
+
const { detail } = event;
|
|
4629
|
+
analytics.emitTransactionSent(buildTonConnectEvent(detail));
|
|
4630
|
+
});
|
|
4631
|
+
eventDispatcher.addEventListener('ton-connect-transaction-signed', event => {
|
|
4632
|
+
const { detail } = event;
|
|
4633
|
+
analytics.emitTransactionSigned(Object.assign(Object.assign({}, buildTonConnectEvent(detail)), { signed_boc: event.detail.signed_transaction }));
|
|
4634
|
+
});
|
|
4635
|
+
eventDispatcher.addEventListener('ton-connect-transaction-signing-failed', event => {
|
|
4636
|
+
var _a;
|
|
4637
|
+
const { detail } = event;
|
|
4638
|
+
analytics.emitTransactionSigningFailed(Object.assign(Object.assign({}, buildTonConnectEvent(detail)), { valid_until: Number(detail.valid_until), messages: detail.messages.map(message => {
|
|
4639
|
+
var _a, _b, _c, _d;
|
|
4640
|
+
return ({
|
|
4641
|
+
address: (_a = message.address) !== null && _a !== void 0 ? _a : '',
|
|
4642
|
+
amount: (_b = message.amount) !== null && _b !== void 0 ? _b : '',
|
|
4643
|
+
payload: (_c = message.payload) !== null && _c !== void 0 ? _c : '',
|
|
4644
|
+
state_init: (_d = message.state_init) !== null && _d !== void 0 ? _d : ''
|
|
4645
|
+
});
|
|
4646
|
+
}), error_message: detail.error_message, error_code: (_a = detail.error_code) !== null && _a !== void 0 ? _a : 0 }));
|
|
4647
|
+
});
|
|
4648
|
+
eventDispatcher.addEventListener('ton-connect-sign-data-request-initiated', event => {
|
|
4649
|
+
const { detail } = event;
|
|
4650
|
+
analytics === null || analytics === void 0 ? void 0 : analytics.emitSignDataRequestInitiated(buildTonConnectEvent(detail));
|
|
4651
|
+
});
|
|
4652
|
+
eventDispatcher.addEventListener('ton-connect-sign-data-request-completed', event => {
|
|
4653
|
+
const { detail } = event;
|
|
4654
|
+
analytics === null || analytics === void 0 ? void 0 : analytics.emitSignDataRequestCompleted(buildTonConnectEvent(detail));
|
|
4655
|
+
});
|
|
4656
|
+
eventDispatcher.addEventListener('ton-connect-sign-data-request-failed', event => {
|
|
4657
|
+
var _a;
|
|
4658
|
+
const { detail } = event;
|
|
4659
|
+
let signDataValue = '';
|
|
4660
|
+
let signDataSchema = undefined;
|
|
4661
|
+
if (detail.data.type === 'text') {
|
|
4662
|
+
signDataValue = detail.data.text;
|
|
4663
|
+
}
|
|
4664
|
+
if (detail.data.type === 'cell') {
|
|
4665
|
+
signDataValue = detail.data.cell;
|
|
4666
|
+
signDataSchema = detail.data.schema;
|
|
4667
|
+
}
|
|
4668
|
+
if (detail.data.type === 'binary') {
|
|
4669
|
+
signDataValue = detail.data.bytes;
|
|
4670
|
+
}
|
|
4671
|
+
analytics === null || analytics === void 0 ? void 0 : analytics.emitSignDataRequestFailed(Object.assign(Object.assign({}, buildTonConnectEvent(detail)), { sign_data_type: detail.data.type, sign_data_value: signDataValue, sign_data_schema: signDataSchema, error_code: (_a = detail.error_code) !== null && _a !== void 0 ? _a : 0, error_message: detail.error_message }));
|
|
4672
|
+
});
|
|
4673
|
+
}
|
|
4674
|
+
|
|
4675
|
+
class DefaultEnvironment {
|
|
4676
|
+
getClientEnvironment() {
|
|
4677
|
+
return '';
|
|
4678
|
+
}
|
|
4679
|
+
getBrowser() {
|
|
4680
|
+
return '';
|
|
4681
|
+
}
|
|
4682
|
+
getLocale() {
|
|
4683
|
+
return '';
|
|
4684
|
+
}
|
|
4685
|
+
getPlatform() {
|
|
4686
|
+
return '';
|
|
4687
|
+
}
|
|
4688
|
+
getTelegramUser() {
|
|
4689
|
+
return undefined;
|
|
4690
|
+
}
|
|
4691
|
+
}
|
|
4692
|
+
|
|
3909
4693
|
class TonConnect {
|
|
3910
4694
|
/**
|
|
3911
4695
|
* Returns available wallets list.
|
|
@@ -3937,13 +4721,15 @@ class TonConnect {
|
|
|
3937
4721
|
this.statusChangeSubscriptions.forEach(callback => callback(this._wallet));
|
|
3938
4722
|
}
|
|
3939
4723
|
constructor(options) {
|
|
4724
|
+
var _a, _b;
|
|
3940
4725
|
this.walletsList = new WalletsListManager();
|
|
3941
4726
|
this._wallet = null;
|
|
3942
4727
|
this.provider = null;
|
|
3943
4728
|
this.statusChangeSubscriptions = [];
|
|
3944
4729
|
this.statusChangeErrorSubscriptions = [];
|
|
4730
|
+
const manifestUrl = (options === null || options === void 0 ? void 0 : options.manifestUrl) || getWebPageManifest();
|
|
3945
4731
|
this.dappSettings = {
|
|
3946
|
-
manifestUrl
|
|
4732
|
+
manifestUrl,
|
|
3947
4733
|
storage: (options === null || options === void 0 ? void 0 : options.storage) || new DefaultStorage()
|
|
3948
4734
|
};
|
|
3949
4735
|
this.walletsRequiredFeatures = options === null || options === void 0 ? void 0 : options.walletsRequiredFeatures;
|
|
@@ -3951,10 +4737,24 @@ class TonConnect {
|
|
|
3951
4737
|
walletsListSource: options === null || options === void 0 ? void 0 : options.walletsListSource,
|
|
3952
4738
|
cacheTTLMs: options === null || options === void 0 ? void 0 : options.walletsListCacheTTLMs
|
|
3953
4739
|
});
|
|
4740
|
+
const eventDispatcher = (_a = options === null || options === void 0 ? void 0 : options.eventDispatcher) !== null && _a !== void 0 ? _a : new BrowserEventDispatcher();
|
|
3954
4741
|
this.tracker = new TonConnectTracker({
|
|
3955
|
-
eventDispatcher
|
|
4742
|
+
eventDispatcher,
|
|
3956
4743
|
tonConnectSdkVersion: tonConnectSdkVersion
|
|
3957
4744
|
});
|
|
4745
|
+
this.environment = (_b = options === null || options === void 0 ? void 0 : options.environment) !== null && _b !== void 0 ? _b : new DefaultEnvironment();
|
|
4746
|
+
// TODO: in production ready make flag to enable them?
|
|
4747
|
+
this.analytics = new AnalyticsManager({ environment: this.environment });
|
|
4748
|
+
const telegramUser = this.environment.getTelegramUser();
|
|
4749
|
+
bindEventsTo(eventDispatcher, this.analytics.scoped({
|
|
4750
|
+
locale: this.environment.getLocale(),
|
|
4751
|
+
browser: this.environment.getBrowser(),
|
|
4752
|
+
platform: this.environment.getPlatform(),
|
|
4753
|
+
tg_id: telegramUser === null || telegramUser === void 0 ? void 0 : telegramUser.id,
|
|
4754
|
+
tma_is_premium: telegramUser === null || telegramUser === void 0 ? void 0 : telegramUser.isPremium,
|
|
4755
|
+
manifest_json_url: manifestUrl,
|
|
4756
|
+
origin_url: getOriginWithPath
|
|
4757
|
+
}));
|
|
3958
4758
|
if (!this.dappSettings.manifestUrl) {
|
|
3959
4759
|
throw new DappMetadataError('Dapp tonconnect-manifest.json must be specified if window.location.origin is undefined. See more https://github.com/ton-connect/docs/blob/main/requests-responses.md#app-manifest');
|
|
3960
4760
|
}
|
|
@@ -3987,17 +4787,22 @@ class TonConnect {
|
|
|
3987
4787
|
}
|
|
3988
4788
|
};
|
|
3989
4789
|
}
|
|
3990
|
-
|
|
3991
|
-
|
|
4790
|
+
// eslint-disable-next-line complexity
|
|
4791
|
+
connect(wallet, requestOrOptions, additionalOptions) {
|
|
4792
|
+
var _a, _b, _c;
|
|
3992
4793
|
// TODO: remove deprecated method
|
|
3993
|
-
const options = {};
|
|
3994
|
-
if (typeof requestOrOptions === 'object' &&
|
|
4794
|
+
const options = Object.assign({}, additionalOptions);
|
|
4795
|
+
if (typeof requestOrOptions === 'object' &&
|
|
4796
|
+
requestOrOptions !== null &&
|
|
4797
|
+
'tonProof' in requestOrOptions) {
|
|
3995
4798
|
options.request = requestOrOptions;
|
|
3996
4799
|
}
|
|
3997
4800
|
if (typeof requestOrOptions === 'object' &&
|
|
4801
|
+
requestOrOptions !== null &&
|
|
3998
4802
|
('openingDeadlineMS' in requestOrOptions ||
|
|
3999
4803
|
'signal' in requestOrOptions ||
|
|
4000
|
-
'request' in requestOrOptions
|
|
4804
|
+
'request' in requestOrOptions ||
|
|
4805
|
+
'traceId' in requestOrOptions)) {
|
|
4001
4806
|
options.request = requestOrOptions === null || requestOrOptions === void 0 ? void 0 : requestOrOptions.request;
|
|
4002
4807
|
options.openingDeadlineMS = requestOrOptions === null || requestOrOptions === void 0 ? void 0 : requestOrOptions.openingDeadlineMS;
|
|
4003
4808
|
options.signal = requestOrOptions === null || requestOrOptions === void 0 ? void 0 : requestOrOptions.signal;
|
|
@@ -4029,10 +4834,12 @@ class TonConnect {
|
|
|
4029
4834
|
(_a = this.provider) === null || _a === void 0 ? void 0 : _a.closeConnection();
|
|
4030
4835
|
this.provider = null;
|
|
4031
4836
|
});
|
|
4032
|
-
|
|
4837
|
+
const traceId = (_c = options === null || options === void 0 ? void 0 : options.traceId) !== null && _c !== void 0 ? _c : UUIDv7();
|
|
4838
|
+
this.tracker.trackConnectionStarted(traceId);
|
|
4033
4839
|
return this.provider.connect(this.createConnectRequest(options === null || options === void 0 ? void 0 : options.request), {
|
|
4034
4840
|
openingDeadlineMS: options === null || options === void 0 ? void 0 : options.openingDeadlineMS,
|
|
4035
|
-
signal: abortController.signal
|
|
4841
|
+
signal: abortController.signal,
|
|
4842
|
+
traceId
|
|
4036
4843
|
});
|
|
4037
4844
|
}
|
|
4038
4845
|
/**
|
|
@@ -4040,13 +4847,14 @@ class TonConnect {
|
|
|
4040
4847
|
*/
|
|
4041
4848
|
restoreConnection(options) {
|
|
4042
4849
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4043
|
-
var _a, _b;
|
|
4044
|
-
|
|
4850
|
+
var _a, _b, _c;
|
|
4851
|
+
const traceId = (_a = options === null || options === void 0 ? void 0 : options.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
4852
|
+
this.tracker.trackConnectionRestoringStarted(traceId);
|
|
4045
4853
|
const abortController = createAbortController(options === null || options === void 0 ? void 0 : options.signal);
|
|
4046
|
-
(
|
|
4854
|
+
(_b = this.abortController) === null || _b === void 0 ? void 0 : _b.abort();
|
|
4047
4855
|
this.abortController = abortController;
|
|
4048
4856
|
if (abortController.signal.aborted) {
|
|
4049
|
-
this.tracker.trackConnectionRestoringError('Connection restoring was aborted');
|
|
4857
|
+
this.tracker.trackConnectionRestoringError('Connection restoring was aborted', traceId);
|
|
4050
4858
|
return;
|
|
4051
4859
|
}
|
|
4052
4860
|
// TODO: potentially race condition here
|
|
@@ -4055,17 +4863,17 @@ class TonConnect {
|
|
|
4055
4863
|
this.walletsList.getEmbeddedWallet()
|
|
4056
4864
|
]);
|
|
4057
4865
|
if (abortController.signal.aborted) {
|
|
4058
|
-
this.tracker.trackConnectionRestoringError('Connection restoring was aborted');
|
|
4866
|
+
this.tracker.trackConnectionRestoringError('Connection restoring was aborted', traceId);
|
|
4059
4867
|
return;
|
|
4060
4868
|
}
|
|
4061
4869
|
let provider = null;
|
|
4062
4870
|
try {
|
|
4063
4871
|
switch (bridgeConnectionType) {
|
|
4064
4872
|
case 'http':
|
|
4065
|
-
provider = yield BridgeProvider.fromStorage(this.dappSettings.storage);
|
|
4873
|
+
provider = yield BridgeProvider.fromStorage(this.dappSettings.storage, this.analytics);
|
|
4066
4874
|
break;
|
|
4067
4875
|
case 'injected':
|
|
4068
|
-
provider = yield InjectedProvider.fromStorage(this.dappSettings.storage);
|
|
4876
|
+
provider = yield InjectedProvider.fromStorage(this.dappSettings.storage, this.analytics);
|
|
4069
4877
|
break;
|
|
4070
4878
|
default:
|
|
4071
4879
|
if (embeddedWallet) {
|
|
@@ -4076,8 +4884,8 @@ class TonConnect {
|
|
|
4076
4884
|
}
|
|
4077
4885
|
}
|
|
4078
4886
|
}
|
|
4079
|
-
catch (
|
|
4080
|
-
this.tracker.trackConnectionRestoringError('Provider is not restored');
|
|
4887
|
+
catch (_d) {
|
|
4888
|
+
this.tracker.trackConnectionRestoringError('Provider is not restored', traceId);
|
|
4081
4889
|
yield this.bridgeConnectionStorage.removeConnection();
|
|
4082
4890
|
provider === null || provider === void 0 ? void 0 : provider.closeConnection();
|
|
4083
4891
|
provider = null;
|
|
@@ -4085,19 +4893,19 @@ class TonConnect {
|
|
|
4085
4893
|
}
|
|
4086
4894
|
if (abortController.signal.aborted) {
|
|
4087
4895
|
provider === null || provider === void 0 ? void 0 : provider.closeConnection();
|
|
4088
|
-
this.tracker.trackConnectionRestoringError('Connection restoring was aborted');
|
|
4896
|
+
this.tracker.trackConnectionRestoringError('Connection restoring was aborted', traceId);
|
|
4089
4897
|
return;
|
|
4090
4898
|
}
|
|
4091
4899
|
if (!provider) {
|
|
4092
4900
|
logError('Provider is not restored');
|
|
4093
|
-
this.tracker.trackConnectionRestoringError('Provider is not restored');
|
|
4901
|
+
this.tracker.trackConnectionRestoringError('Provider is not restored', traceId);
|
|
4094
4902
|
return;
|
|
4095
4903
|
}
|
|
4096
|
-
(
|
|
4904
|
+
(_c = this.provider) === null || _c === void 0 ? void 0 : _c.closeConnection();
|
|
4097
4905
|
this.provider = provider;
|
|
4098
4906
|
provider.listen(this.walletEventsListener.bind(this));
|
|
4099
4907
|
const onAbortRestore = () => {
|
|
4100
|
-
this.tracker.trackConnectionRestoringError('Connection restoring was aborted');
|
|
4908
|
+
this.tracker.trackConnectionRestoringError('Connection restoring was aborted', traceId);
|
|
4101
4909
|
provider === null || provider === void 0 ? void 0 : provider.closeConnection();
|
|
4102
4910
|
provider = null;
|
|
4103
4911
|
};
|
|
@@ -4105,14 +4913,16 @@ class TonConnect {
|
|
|
4105
4913
|
const restoreConnectionTask = callForSuccess((_options) => __awaiter(this, void 0, void 0, function* () {
|
|
4106
4914
|
yield (provider === null || provider === void 0 ? void 0 : provider.restoreConnection({
|
|
4107
4915
|
openingDeadlineMS: options === null || options === void 0 ? void 0 : options.openingDeadlineMS,
|
|
4108
|
-
signal: _options.signal
|
|
4916
|
+
signal: _options.signal,
|
|
4917
|
+
traceId
|
|
4109
4918
|
}));
|
|
4110
4919
|
abortController.signal.removeEventListener('abort', onAbortRestore);
|
|
4111
4920
|
if (this.connected) {
|
|
4112
|
-
this.
|
|
4921
|
+
const sessionInfo = this.getSessionInfo();
|
|
4922
|
+
this.tracker.trackConnectionRestoringCompleted(this.wallet, sessionInfo, traceId);
|
|
4113
4923
|
}
|
|
4114
4924
|
else {
|
|
4115
|
-
this.tracker.trackConnectionRestoringError('Connection restoring failed');
|
|
4925
|
+
this.tracker.trackConnectionRestoringError('Connection restoring failed', traceId);
|
|
4116
4926
|
}
|
|
4117
4927
|
}), {
|
|
4118
4928
|
attempts: Number.MAX_SAFE_INTEGER,
|
|
@@ -4126,6 +4936,7 @@ class TonConnect {
|
|
|
4126
4936
|
}
|
|
4127
4937
|
sendTransaction(transaction, optionsOrOnRequestSent) {
|
|
4128
4938
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4939
|
+
var _a, _b, _c;
|
|
4129
4940
|
// TODO: remove deprecated method
|
|
4130
4941
|
const options = {};
|
|
4131
4942
|
if (typeof optionsOrOnRequestSent === 'function') {
|
|
@@ -4134,6 +4945,7 @@ class TonConnect {
|
|
|
4134
4945
|
else {
|
|
4135
4946
|
options.onRequestSent = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.onRequestSent;
|
|
4136
4947
|
options.signal = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.signal;
|
|
4948
|
+
options.traceId = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.traceId;
|
|
4137
4949
|
}
|
|
4138
4950
|
// Validate transaction
|
|
4139
4951
|
const validationError = validateSendTransactionRequest(transaction);
|
|
@@ -4156,26 +4968,41 @@ class TonConnect {
|
|
|
4156
4968
|
requiredMessagesNumber,
|
|
4157
4969
|
requireExtraCurrencies
|
|
4158
4970
|
});
|
|
4159
|
-
this.
|
|
4971
|
+
const sessionInfo = this.getSessionInfo();
|
|
4972
|
+
const traceId = (_a = options === null || options === void 0 ? void 0 : options.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
4973
|
+
this.tracker.trackTransactionSentForSignature(this.wallet, transaction, sessionInfo, traceId);
|
|
4160
4974
|
const { validUntil, messages } = transaction, tx = __rest(transaction, ["validUntil", "messages"]);
|
|
4161
4975
|
const from = transaction.from || this.account.address;
|
|
4162
4976
|
const network = transaction.network || this.account.chain;
|
|
4977
|
+
if (((_b = this.wallet) === null || _b === void 0 ? void 0 : _b.account.chain) && network !== this.wallet.account.chain) {
|
|
4978
|
+
throw new WalletWrongNetworkError('Wallet connected to a wrong network', {
|
|
4979
|
+
cause: {
|
|
4980
|
+
expectedChainId: (_c = this.wallet) === null || _c === void 0 ? void 0 : _c.account.chain,
|
|
4981
|
+
actualChainId: network
|
|
4982
|
+
}
|
|
4983
|
+
});
|
|
4984
|
+
}
|
|
4163
4985
|
const response = yield this.provider.sendRequest(sendTransactionParser.convertToRpcRequest(Object.assign(Object.assign({}, tx), { from,
|
|
4164
4986
|
network, valid_until: validUntil, messages: messages.map((_a) => {
|
|
4165
4987
|
var { extraCurrency, payload, stateInit } = _a, msg = __rest(_a, ["extraCurrency", "payload", "stateInit"]);
|
|
4166
4988
|
return (Object.assign(Object.assign({}, msg), { payload: normalizeBase64(payload), stateInit: normalizeBase64(stateInit), extra_currency: extraCurrency }));
|
|
4167
|
-
}) })), {
|
|
4989
|
+
}) })), {
|
|
4990
|
+
onRequestSent: options.onRequestSent,
|
|
4991
|
+
signal: abortController.signal,
|
|
4992
|
+
traceId
|
|
4993
|
+
});
|
|
4168
4994
|
if (sendTransactionParser.isError(response)) {
|
|
4169
|
-
this.tracker.trackTransactionSigningFailed(this.wallet, transaction, response.error.message, response.error.code);
|
|
4995
|
+
this.tracker.trackTransactionSigningFailed(this.wallet, transaction, response.error.message, response.error.code, sessionInfo, traceId);
|
|
4170
4996
|
return sendTransactionParser.parseAndThrowError(response);
|
|
4171
4997
|
}
|
|
4172
4998
|
const result = sendTransactionParser.convertFromRpcResponse(response);
|
|
4173
|
-
this.tracker.trackTransactionSigned(this.wallet, transaction, result);
|
|
4174
|
-
return result;
|
|
4999
|
+
this.tracker.trackTransactionSigned(this.wallet, transaction, result, sessionInfo, traceId);
|
|
5000
|
+
return Object.assign(Object.assign({}, result), { traceId: response.traceId });
|
|
4175
5001
|
});
|
|
4176
5002
|
}
|
|
4177
5003
|
signData(data, options) {
|
|
4178
5004
|
return __awaiter(this, void 0, void 0, function* () {
|
|
5005
|
+
var _a, _b, _c;
|
|
4179
5006
|
const abortController = createAbortController(options === null || options === void 0 ? void 0 : options.signal);
|
|
4180
5007
|
if (abortController.signal.aborted) {
|
|
4181
5008
|
throw new TonConnectError('data sending was aborted');
|
|
@@ -4192,26 +5019,47 @@ class TonConnect {
|
|
|
4192
5019
|
}
|
|
4193
5020
|
this.checkConnection();
|
|
4194
5021
|
checkSignDataSupport(this.wallet.device.features, { requiredTypes: [data.type] });
|
|
4195
|
-
this.
|
|
5022
|
+
const sessionInfo = this.getSessionInfo();
|
|
5023
|
+
const traceId = (_a = options === null || options === void 0 ? void 0 : options.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
5024
|
+
this.tracker.trackDataSentForSignature(this.wallet, data, sessionInfo, traceId);
|
|
4196
5025
|
const from = data.from || this.account.address;
|
|
4197
5026
|
const network = data.network || this.account.chain;
|
|
5027
|
+
if (((_b = this.wallet) === null || _b === void 0 ? void 0 : _b.account.chain) && network !== this.wallet.account.chain) {
|
|
5028
|
+
throw new WalletWrongNetworkError('Wallet connected to a wrong network', {
|
|
5029
|
+
cause: {
|
|
5030
|
+
expectedChainId: (_c = this.wallet) === null || _c === void 0 ? void 0 : _c.account.chain,
|
|
5031
|
+
actualChainId: network
|
|
5032
|
+
}
|
|
5033
|
+
});
|
|
5034
|
+
}
|
|
4198
5035
|
const response = yield this.provider.sendRequest(signDataParser.convertToRpcRequest(Object.assign(Object.assign(Object.assign({}, data), (data.type === 'cell' ? { cell: normalizeBase64(data.cell) } : {})), { from,
|
|
4199
|
-
network })), { onRequestSent: options === null || options === void 0 ? void 0 : options.onRequestSent, signal: abortController.signal });
|
|
5036
|
+
network })), { onRequestSent: options === null || options === void 0 ? void 0 : options.onRequestSent, signal: abortController.signal, traceId });
|
|
4200
5037
|
if (signDataParser.isError(response)) {
|
|
4201
|
-
this.tracker.trackDataSigningFailed(this.wallet, data, response.error.message, response.error.code);
|
|
5038
|
+
this.tracker.trackDataSigningFailed(this.wallet, data, response.error.message, response.error.code, sessionInfo, traceId);
|
|
4202
5039
|
return signDataParser.parseAndThrowError(response);
|
|
4203
5040
|
}
|
|
4204
5041
|
const result = signDataParser.convertFromRpcResponse(response);
|
|
4205
|
-
this.tracker.trackDataSigned(this.wallet, data, result);
|
|
4206
|
-
return result;
|
|
5042
|
+
this.tracker.trackDataSigned(this.wallet, data, result, sessionInfo, traceId);
|
|
5043
|
+
return Object.assign(Object.assign({}, result), { traceId });
|
|
4207
5044
|
});
|
|
4208
5045
|
}
|
|
5046
|
+
/**
|
|
5047
|
+
* Set desired network for the connection. Can only be set before connecting.
|
|
5048
|
+
* If wallet connects with a different chain, the SDK will throw an error and abort connection.
|
|
5049
|
+
* @param network desired network id (e.g., '-239', '-3', or custom). Pass undefined to allow any network.
|
|
5050
|
+
*/
|
|
5051
|
+
setConnectionNetwork(network) {
|
|
5052
|
+
if (this.connected) {
|
|
5053
|
+
throw new TonConnectError('Cannot change network while wallet is connected');
|
|
5054
|
+
}
|
|
5055
|
+
this.desiredChainId = network;
|
|
5056
|
+
}
|
|
4209
5057
|
/**
|
|
4210
5058
|
* Disconnect form thw connected wallet and drop current session.
|
|
4211
5059
|
*/
|
|
4212
5060
|
disconnect(options) {
|
|
4213
5061
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4214
|
-
var _a;
|
|
5062
|
+
var _a, _b;
|
|
4215
5063
|
if (!this.connected) {
|
|
4216
5064
|
throw new WalletNotConnectedError();
|
|
4217
5065
|
}
|
|
@@ -4221,9 +5069,11 @@ class TonConnect {
|
|
|
4221
5069
|
if (abortController.signal.aborted) {
|
|
4222
5070
|
throw new TonConnectError('Disconnect was aborted');
|
|
4223
5071
|
}
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
5072
|
+
const traceId = (_a = options === null || options === void 0 ? void 0 : options.traceId) !== null && _a !== void 0 ? _a : UUIDv7();
|
|
5073
|
+
this.onWalletDisconnected('dapp', { traceId });
|
|
5074
|
+
yield ((_b = this.provider) === null || _b === void 0 ? void 0 : _b.disconnect({
|
|
5075
|
+
signal: abortController.signal,
|
|
5076
|
+
traceId
|
|
4227
5077
|
}));
|
|
4228
5078
|
prevAbortController === null || prevAbortController === void 0 ? void 0 : prevAbortController.abort();
|
|
4229
5079
|
});
|
|
@@ -4234,7 +5084,7 @@ class TonConnect {
|
|
|
4234
5084
|
*/
|
|
4235
5085
|
getSessionId() {
|
|
4236
5086
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4237
|
-
if (!this.provider
|
|
5087
|
+
if (!this.provider) {
|
|
4238
5088
|
return null;
|
|
4239
5089
|
}
|
|
4240
5090
|
try {
|
|
@@ -4256,6 +5106,30 @@ class TonConnect {
|
|
|
4256
5106
|
}
|
|
4257
5107
|
});
|
|
4258
5108
|
}
|
|
5109
|
+
getSessionInfo() {
|
|
5110
|
+
var _a;
|
|
5111
|
+
if (((_a = this.provider) === null || _a === void 0 ? void 0 : _a.type) !== 'http') {
|
|
5112
|
+
return null;
|
|
5113
|
+
}
|
|
5114
|
+
if (!('session' in this.provider)) {
|
|
5115
|
+
return null;
|
|
5116
|
+
}
|
|
5117
|
+
try {
|
|
5118
|
+
const session = this.provider.session;
|
|
5119
|
+
if (!session) {
|
|
5120
|
+
return null;
|
|
5121
|
+
}
|
|
5122
|
+
const clientId = session.sessionCrypto.sessionId;
|
|
5123
|
+
let walletId = null;
|
|
5124
|
+
if ('walletPublicKey' in session) {
|
|
5125
|
+
walletId = session.walletPublicKey;
|
|
5126
|
+
}
|
|
5127
|
+
return { clientId, walletId };
|
|
5128
|
+
}
|
|
5129
|
+
catch (_b) {
|
|
5130
|
+
return null;
|
|
5131
|
+
}
|
|
5132
|
+
}
|
|
4259
5133
|
/**
|
|
4260
5134
|
* Pause bridge HTTP connection. Might be helpful, if you want to pause connections while browser tab is unfocused,
|
|
4261
5135
|
* or if you use SDK with NodeJS and want to save server resources.
|
|
@@ -4299,10 +5173,10 @@ class TonConnect {
|
|
|
4299
5173
|
createProvider(wallet) {
|
|
4300
5174
|
let provider;
|
|
4301
5175
|
if (!Array.isArray(wallet) && isWalletConnectionSourceJS(wallet)) {
|
|
4302
|
-
provider = new InjectedProvider(this.dappSettings.storage, wallet.jsBridgeKey);
|
|
5176
|
+
provider = new InjectedProvider(this.dappSettings.storage, wallet.jsBridgeKey, this.analytics);
|
|
4303
5177
|
}
|
|
4304
5178
|
else {
|
|
4305
|
-
provider = new BridgeProvider(this.dappSettings.storage, wallet);
|
|
5179
|
+
provider = new BridgeProvider(this.dappSettings.storage, wallet, this.analytics);
|
|
4306
5180
|
}
|
|
4307
5181
|
provider.listen(this.walletEventsListener.bind(this));
|
|
4308
5182
|
return provider;
|
|
@@ -4310,19 +5184,19 @@ class TonConnect {
|
|
|
4310
5184
|
walletEventsListener(e) {
|
|
4311
5185
|
switch (e.event) {
|
|
4312
5186
|
case 'connect':
|
|
4313
|
-
this.onWalletConnected(e.payload);
|
|
5187
|
+
this.onWalletConnected(e.payload, { traceId: e.traceId });
|
|
4314
5188
|
break;
|
|
4315
5189
|
case 'connect_error':
|
|
4316
|
-
this.tracker.trackConnectionError(e.payload.message, e.payload.code);
|
|
5190
|
+
this.tracker.trackConnectionError(e.payload.message, e.payload.code, this.getSessionInfo(), e.traceId);
|
|
4317
5191
|
const walletError = connectErrorsParser.parseError(e.payload);
|
|
4318
5192
|
this.onWalletConnectError(walletError);
|
|
4319
5193
|
break;
|
|
4320
5194
|
case 'disconnect':
|
|
4321
|
-
this.onWalletDisconnected('wallet');
|
|
5195
|
+
this.onWalletDisconnected('wallet', { traceId: e.traceId });
|
|
4322
5196
|
}
|
|
4323
5197
|
}
|
|
4324
|
-
onWalletConnected(connectEvent) {
|
|
4325
|
-
var _a;
|
|
5198
|
+
onWalletConnected(connectEvent, options) {
|
|
5199
|
+
var _a, _b;
|
|
4326
5200
|
const tonAccountItem = connectEvent.items.find(item => item.name === 'ton_addr');
|
|
4327
5201
|
const tonProofItem = connectEvent.items.find(item => item.name === 'ton_proof');
|
|
4328
5202
|
if (!tonAccountItem) {
|
|
@@ -4344,6 +5218,15 @@ class TonConnect {
|
|
|
4344
5218
|
publicKey: tonAccountItem.publicKey
|
|
4345
5219
|
}
|
|
4346
5220
|
};
|
|
5221
|
+
if (this.desiredChainId && wallet.account.chain !== this.desiredChainId) {
|
|
5222
|
+
const expectedChainId = this.desiredChainId;
|
|
5223
|
+
const actualChainId = wallet.account.chain;
|
|
5224
|
+
(_b = this.provider) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
5225
|
+
this.onWalletConnectError(new WalletWrongNetworkError('Wallet connected to a wrong network', {
|
|
5226
|
+
cause: { expectedChainId, actualChainId }
|
|
5227
|
+
}));
|
|
5228
|
+
return;
|
|
5229
|
+
}
|
|
4347
5230
|
if (tonProofItem) {
|
|
4348
5231
|
const validationError = validateTonProofItemReply(tonProofItem);
|
|
4349
5232
|
let tonProof = undefined;
|
|
@@ -4401,7 +5284,8 @@ class TonConnect {
|
|
|
4401
5284
|
wallet.connectItems = { tonProof };
|
|
4402
5285
|
}
|
|
4403
5286
|
this.wallet = wallet;
|
|
4404
|
-
this.
|
|
5287
|
+
const sessionInfo = this.getSessionInfo();
|
|
5288
|
+
this.tracker.trackConnectionCompleted(wallet, sessionInfo, options === null || options === void 0 ? void 0 : options.traceId);
|
|
4405
5289
|
}
|
|
4406
5290
|
onWalletConnectError(error) {
|
|
4407
5291
|
this.statusChangeErrorSubscriptions.forEach(errorsHandler => errorsHandler(error));
|
|
@@ -4411,8 +5295,9 @@ class TonConnect {
|
|
|
4411
5295
|
throw error;
|
|
4412
5296
|
}
|
|
4413
5297
|
}
|
|
4414
|
-
onWalletDisconnected(scope) {
|
|
4415
|
-
this.
|
|
5298
|
+
onWalletDisconnected(scope, options) {
|
|
5299
|
+
const sessionInfo = this.getSessionInfo();
|
|
5300
|
+
this.tracker.trackDisconnection(this.wallet, scope, sessionInfo, options === null || options === void 0 ? void 0 : options.traceId);
|
|
4416
5301
|
this.wallet = null;
|
|
4417
5302
|
}
|
|
4418
5303
|
checkConnection() {
|
|
@@ -4422,9 +5307,7 @@ class TonConnect {
|
|
|
4422
5307
|
}
|
|
4423
5308
|
createConnectRequest(request) {
|
|
4424
5309
|
const items = [
|
|
4425
|
-
{
|
|
4426
|
-
name: 'ton_addr'
|
|
4427
|
-
}
|
|
5310
|
+
Object.assign({ name: 'ton_addr' }, (this.desiredChainId ? { network: this.desiredChainId } : {}))
|
|
4428
5311
|
];
|
|
4429
5312
|
if (request === null || request === void 0 ? void 0 : request.tonProof) {
|
|
4430
5313
|
items.push({
|
|
@@ -4481,6 +5364,7 @@ exports.LocalstorageNotFoundError = LocalstorageNotFoundError;
|
|
|
4481
5364
|
exports.ParseHexError = ParseHexError;
|
|
4482
5365
|
exports.TonConnect = TonConnect;
|
|
4483
5366
|
exports.TonConnectError = TonConnectError;
|
|
5367
|
+
exports.UUIDv7 = UUIDv7;
|
|
4484
5368
|
exports.UnknownAppError = UnknownAppError;
|
|
4485
5369
|
exports.UnknownError = UnknownError;
|
|
4486
5370
|
exports.UserRejectsError = UserRejectsError;
|
|
@@ -4489,6 +5373,7 @@ exports.WalletMissingRequiredFeaturesError = WalletMissingRequiredFeaturesError;
|
|
|
4489
5373
|
exports.WalletNotConnectedError = WalletNotConnectedError;
|
|
4490
5374
|
exports.WalletNotInjectedError = WalletNotInjectedError;
|
|
4491
5375
|
exports.WalletNotSupportFeatureError = WalletNotSupportFeatureError;
|
|
5376
|
+
exports.WalletWrongNetworkError = WalletWrongNetworkError;
|
|
4492
5377
|
exports.WalletsListManager = WalletsListManager;
|
|
4493
5378
|
exports.WrongAddressError = WrongAddressError;
|
|
4494
5379
|
exports.checkRequiredWalletFeatures = checkRequiredWalletFeatures;
|
|
@@ -4504,13 +5389,17 @@ exports.createDataSigningFailedEvent = createDataSigningFailedEvent;
|
|
|
4504
5389
|
exports.createDisconnectionEvent = createDisconnectionEvent;
|
|
4505
5390
|
exports.createRequestVersionEvent = createRequestVersionEvent;
|
|
4506
5391
|
exports.createResponseVersionEvent = createResponseVersionEvent;
|
|
5392
|
+
exports.createSelectedWalletEvent = createSelectedWalletEvent;
|
|
4507
5393
|
exports.createTransactionSentForSignatureEvent = createTransactionSentForSignatureEvent;
|
|
4508
5394
|
exports.createTransactionSignedEvent = createTransactionSignedEvent;
|
|
4509
5395
|
exports.createTransactionSigningFailedEvent = createTransactionSigningFailedEvent;
|
|
4510
5396
|
exports.createVersionInfo = createVersionInfo;
|
|
5397
|
+
exports.createWalletModalOpenedEvent = createWalletModalOpenedEvent;
|
|
5398
|
+
exports.decodeTelegramUrlParameters = decodeTelegramUrlParameters;
|
|
4511
5399
|
exports.default = TonConnect;
|
|
4512
5400
|
exports.enableQaMode = enableQaMode;
|
|
4513
5401
|
exports.encodeTelegramUrlParameters = encodeTelegramUrlParameters;
|
|
5402
|
+
exports.isConnectUrl = isConnectUrl;
|
|
4514
5403
|
exports.isQaModeEnabled = isQaModeEnabled;
|
|
4515
5404
|
exports.isTelegramUrl = isTelegramUrl;
|
|
4516
5405
|
exports.isWalletInfoCurrentlyEmbedded = isWalletInfoCurrentlyEmbedded;
|