@fivenorth/loop-sdk 0.1.3 → 0.3.0
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 +5 -3
- package/dist/index.js +60 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -146,7 +146,7 @@ try {
|
|
|
146
146
|
|
|
147
147
|
# API
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
Coming soon
|
|
150
150
|
|
|
151
151
|
# Development Guide
|
|
152
152
|
|
|
@@ -158,12 +158,14 @@ To install dependencies:
|
|
|
158
158
|
bun install
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
-
To run:
|
|
161
|
+
To run the dev server, that is also auto re-compile the sdk:
|
|
162
162
|
|
|
163
163
|
```bash
|
|
164
|
-
bun
|
|
164
|
+
bun start
|
|
165
165
|
```
|
|
166
166
|
|
|
167
|
+
Upon doing so you can visit http://localhost:3030/ to see the local demo app, serve in `demo/test.html` and SDK is auto compile so you can actively working and trying out the SDK.
|
|
168
|
+
|
|
167
169
|
# Publish the package to NPM
|
|
168
170
|
|
|
169
171
|
|
package/dist/index.js
CHANGED
|
@@ -2213,16 +2213,18 @@ class Provider {
|
|
|
2213
2213
|
connection;
|
|
2214
2214
|
party_id;
|
|
2215
2215
|
public_key;
|
|
2216
|
+
email;
|
|
2216
2217
|
auth_token;
|
|
2217
2218
|
requests = new Map;
|
|
2218
2219
|
requestTimeout = 30000;
|
|
2219
|
-
constructor({ connection, party_id, public_key, auth_token, requestTimeout }) {
|
|
2220
|
+
constructor({ connection, party_id, public_key, auth_token, email, requestTimeout }) {
|
|
2220
2221
|
if (!connection) {
|
|
2221
2222
|
throw new Error("Provider requires a connection object.");
|
|
2222
2223
|
}
|
|
2223
2224
|
this.connection = connection;
|
|
2224
2225
|
this.party_id = party_id;
|
|
2225
2226
|
this.public_key = public_key;
|
|
2227
|
+
this.email = email;
|
|
2226
2228
|
this.auth_token = auth_token;
|
|
2227
2229
|
this.requestTimeout = requestTimeout || 30000;
|
|
2228
2230
|
}
|
|
@@ -2286,15 +2288,18 @@ class LoopSDK {
|
|
|
2286
2288
|
appName = "Unknown";
|
|
2287
2289
|
connection = null;
|
|
2288
2290
|
provider = null;
|
|
2291
|
+
openMode = "popup";
|
|
2292
|
+
popupWindow = null;
|
|
2289
2293
|
onAccept = null;
|
|
2290
2294
|
onReject = null;
|
|
2291
2295
|
overlay = null;
|
|
2292
2296
|
ticketId = null;
|
|
2293
2297
|
constructor() {}
|
|
2294
|
-
init({ appName, network, walletUrl, apiUrl, onAccept, onReject }) {
|
|
2298
|
+
init({ appName, network, walletUrl, apiUrl, onAccept, onReject, openMode }) {
|
|
2295
2299
|
this.appName = appName;
|
|
2296
2300
|
this.onAccept = onAccept || null;
|
|
2297
2301
|
this.onReject = onReject || null;
|
|
2302
|
+
this.openMode = openMode ?? "popup";
|
|
2298
2303
|
this.connection = new Connection({ network, walletUrl, apiUrl });
|
|
2299
2304
|
}
|
|
2300
2305
|
async connect() {
|
|
@@ -2308,23 +2313,30 @@ class LoopSDK {
|
|
|
2308
2313
|
const existingConnectionRaw = localStorage.getItem("loop_connect");
|
|
2309
2314
|
if (existingConnectionRaw) {
|
|
2310
2315
|
try {
|
|
2311
|
-
|
|
2316
|
+
let canReuseTicket = true;
|
|
2317
|
+
const { ticketId, authToken, partyId, publicKey, email } = JSON.parse(existingConnectionRaw);
|
|
2312
2318
|
if (authToken && partyId && publicKey) {
|
|
2313
2319
|
try {
|
|
2314
2320
|
const verifiedAccount = await this.connection.verifySession(authToken);
|
|
2315
2321
|
if (verifiedAccount.party_id === partyId) {
|
|
2316
|
-
this.provider = new Provider({ connection: this.connection, party_id: partyId, auth_token: authToken, public_key: publicKey });
|
|
2322
|
+
this.provider = new Provider({ connection: this.connection, party_id: partyId, auth_token: authToken, public_key: publicKey, email });
|
|
2317
2323
|
this.onAccept?.(this.provider);
|
|
2318
2324
|
if (ticketId) {
|
|
2319
2325
|
this.connection.connectWebSocket(ticketId, this.handleWebSocketMessage.bind(this));
|
|
2320
2326
|
}
|
|
2321
2327
|
return;
|
|
2328
|
+
} else {
|
|
2329
|
+
console.warn("[LoopSDK] Sttored partyId does not march verified account. Clearing cached session.");
|
|
2330
|
+
canReuseTicket = false;
|
|
2331
|
+
localStorage.removeItem("loop_connect");
|
|
2322
2332
|
}
|
|
2323
2333
|
} catch (err) {
|
|
2324
2334
|
console.error("Auto-login failed, token is invalid. Starting new connection.", err);
|
|
2335
|
+
canReuseTicket = false;
|
|
2336
|
+
localStorage.removeItem("loop_connect");
|
|
2325
2337
|
}
|
|
2326
2338
|
}
|
|
2327
|
-
if (ticketId) {
|
|
2339
|
+
if (ticketId && canReuseTicket) {
|
|
2328
2340
|
this.ticketId = ticketId;
|
|
2329
2341
|
const connectUrl = `${this.connection.walletUrl}/.connect/?ticketId=${ticketId}`;
|
|
2330
2342
|
this.showQrCode(connectUrl);
|
|
@@ -2351,10 +2363,12 @@ class LoopSDK {
|
|
|
2351
2363
|
}
|
|
2352
2364
|
handleWebSocketMessage(event) {
|
|
2353
2365
|
const message = JSON.parse(event.data);
|
|
2366
|
+
console.log("[LoopSDK] WS message received:", message);
|
|
2354
2367
|
if (message.type === "handshake_accept" /* HANDSHAKE_ACCEPT */) {
|
|
2355
|
-
|
|
2368
|
+
console.log("[LoopSDK] Entering HANDSHAKE_ACCEPT flow");
|
|
2369
|
+
const { authToken, partyId, publicKey, email } = message.payload || {};
|
|
2356
2370
|
if (authToken && partyId && publicKey) {
|
|
2357
|
-
this.provider = new Provider({ connection: this.connection, party_id: partyId, auth_token: authToken, public_key: publicKey });
|
|
2371
|
+
this.provider = new Provider({ connection: this.connection, party_id: partyId, auth_token: authToken, public_key: publicKey, email });
|
|
2358
2372
|
const connectionInfoRaw = localStorage.getItem("loop_connect");
|
|
2359
2373
|
if (connectionInfoRaw) {
|
|
2360
2374
|
try {
|
|
@@ -2362,24 +2376,59 @@ class LoopSDK {
|
|
|
2362
2376
|
connectionInfo.authToken = authToken;
|
|
2363
2377
|
connectionInfo.partyId = partyId;
|
|
2364
2378
|
connectionInfo.publicKey = publicKey;
|
|
2379
|
+
connectionInfo.email = email;
|
|
2365
2380
|
localStorage.setItem("loop_connect", JSON.stringify(connectionInfo));
|
|
2366
2381
|
this.onAccept?.(this.provider);
|
|
2367
2382
|
this.hideQrCode();
|
|
2368
2383
|
this.connection?.connectWebSocket(connectionInfo.ticketId, this.handleWebSocketMessage.bind(this));
|
|
2384
|
+
console.log("[LoopSDK] HANDSHAKE_ACCEPT: closing popup (if exists)");
|
|
2385
|
+
if (this.popupWindow && !this.popupWindow.closed) {
|
|
2386
|
+
this.popupWindow.close();
|
|
2387
|
+
}
|
|
2388
|
+
this.popupWindow = null;
|
|
2369
2389
|
} catch (error) {
|
|
2370
2390
|
console.error("Failed to update local storage with auth token.", error);
|
|
2371
2391
|
}
|
|
2372
2392
|
}
|
|
2373
2393
|
}
|
|
2374
2394
|
} else if (message.type === "handshake_reject" /* HANDSHAKE_REJECT */) {
|
|
2395
|
+
console.log("[LoopSDK] Entering HANDSHAKE_REJECT flow");
|
|
2375
2396
|
localStorage.removeItem("loop_connect");
|
|
2376
2397
|
this.connection?.ws?.close();
|
|
2377
2398
|
this.onReject?.();
|
|
2378
2399
|
this.hideQrCode();
|
|
2400
|
+
console.log("[LoopSDK] HANDSHAKE_REJECT: closing popup (if exists)");
|
|
2401
|
+
if (this.popupWindow && !this.popupWindow.closed) {
|
|
2402
|
+
this.popupWindow.close();
|
|
2403
|
+
}
|
|
2404
|
+
this.popupWindow = null;
|
|
2379
2405
|
} else if (this.provider) {
|
|
2380
2406
|
this.provider.handleResponse(message);
|
|
2381
2407
|
}
|
|
2382
2408
|
}
|
|
2409
|
+
openWallet(url) {
|
|
2410
|
+
if (typeof window === "undefined") {
|
|
2411
|
+
return;
|
|
2412
|
+
}
|
|
2413
|
+
if (this.openMode === "popup") {
|
|
2414
|
+
const width = 480;
|
|
2415
|
+
const height = 720;
|
|
2416
|
+
const left = (window.innerWidth - width) / 2 + window.screenX;
|
|
2417
|
+
const top = (window.innerWidth - height) / 2 + window.screenY;
|
|
2418
|
+
const features = `width=${width},height=${height},` + `left=${left},top=${top},` + "menubar=no,toolbar=no,location=no," + "resizable=yes,scrollbars=yes,status=no";
|
|
2419
|
+
const popup = window.open(url, "loop-wallet", features);
|
|
2420
|
+
if (!popup) {
|
|
2421
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2424
|
+
this.popupWindow = popup;
|
|
2425
|
+
try {
|
|
2426
|
+
popup.focus();
|
|
2427
|
+
} catch {}
|
|
2428
|
+
return;
|
|
2429
|
+
}
|
|
2430
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
2431
|
+
}
|
|
2383
2432
|
showQrCode(url) {
|
|
2384
2433
|
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
2385
2434
|
return;
|
|
@@ -2409,7 +2458,10 @@ class LoopSDK {
|
|
|
2409
2458
|
link.textContent = "Or click here to connect";
|
|
2410
2459
|
link.style.color = "white";
|
|
2411
2460
|
link.style.marginTop = "20px";
|
|
2412
|
-
link.
|
|
2461
|
+
link.onclick = (e) => {
|
|
2462
|
+
e.preventDefault();
|
|
2463
|
+
this.openWallet(url);
|
|
2464
|
+
};
|
|
2413
2465
|
overlay.appendChild(link);
|
|
2414
2466
|
overlay.onclick = (e) => {
|
|
2415
2467
|
if (e.target === overlay) {
|