@fivenorth/loop-sdk 0.9.0 → 0.11.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/dist/index.js CHANGED
@@ -2,6 +2,7 @@ var __create = Object.create;
2
2
  var __getProtoOf = Object.getPrototypeOf;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
7
  var __toESM = (mod, isNodeMode, target) => {
7
8
  target = mod != null ? __create(__getProtoOf(mod)) : {};
@@ -14,7 +15,38 @@ var __toESM = (mod, isNodeMode, target) => {
14
15
  });
15
16
  return to;
16
17
  };
18
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
19
+ var __toCommonJS = (from) => {
20
+ var entry = __moduleCache.get(from), desc;
21
+ if (entry)
22
+ return entry;
23
+ entry = __defProp({}, "__esModule", { value: true });
24
+ if (from && typeof from === "object" || typeof from === "function")
25
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
26
+ get: () => from[key],
27
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
28
+ }));
29
+ __moduleCache.set(from, entry);
30
+ return entry;
31
+ };
17
32
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
33
+ var __export = (target, all) => {
34
+ for (var name in all)
35
+ __defProp(target, name, {
36
+ get: all[name],
37
+ enumerable: true,
38
+ configurable: true,
39
+ set: (newValue) => all[name] = () => newValue
40
+ });
41
+ };
42
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
43
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
44
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
45
+ }) : x)(function(x) {
46
+ if (typeof require !== "undefined")
47
+ return require.apply(this, arguments);
48
+ throw Error('Dynamic require of "' + x + '" is not supported');
49
+ });
18
50
 
19
51
  // node_modules/qrcode/lib/can-promise.js
20
52
  var require_can_promise = __commonJS((exports, module) => {
@@ -2092,229 +2124,6 @@ function isUnauthCode(code) {
2092
2124
  return UNAUTH_CODES.has(code);
2093
2125
  }
2094
2126
 
2095
- // src/connection.ts
2096
- class Connection {
2097
- walletUrl = "https://cantonloop.com";
2098
- apiUrl = "https://cantonloop.com";
2099
- ws = null;
2100
- network = "main";
2101
- ticketId = null;
2102
- onMessageHandler = null;
2103
- reconnectPromise = null;
2104
- status = "disconnected";
2105
- constructor({ network, walletUrl, apiUrl }) {
2106
- this.network = network || "main";
2107
- switch (this.network) {
2108
- case "local":
2109
- this.walletUrl = "http://localhost:3000";
2110
- this.apiUrl = "http://localhost:8080";
2111
- break;
2112
- case "devnet":
2113
- case "dev":
2114
- this.walletUrl = "https://devnet.cantonloop.com";
2115
- this.apiUrl = "https://devnet.cantonloop.com";
2116
- break;
2117
- case "testnet":
2118
- case "test":
2119
- this.walletUrl = "https://testnet.cantonloop.com";
2120
- this.apiUrl = "https://testnet.cantonloop.com";
2121
- break;
2122
- case "mainnet":
2123
- case "main":
2124
- this.walletUrl = "https://cantonloop.com";
2125
- this.apiUrl = "https://cantonloop.com";
2126
- break;
2127
- }
2128
- if (walletUrl) {
2129
- this.walletUrl = walletUrl;
2130
- }
2131
- if (apiUrl) {
2132
- this.apiUrl = apiUrl;
2133
- }
2134
- }
2135
- connectInProgress() {
2136
- return this.status === "connecting" || this.status === "connected";
2137
- }
2138
- async getTicket(appName, sessionId, version) {
2139
- const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/tickets`, {
2140
- method: "POST",
2141
- headers: {
2142
- "Content-Type": "application/json"
2143
- },
2144
- body: JSON.stringify({
2145
- app_name: appName,
2146
- session_id: sessionId,
2147
- version
2148
- })
2149
- });
2150
- if (!response.ok) {
2151
- throw new Error("Failed to get ticket from server.");
2152
- }
2153
- return response.json();
2154
- }
2155
- async getHolding(authToken) {
2156
- const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/account/holding`, {
2157
- method: "GET",
2158
- headers: {
2159
- "Content-Type": "application/json",
2160
- Authorization: `Bearer ${authToken}`
2161
- }
2162
- });
2163
- if (!response.ok) {
2164
- throw new Error("Failed to get holdings.");
2165
- }
2166
- return response.json();
2167
- }
2168
- async getActiveContracts(authToken, params) {
2169
- const url = new URL(`${this.apiUrl}/api/v1/.connect/pair/account/active-contracts`);
2170
- if (params?.templateId) {
2171
- url.searchParams.append("templateId", params.templateId);
2172
- }
2173
- if (params?.interfaceId) {
2174
- url.searchParams.append("interfaceId", params.interfaceId);
2175
- }
2176
- const response = await fetch(url.toString(), {
2177
- method: "GET",
2178
- headers: {
2179
- "Content-Type": "application/json",
2180
- Authorization: `Bearer ${authToken}`
2181
- }
2182
- });
2183
- if (!response.ok) {
2184
- throw new Error("Failed to get active contracts.");
2185
- }
2186
- return response.json();
2187
- }
2188
- async prepareTransfer(authToken, params) {
2189
- const payload = {
2190
- recipient: params.recipient,
2191
- amount: params.amount
2192
- };
2193
- if (params.instrument) {
2194
- if (params.instrument.instrument_admin) {
2195
- payload.instrument_admin = params.instrument.instrument_admin;
2196
- }
2197
- if (params.instrument.instrument_id) {
2198
- payload.instrument_id = params.instrument.instrument_id;
2199
- }
2200
- }
2201
- if (params.requested_at) {
2202
- payload.requested_at = params.requested_at;
2203
- }
2204
- if (params.execute_before) {
2205
- payload.execute_before = params.execute_before;
2206
- }
2207
- const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/transfer`, {
2208
- method: "POST",
2209
- headers: {
2210
- "Content-Type": "application/json",
2211
- Authorization: `Bearer ${authToken}`
2212
- },
2213
- body: JSON.stringify(payload)
2214
- });
2215
- if (!response.ok) {
2216
- throw new Error("Failed to prepare transfer.");
2217
- }
2218
- const data = await response.json();
2219
- return data.payload;
2220
- }
2221
- async verifySession(authToken) {
2222
- const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/account`, {
2223
- method: "GET",
2224
- headers: {
2225
- "Content-Type": "application/json",
2226
- Authorization: `Bearer ${authToken}`
2227
- }
2228
- });
2229
- if (!response.ok) {
2230
- if (response.status === 401 || response.status === 403) {
2231
- throw new UnauthorizedError;
2232
- }
2233
- throw new Error(`Session verification failed with status ${response.status}.`);
2234
- }
2235
- const data = await response.json();
2236
- const email = data?.email;
2237
- if (!data?.party_id || !data?.public_key) {
2238
- throw new Error("Invalid session verification response.");
2239
- }
2240
- const account = {
2241
- party_id: data?.party_id,
2242
- auth_token: authToken,
2243
- public_key: data?.public_key,
2244
- email,
2245
- has_preapproval: data?.has_preapproval,
2246
- has_merge_delegation: data?.has_merge_delegation,
2247
- usdc_bridge_access: data?.usdc_bridge_access
2248
- };
2249
- return account;
2250
- }
2251
- connectWebSocket(ticketId, onMessage) {
2252
- if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) && this.ticketId !== ticketId) {
2253
- this.ws.close();
2254
- this.ws = null;
2255
- }
2256
- if (this.status === "connecting" || this.status === "connected") {
2257
- return;
2258
- }
2259
- this.onMessageHandler = onMessage;
2260
- this.ticketId = ticketId;
2261
- this.status = "connecting";
2262
- this.attachWebSocket(ticketId, onMessage);
2263
- }
2264
- reconnect() {
2265
- if (!this.ticketId || !this.onMessageHandler) {
2266
- return Promise.reject(new Error("Cannot reconnect without a known ticket."));
2267
- }
2268
- return new Promise((resolve, reject) => {
2269
- let opened = false;
2270
- this.attachWebSocket(this.ticketId, this.onMessageHandler, () => {
2271
- opened = true;
2272
- resolve();
2273
- }, () => {
2274
- if (opened) {
2275
- return;
2276
- }
2277
- reject(new Error("Failed to reconnect to ticket server."));
2278
- }, () => {
2279
- if (opened) {
2280
- return;
2281
- }
2282
- reject(new Error("Failed to reconnect to ticket server."));
2283
- });
2284
- });
2285
- }
2286
- websocketUrl(ticketId) {
2287
- return `${this.network === "local" ? "ws" : "wss"}://${this.apiUrl.replace("https://", "").replace("http://", "")}/api/v1/.connect/pair/ws/${encodeURIComponent(ticketId)}`;
2288
- }
2289
- attachWebSocket(ticketId, onMessage, onOpen, onError, onClose) {
2290
- const wsUrl = this.websocketUrl(ticketId);
2291
- const ws = new WebSocket(wsUrl);
2292
- ws.onmessage = onMessage;
2293
- ws.onopen = () => {
2294
- this.status = "connected";
2295
- console.log("[LoopSDK] Connected to ticket server.");
2296
- onOpen?.();
2297
- };
2298
- ws.onclose = (event) => {
2299
- this.status = "disconnected";
2300
- if (this.ws === ws) {
2301
- this.ws = null;
2302
- }
2303
- console.log("[LoopSDK] Disconnected from ticket server.");
2304
- onClose?.(event);
2305
- };
2306
- ws.onerror = (event) => {
2307
- this.status = "disconnected";
2308
- ws.close();
2309
- if (this.ws === ws) {
2310
- this.ws = null;
2311
- }
2312
- onError?.(event);
2313
- };
2314
- this.ws = ws;
2315
- }
2316
- }
2317
-
2318
2127
  // src/types.ts
2319
2128
  var MessageType;
2320
2129
  ((MessageType2) => {
@@ -2396,14 +2205,18 @@ class Provider {
2396
2205
  return this.connection.getActiveContracts(this.auth_token, params);
2397
2206
  }
2398
2207
  async submitTransaction(payload, options) {
2399
- return this.sendRequest("run_transaction" /* RUN_TRANSACTION */, payload, options);
2208
+ const requestPayload = options?.estimateTraffic ? { ...payload, estimate_traffic: true } : payload;
2209
+ const executionMode = options?.executionMode;
2210
+ const finalPayload = executionMode === "wait" ? { ...requestPayload, execution_mode: "wait" } : requestPayload;
2211
+ return this.sendRequest("run_transaction" /* RUN_TRANSACTION */, finalPayload, options);
2400
2212
  }
2401
2213
  async submitAndWaitForTransaction(payload, options) {
2402
- return this.sendRequest("run_transaction" /* RUN_TRANSACTION */, { ...payload, execution_mode: "wait" }, options);
2214
+ const requestPayload = options?.estimateTraffic ? { ...payload, estimate_traffic: true } : payload;
2215
+ return this.sendRequest("run_transaction" /* RUN_TRANSACTION */, { ...requestPayload, execution_mode: "wait" }, options);
2403
2216
  }
2404
2217
  async transfer(recipient, amount, instrument, options) {
2405
2218
  const amountStr = typeof amount === "number" ? amount.toString() : amount;
2406
- const { requestedAt, executeBefore, requestTimeout } = options || {};
2219
+ const { requestedAt, executeBefore, requestTimeout, estimateTraffic, memo } = options || {};
2407
2220
  const message = options?.message;
2408
2221
  const resolveDate = (value, fallbackMs) => {
2409
2222
  if (value instanceof Date) {
@@ -2429,6 +2242,9 @@ class Provider {
2429
2242
  requested_at: requestedAtIso,
2430
2243
  execute_before: executeBeforeIso
2431
2244
  };
2245
+ if (memo) {
2246
+ transferRequest.memo = memo;
2247
+ }
2432
2248
  const preparedPayload = await this.connection.prepareTransfer(this.auth_token, transferRequest);
2433
2249
  const submitFn = options?.executionMode === "wait" ? this.submitAndWaitForTransaction.bind(this) : this.submitTransaction.bind(this);
2434
2250
  return submitFn({
@@ -2438,7 +2254,7 @@ class Provider {
2438
2254
  actAs: preparedPayload.actAs,
2439
2255
  readAs: preparedPayload.readAs,
2440
2256
  synchronizerId: preparedPayload.synchronizerId
2441
- }, { requestTimeout, message });
2257
+ }, { requestTimeout, message, estimateTraffic });
2442
2258
  }
2443
2259
  async signMessage(message) {
2444
2260
  return this.sendRequest("sign_raw_message" /* SIGN_RAW_MESSAGE */, message);
@@ -2551,6 +2367,283 @@ class Provider {
2551
2367
  }
2552
2368
  }
2553
2369
 
2370
+ // src/connection.ts
2371
+ class Connection {
2372
+ walletUrl = "https://cantonloop.com";
2373
+ apiUrl = "https://cantonloop.com";
2374
+ ws = null;
2375
+ network = "main";
2376
+ ticketId = null;
2377
+ onMessageHandler = null;
2378
+ reconnectPromise = null;
2379
+ status = "disconnected";
2380
+ constructor({ network, walletUrl, apiUrl }) {
2381
+ this.network = network || "main";
2382
+ switch (this.network) {
2383
+ case "local":
2384
+ this.walletUrl = "http://localhost:3000";
2385
+ this.apiUrl = "http://localhost:8080";
2386
+ break;
2387
+ case "devnet":
2388
+ case "dev":
2389
+ this.walletUrl = "https://devnet.cantonloop.com";
2390
+ this.apiUrl = "https://devnet.cantonloop.com";
2391
+ break;
2392
+ case "testnet":
2393
+ case "test":
2394
+ this.walletUrl = "https://testnet.cantonloop.com";
2395
+ this.apiUrl = "https://testnet.cantonloop.com";
2396
+ break;
2397
+ case "mainnet":
2398
+ case "main":
2399
+ this.walletUrl = "https://cantonloop.com";
2400
+ this.apiUrl = "https://cantonloop.com";
2401
+ break;
2402
+ }
2403
+ if (walletUrl) {
2404
+ this.walletUrl = walletUrl;
2405
+ }
2406
+ if (apiUrl) {
2407
+ this.apiUrl = apiUrl;
2408
+ }
2409
+ }
2410
+ connectInProgress() {
2411
+ return this.status === "connecting" || this.status === "connected";
2412
+ }
2413
+ async getTicket(appName, sessionId, version) {
2414
+ const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/tickets`, {
2415
+ method: "POST",
2416
+ headers: {
2417
+ "Content-Type": "application/json"
2418
+ },
2419
+ body: JSON.stringify({
2420
+ app_name: appName,
2421
+ session_id: sessionId,
2422
+ version
2423
+ })
2424
+ });
2425
+ if (!response.ok) {
2426
+ throw new Error("Failed to get ticket from server.");
2427
+ }
2428
+ return response.json();
2429
+ }
2430
+ async getHolding(authToken) {
2431
+ const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/account/holding`, {
2432
+ method: "GET",
2433
+ headers: {
2434
+ "Content-Type": "application/json",
2435
+ Authorization: `Bearer ${authToken}`
2436
+ }
2437
+ });
2438
+ if (!response.ok) {
2439
+ throw new Error("Failed to get holdings. " + await response.text());
2440
+ }
2441
+ return response.json();
2442
+ }
2443
+ async getActiveContracts(authToken, params) {
2444
+ const url = new URL(`${this.apiUrl}/api/v1/.connect/pair/account/active-contracts`);
2445
+ if (params?.templateId) {
2446
+ url.searchParams.append("templateId", params.templateId);
2447
+ }
2448
+ if (params?.interfaceId) {
2449
+ url.searchParams.append("interfaceId", params.interfaceId);
2450
+ }
2451
+ const response = await fetch(url.toString(), {
2452
+ method: "GET",
2453
+ headers: {
2454
+ "Content-Type": "application/json",
2455
+ Authorization: `Bearer ${authToken}`
2456
+ }
2457
+ });
2458
+ if (!response.ok) {
2459
+ throw new Error("Failed to get active contracts.");
2460
+ }
2461
+ return response.json();
2462
+ }
2463
+ async prepareTransfer(authToken, params) {
2464
+ const payload = {
2465
+ recipient: params.recipient,
2466
+ amount: params.amount
2467
+ };
2468
+ if (params.instrument) {
2469
+ if (params.instrument.instrument_admin) {
2470
+ payload.instrument_admin = params.instrument.instrument_admin;
2471
+ }
2472
+ if (params.instrument.instrument_id) {
2473
+ payload.instrument_id = params.instrument.instrument_id;
2474
+ }
2475
+ }
2476
+ if (params.requested_at) {
2477
+ payload.requested_at = params.requested_at;
2478
+ }
2479
+ if (params.execute_before) {
2480
+ payload.execute_before = params.execute_before;
2481
+ }
2482
+ if (params.memo) {
2483
+ payload.memo = params.memo;
2484
+ }
2485
+ const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/transfer`, {
2486
+ method: "POST",
2487
+ headers: {
2488
+ "Content-Type": "application/json",
2489
+ Authorization: `Bearer ${authToken}`
2490
+ },
2491
+ body: JSON.stringify(payload)
2492
+ });
2493
+ if (!response.ok) {
2494
+ console.error("Failed to prepare transfer.", await response.text());
2495
+ throw new Error("Failed to prepare transfer.");
2496
+ }
2497
+ const data = await response.json();
2498
+ return data.payload;
2499
+ }
2500
+ async verifySession(authToken) {
2501
+ const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/account`, {
2502
+ method: "GET",
2503
+ headers: {
2504
+ "Content-Type": "application/json",
2505
+ Authorization: `Bearer ${authToken}`
2506
+ }
2507
+ });
2508
+ if (!response.ok) {
2509
+ if (response.status === 401 || response.status === 403) {
2510
+ throw new UnauthorizedError;
2511
+ }
2512
+ throw new Error(`Session verification failed with status ${response.status}.`);
2513
+ }
2514
+ const data = await response.json();
2515
+ const email = data?.email;
2516
+ if (!data?.party_id || !data?.public_key) {
2517
+ throw new Error("Invalid session verification response.");
2518
+ }
2519
+ const account = {
2520
+ party_id: data?.party_id,
2521
+ auth_token: authToken,
2522
+ public_key: data?.public_key,
2523
+ email,
2524
+ has_preapproval: data?.has_preapproval,
2525
+ has_merge_delegation: data?.has_merge_delegation,
2526
+ usdc_bridge_access: data?.usdc_bridge_access
2527
+ };
2528
+ return account;
2529
+ }
2530
+ connectWebSocket(ticketId, onMessage) {
2531
+ if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) && this.ticketId !== ticketId) {
2532
+ this.ws.close();
2533
+ this.ws = null;
2534
+ }
2535
+ if (this.status === "connecting" || this.status === "connected") {
2536
+ return;
2537
+ }
2538
+ this.onMessageHandler = onMessage;
2539
+ this.ticketId = ticketId;
2540
+ this.status = "connecting";
2541
+ this.attachWebSocket(ticketId, onMessage);
2542
+ }
2543
+ reconnect() {
2544
+ if (!this.ticketId || !this.onMessageHandler) {
2545
+ return Promise.reject(new Error("Cannot reconnect without a known ticket."));
2546
+ }
2547
+ return new Promise((resolve, reject) => {
2548
+ let opened = false;
2549
+ this.attachWebSocket(this.ticketId, this.onMessageHandler, () => {
2550
+ opened = true;
2551
+ resolve();
2552
+ }, () => {
2553
+ if (opened) {
2554
+ return;
2555
+ }
2556
+ reject(new Error("Failed to reconnect to ticket server."));
2557
+ }, () => {
2558
+ if (opened) {
2559
+ return;
2560
+ }
2561
+ reject(new Error("Failed to reconnect to ticket server."));
2562
+ });
2563
+ });
2564
+ }
2565
+ async exchangeApiKey({ publicKey, signature, epoch }) {
2566
+ const response = await fetch(`${this.apiUrl}/api/v1/.connect/pair/apikey`, {
2567
+ method: "POST",
2568
+ headers: {
2569
+ "Content-Type": "application/json"
2570
+ },
2571
+ body: JSON.stringify({
2572
+ public_key: publicKey,
2573
+ signature,
2574
+ epoch
2575
+ })
2576
+ });
2577
+ if (!response.ok) {
2578
+ throw new Error("Failed to get API key from server.");
2579
+ }
2580
+ return response.json();
2581
+ }
2582
+ prepareTransaction(session, params) {
2583
+ return fetch(`${this.apiUrl}/api/v1/.connect/tickets/prepare-transaction`, {
2584
+ method: "POST",
2585
+ headers: {
2586
+ "Content-Type": "application/json",
2587
+ Authorization: `Bearer ${session.userApiKey}`
2588
+ },
2589
+ body: JSON.stringify({
2590
+ payload: params,
2591
+ ticket_id: session.ticketId
2592
+ })
2593
+ }).then((response) => response.json());
2594
+ }
2595
+ async executeTransaction(session, params) {
2596
+ if (!session.ticketId) {
2597
+ throw new Error("Ticket ID is required");
2598
+ }
2599
+ const resp = fetch(`${this.apiUrl}/api/v1/.connect/tickets/execute-transaction`, {
2600
+ method: "POST",
2601
+ headers: {
2602
+ "Content-Type": "application/json",
2603
+ Authorization: `Bearer ${session.userApiKey}`
2604
+ },
2605
+ body: JSON.stringify({
2606
+ ticket_id: session.ticketId,
2607
+ request_id: generateRequestId(),
2608
+ command_id: params.command_id,
2609
+ signature: params.signature,
2610
+ transaction_data: params.transaction_data
2611
+ })
2612
+ });
2613
+ return (await resp).json();
2614
+ }
2615
+ websocketUrl(ticketId) {
2616
+ return `${this.network === "local" ? "ws" : "wss"}://${this.apiUrl.replace("https://", "").replace("http://", "")}/api/v1/.connect/pair/ws/${encodeURIComponent(ticketId)}`;
2617
+ }
2618
+ attachWebSocket(ticketId, onMessage, onOpen, onError, onClose) {
2619
+ const wsUrl = this.websocketUrl(ticketId);
2620
+ const ws = new WebSocket(wsUrl);
2621
+ ws.onmessage = onMessage;
2622
+ ws.onopen = () => {
2623
+ this.status = "connected";
2624
+ console.log("[LoopSDK] Connected to ticket server.");
2625
+ onOpen?.();
2626
+ };
2627
+ ws.onclose = (event) => {
2628
+ this.status = "disconnected";
2629
+ if (this.ws === ws) {
2630
+ this.ws = null;
2631
+ }
2632
+ console.log("[LoopSDK] Disconnected from ticket server.");
2633
+ onClose?.(event);
2634
+ };
2635
+ ws.onerror = (event) => {
2636
+ this.status = "disconnected";
2637
+ ws.close();
2638
+ if (this.ws === ws) {
2639
+ this.ws = null;
2640
+ }
2641
+ onError?.(event);
2642
+ };
2643
+ this.ws = ws;
2644
+ }
2645
+ }
2646
+
2554
2647
  // src/session.ts
2555
2648
  var STORAGE_KEY_LOOP_CONNECT = "loop_connect";
2556
2649
 
@@ -2561,14 +2654,16 @@ class SessionInfo {
2561
2654
  partyId;
2562
2655
  publicKey;
2563
2656
  email;
2657
+ userApiKey;
2564
2658
  _isAuthorized = false;
2565
- constructor({ sessionId, ticketId, authToken, partyId, publicKey, email }) {
2659
+ constructor({ sessionId, ticketId, authToken, partyId, publicKey, email, userApiKey }) {
2566
2660
  this.sessionId = sessionId;
2567
2661
  this.ticketId = ticketId;
2568
2662
  this.authToken = authToken;
2569
2663
  this.partyId = partyId;
2570
2664
  this.publicKey = publicKey;
2571
2665
  this.email = email;
2666
+ this.userApiKey = userApiKey;
2572
2667
  }
2573
2668
  setTicketId(ticketId) {
2574
2669
  this.ticketId = ticketId;
@@ -2950,28 +3045,31 @@ class LoopSDK {
2950
3045
  .loop-connect {
2951
3046
  position: fixed;
2952
3047
  inset: 0;
2953
- background: oklch(0.222 0 0 / 0.85);
3048
+ background: rgba(0, 0, 0, 0.85);
2954
3049
  backdrop-filter: blur(8px);
2955
3050
  display: flex;
2956
3051
  justify-content: center;
2957
3052
  align-items: center;
2958
3053
  z-index: 10000;
2959
- font-family: system-ui, -apple-system, sans-serif;
3054
+ font-family: "Inter", system-ui, -apple-system, sans-serif;
2960
3055
  animation: fadeIn 0.2s ease-out;
2961
3056
  }
2962
3057
  .loop-connect dialog {
2963
3058
  position: relative;
2964
3059
  overflow: hidden;
2965
- background: oklch(0.253 0.008 274.6);
2966
- box-shadow: 0 4px 24px oklch(0 0 0 / 0.1);
2967
- border: 1px solid oklch(0.41 0.01 278.4);
2968
- border-radius: 32px;
2969
- padding: 24px;
3060
+ background: #080808;
3061
+ box-shadow: 0 24px 60px -12px rgba(0, 0, 0, 0.5);
3062
+ border-radius: 40px;
3063
+ border: none;
3064
+ width: 340px;
3065
+ height: 534px;
3066
+ box-sizing: border-box;
3067
+ padding: 32px;
2970
3068
  display: flex;
2971
3069
  flex-direction: column;
2972
3070
  align-items: center;
2973
- gap: 16px;
2974
- color: oklch(0.975 0.005 280);
3071
+ gap: 0;
3072
+ color: #ffffff;
2975
3073
  }
2976
3074
  .loop-connect .bg-logo {
2977
3075
  position: absolute;
@@ -2983,56 +3081,89 @@ class LoopSDK {
2983
3081
  pointer-events: none;
2984
3082
  }
2985
3083
  .loop-connect h3 {
3084
+ position: absolute;
3085
+ top: 32px;
3086
+ left: 32px;
3087
+ right: 32px;
2986
3088
  margin: 0;
2987
3089
  font-size: 18px;
2988
- font-weight: 600;
2989
- letter-spacing: -0.015em;
3090
+ font-weight: 700;
3091
+ line-height: 27px;
3092
+ letter-spacing: -0.45px;
3093
+ text-align: center;
2990
3094
  }
2991
3095
  .loop-connect figure {
3096
+ position: absolute;
3097
+ top: 91px;
3098
+ left: 32px;
3099
+ width: 276px;
3100
+ height: 276px;
2992
3101
  margin: 0;
2993
- background: oklch(1 0 0);
2994
- padding: 8px;
2995
- border-radius: 24px;
3102
+ background: #ffffff;
3103
+ padding: 20px;
3104
+ border-radius: 8px;
2996
3105
  display: flex;
2997
3106
  justify-content: center;
2998
- border: 2px solid oklch(0.41 0.01 278.4);
2999
- box-shadow: 0 4px 24px oklch(0 0 0 / 0.1);
3107
+ border: none;
3108
+ box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1);
3109
+ box-sizing: border-box;
3000
3110
  }
3001
3111
  .loop-connect img {
3002
3112
  display: block;
3003
- width: 225px;
3004
- height: 225px;
3113
+ width: 236px;
3114
+ height: 236px;
3115
+ object-fit: contain;
3116
+ border-radius: 12px;
3005
3117
  }
3006
3118
  .loop-connect .divider {
3007
- width: 100%;
3119
+ position: absolute;
3120
+ top: 399px;
3121
+ left: 36px;
3122
+ right: 36px;
3123
+ width: auto;
3008
3124
  display: flex;
3009
3125
  align-items: center;
3010
- gap: 16px;
3011
- color: oklch(0.554 0.012 280.3);
3012
- font-size: 13px;
3013
- font-weight: 600;
3126
+ justify-content: center;
3127
+ gap: 12px;
3128
+ color: #64748b;
3129
+ font-size: 11px;
3130
+ font-weight: 700;
3131
+ letter-spacing: 0.15em;
3132
+ text-transform: uppercase;
3133
+ text-align: center;
3014
3134
  }
3015
3135
  .loop-connect .divider::before,
3016
3136
  .loop-connect .divider::after {
3017
3137
  content: "";
3018
3138
  flex: 1;
3019
3139
  height: 1px;
3020
- background: oklch(0.45 0.01 278);
3140
+ background: #1e293b;
3021
3141
  }
3022
3142
  .loop-connect button {
3023
- background: oklch(0.976 0.101 112.3);
3024
- border: 1px solid oklch(0.82 0.16 110);
3025
- color: oklch(0.222 0 0);
3026
- padding: 16px 32px;
3027
- border-radius: 24px;
3143
+ position: absolute;
3144
+ top: 447.5px;
3145
+ left: 32px;
3146
+ right: 32px;
3147
+ background: #f2ff96;
3148
+ border: none;
3149
+ color: #0f172a;
3150
+ text-align: center;
3151
+ font-family: "Inter", system-ui, -apple-system, sans-serif;
3152
+ font-style: normal;
3153
+ padding: 0 24px;
3154
+ border-radius: 8px;
3028
3155
  font-size: 15px;
3029
3156
  font-weight: 600;
3157
+ line-height: 22.5px;
3030
3158
  cursor: pointer;
3031
3159
  transition: all 0.2s ease;
3032
- width: 100%;
3160
+ width: auto;
3161
+ height: 54.5px;
3162
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2),
3163
+ 0 4px 6px -4px rgba(0, 0, 0, 0.2);
3033
3164
  }
3034
3165
  .loop-connect button:hover {
3035
- background: oklch(0.98 0.105 112.5);
3166
+ background: #f6ffb4;
3036
3167
  }
3037
3168
  @keyframes fadeIn {
3038
3169
  from { opacity: 0; }
@@ -3043,7 +3174,7 @@ class LoopSDK {
3043
3174
  }
3044
3175
  showQrCode(url) {
3045
3176
  this.injectModalStyles();
3046
- import_qrcode.default.toDataURL(url, (err, dataUrl) => {
3177
+ import_qrcode.default.toDataURL(url, { margin: 0 }, (err, dataUrl) => {
3047
3178
  if (err) {
3048
3179
  console.error("Failed to generate QR code", err);
3049
3180
  return;