@lydianpay/lydianconnect 1.3.0 → 1.5.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 -1
- package/dist/index.cjs +77 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -2
- package/dist/index.d.ts +24 -2
- package/dist/index.js +77 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,7 +41,11 @@ lc.on((event) => {
|
|
|
41
41
|
| `icon` | no | Icon shown in the connect prompt. |
|
|
42
42
|
| `description` | no | Defaults to `appName`. |
|
|
43
43
|
|
|
44
|
-
`connect({ walletId, chainId })` — `chainId` is the chain the user is paying on (a number like `137`, or a CAIP-2 id like `'eip155:137'`).
|
|
44
|
+
`connect({ walletId, chainId })` — `chainId` is the chain the user is paying on (a number like `137`, or a CAIP-2 id like `'eip155:137'`). The connection is pinned to it: requests target it, and EVM wallets are switched onto it.
|
|
45
|
+
|
|
46
|
+
`connect({ walletId, chains })` — multi-network discovery: propose every chain the app can serve and let the wallet approve a subset, reported on `connection.approvedChains` (WalletConnect sessions only; SDK/injected connections leave it `undefined`). Nothing is pinned and no chain switch is forced. Connect again with `chainId` once the user picks a chain — a WalletConnect session that approved it is reused without a second prompt.
|
|
47
|
+
|
|
48
|
+
The WalletConnect client also advertises a return link derived from the page URL (origin + path, no query/hash); wallets may use it to bring the user back to the page after a deep-link approval.
|
|
45
49
|
|
|
46
50
|
## Supported wallets
|
|
47
51
|
|
package/dist/index.cjs
CHANGED
|
@@ -156,6 +156,20 @@ function buildNamespace(chainId) {
|
|
|
156
156
|
}
|
|
157
157
|
};
|
|
158
158
|
}
|
|
159
|
+
function buildNamespaces(chains) {
|
|
160
|
+
const byName = /* @__PURE__ */ new Map();
|
|
161
|
+
chains.forEach((chain) => {
|
|
162
|
+
const single = buildNamespace(chain);
|
|
163
|
+
const caip = single.value.chains?.[0];
|
|
164
|
+
const merged = byName.get(single.name);
|
|
165
|
+
if (!merged) {
|
|
166
|
+
byName.set(single.name, single);
|
|
167
|
+
} else if (caip && !merged.value.chains?.includes(caip)) {
|
|
168
|
+
merged.value.chains = [...merged.value.chains ?? [], caip];
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
return [...byName.values()];
|
|
172
|
+
}
|
|
159
173
|
|
|
160
174
|
// node_modules/@lydianpay/lydianconnect-catalog/dist/index.js
|
|
161
175
|
var ICON_BASE = "https://wallet-assets.lydian.com/wallets";
|
|
@@ -253,7 +267,7 @@ var WALLET_CATALOG = WALLETS.map((w) => ({
|
|
|
253
267
|
|
|
254
268
|
// src/core/connector.ts
|
|
255
269
|
function requestedChain(req) {
|
|
256
|
-
return req.
|
|
270
|
+
return req.pinned;
|
|
257
271
|
}
|
|
258
272
|
var BaseConnector = class {
|
|
259
273
|
constructor() {
|
|
@@ -304,6 +318,10 @@ var BaseConnector = class {
|
|
|
304
318
|
function deriveUrl() {
|
|
305
319
|
return typeof window !== "undefined" ? window.location.origin : "";
|
|
306
320
|
}
|
|
321
|
+
function deriveRedirectUrl() {
|
|
322
|
+
if (typeof window === "undefined") return "";
|
|
323
|
+
return window.location.origin + window.location.pathname;
|
|
324
|
+
}
|
|
307
325
|
|
|
308
326
|
// src/connectors/eip155/chain.ts
|
|
309
327
|
var CHAIN_SETTLE = { timeoutMs: 4e3, intervalMs: 100 };
|
|
@@ -609,9 +627,8 @@ function rpcFor2(provider) {
|
|
|
609
627
|
return ({ method, params }) => rpc(provider, method, params);
|
|
610
628
|
}
|
|
611
629
|
function evmChainIds(req) {
|
|
612
|
-
const
|
|
613
|
-
|
|
614
|
-
return Number.isFinite(n) && n > 0 ? [n] : void 0;
|
|
630
|
+
const ids = (req.namespace.value.chains ?? []).map((chain) => Number(chain.split(":")[1])).filter((n) => Number.isFinite(n) && n > 0);
|
|
631
|
+
return ids.length > 0 ? ids : void 0;
|
|
615
632
|
}
|
|
616
633
|
|
|
617
634
|
// src/connectors/injected/connector.ts
|
|
@@ -1264,13 +1281,16 @@ var WalletConnectConnector = class extends BaseConnector {
|
|
|
1264
1281
|
}
|
|
1265
1282
|
async getClient() {
|
|
1266
1283
|
if (this.client) return this.client;
|
|
1284
|
+
const redirectUrl = deriveRedirectUrl();
|
|
1267
1285
|
const client = await SignClient__default.default.init({
|
|
1268
1286
|
projectId: this.options.projectId,
|
|
1269
1287
|
metadata: {
|
|
1270
1288
|
name: this.app.appName,
|
|
1271
1289
|
description: this.app.description ?? this.app.appName,
|
|
1272
1290
|
url: deriveUrl(),
|
|
1273
|
-
icons: this.app.icon ? [this.app.icon] : []
|
|
1291
|
+
icons: this.app.icon ? [this.app.icon] : [],
|
|
1292
|
+
// Wallets may use this to return the user after deep-link approvals.
|
|
1293
|
+
...redirectUrl ? { redirect: { universal: redirectUrl } } : {}
|
|
1274
1294
|
},
|
|
1275
1295
|
relayUrl: this.options.relayUrl
|
|
1276
1296
|
});
|
|
@@ -1302,8 +1322,11 @@ var WalletConnectConnector = class extends BaseConnector {
|
|
|
1302
1322
|
const client = await this.getClient();
|
|
1303
1323
|
const reused = await this.tryReuse(client, req);
|
|
1304
1324
|
if (reused) return reused;
|
|
1325
|
+
const proposed = [req.namespace, ...req.extraNamespaces ?? []];
|
|
1305
1326
|
const { uri, approval } = await client.connect({
|
|
1306
|
-
|
|
1327
|
+
optionalNamespaces: Object.fromEntries(
|
|
1328
|
+
proposed.map((ns) => [ns.name, ns.value])
|
|
1329
|
+
)
|
|
1307
1330
|
});
|
|
1308
1331
|
if (!uri) throw new Error("WalletConnect did not return a pairing URI");
|
|
1309
1332
|
const link = isMobile() ? this.links[req.walletId] : void 0;
|
|
@@ -1335,7 +1358,8 @@ var WalletConnectConnector = class extends BaseConnector {
|
|
|
1335
1358
|
client,
|
|
1336
1359
|
req.walletId,
|
|
1337
1360
|
session,
|
|
1338
|
-
req.namespace
|
|
1361
|
+
req.namespace,
|
|
1362
|
+
req.pinned
|
|
1339
1363
|
);
|
|
1340
1364
|
this.topics.set(req.walletId, session.topic);
|
|
1341
1365
|
this.persist();
|
|
@@ -1402,21 +1426,32 @@ var WalletConnectConnector = class extends BaseConnector {
|
|
|
1402
1426
|
return null;
|
|
1403
1427
|
}
|
|
1404
1428
|
const ns = session.namespaces[req.namespace.name];
|
|
1405
|
-
|
|
1406
|
-
if (
|
|
1407
|
-
return this.toConnection(
|
|
1429
|
+
if (!ns) return null;
|
|
1430
|
+
if (req.pinned && !grantedChains(ns).includes(req.pinned)) return null;
|
|
1431
|
+
return this.toConnection(
|
|
1432
|
+
client,
|
|
1433
|
+
req.walletId,
|
|
1434
|
+
session,
|
|
1435
|
+
req.namespace,
|
|
1436
|
+
req.pinned
|
|
1437
|
+
);
|
|
1408
1438
|
}
|
|
1409
|
-
toConnection(client, walletId, session, namespace) {
|
|
1439
|
+
toConnection(client, walletId, session, namespace, wanted) {
|
|
1410
1440
|
const ns = session.namespaces[namespace.name];
|
|
1411
1441
|
const account = (ns?.accounts ?? []).map((a) => a.split(":")[2]).find((a) => !!a) ?? "";
|
|
1412
|
-
const approved =
|
|
1413
|
-
const wanted = namespace.value.chains?.[0];
|
|
1442
|
+
const approved = grantedChains(ns);
|
|
1414
1443
|
const chainId = wanted && approved.includes(wanted) ? wanted : approved[0] ?? `${namespace.name}:1`;
|
|
1444
|
+
const approvedChains = [
|
|
1445
|
+
...new Set(
|
|
1446
|
+
Object.values(session.namespaces).flatMap((n) => grantedChains(n))
|
|
1447
|
+
)
|
|
1448
|
+
];
|
|
1415
1449
|
const topic = session.topic;
|
|
1416
1450
|
return {
|
|
1417
1451
|
walletId,
|
|
1418
1452
|
account,
|
|
1419
1453
|
chainId,
|
|
1454
|
+
approvedChains,
|
|
1420
1455
|
request: (args) => client.request({
|
|
1421
1456
|
topic,
|
|
1422
1457
|
chainId,
|
|
@@ -1477,6 +1512,11 @@ var WalletConnectConnector = class extends BaseConnector {
|
|
|
1477
1512
|
}
|
|
1478
1513
|
}
|
|
1479
1514
|
};
|
|
1515
|
+
function grantedChains(ns) {
|
|
1516
|
+
if (!ns) return [];
|
|
1517
|
+
if (ns.chains?.length) return ns.chains;
|
|
1518
|
+
return (ns.accounts ?? []).map((a) => a.split(":").slice(0, 2).join(":"));
|
|
1519
|
+
}
|
|
1480
1520
|
function firstNamespace(session) {
|
|
1481
1521
|
const name = Object.keys(session.namespaces)[0];
|
|
1482
1522
|
if (!name) return null;
|
|
@@ -1521,14 +1561,35 @@ var LydianConnect = class {
|
|
|
1521
1561
|
return this.manager.init();
|
|
1522
1562
|
}
|
|
1523
1563
|
async connect(input) {
|
|
1524
|
-
|
|
1564
|
+
const chains = "chains" in input ? input.chains : void 0;
|
|
1565
|
+
const chainId = "chainId" in input ? input.chainId : void 0;
|
|
1566
|
+
if (chains !== void 0 && chainId !== void 0) {
|
|
1567
|
+
throw new Error(
|
|
1568
|
+
"connect() takes either chainId (pinned) or chains (discovery), not both"
|
|
1569
|
+
);
|
|
1570
|
+
}
|
|
1571
|
+
if (chains !== void 0) {
|
|
1572
|
+
const [primary, ...extra] = buildNamespaces(chains);
|
|
1573
|
+
if (!primary) {
|
|
1574
|
+
throw new Error("connect() discovery requires a non-empty chains list");
|
|
1575
|
+
}
|
|
1576
|
+
return this.manager.connect({
|
|
1577
|
+
walletId: input.walletId,
|
|
1578
|
+
namespace: primary,
|
|
1579
|
+
extraNamespaces: extra.length > 0 ? extra : void 0,
|
|
1580
|
+
signal: input.signal
|
|
1581
|
+
});
|
|
1582
|
+
}
|
|
1583
|
+
if (chainId === void 0 || chainId === null) {
|
|
1525
1584
|
throw new Error(
|
|
1526
|
-
'connect() requires a chainId (a number like 137 or an "eip155:<id>" string)'
|
|
1585
|
+
'connect() requires a chainId (a number like 137 or an "eip155:<id>" string) or a chains list'
|
|
1527
1586
|
);
|
|
1528
1587
|
}
|
|
1588
|
+
const namespace = buildNamespace(chainId);
|
|
1529
1589
|
return this.manager.connect({
|
|
1530
1590
|
walletId: input.walletId,
|
|
1531
|
-
namespace
|
|
1591
|
+
namespace,
|
|
1592
|
+
pinned: namespace.value.chains?.[0],
|
|
1532
1593
|
signal: input.signal
|
|
1533
1594
|
});
|
|
1534
1595
|
}
|