@lydianpay/lydianconnect 1.4.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 +3 -1
- package/dist/index.cjs +69 -15
- 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 +69 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -46,6 +46,13 @@ interface Connection {
|
|
|
46
46
|
readonly account: string;
|
|
47
47
|
/** CAIP-2 chain id, e.g. "eip155:1". */
|
|
48
48
|
readonly chainId: string;
|
|
49
|
+
/**
|
|
50
|
+
* The CAIP-2 chains the wallet's session granted, across all namespaces.
|
|
51
|
+
* WalletConnect only — SDK and injected connections leave it undefined, since
|
|
52
|
+
* switching (`wallet_switchEthereumChain`) has no approval concept and any
|
|
53
|
+
* chain in the provider's family is reachable anyway.
|
|
54
|
+
*/
|
|
55
|
+
readonly approvedChains?: readonly string[];
|
|
49
56
|
request<T = unknown>(args: {
|
|
50
57
|
method: string;
|
|
51
58
|
params?: unknown;
|
|
@@ -67,13 +74,28 @@ interface LydianConnectConfig extends AppConfig {
|
|
|
67
74
|
/** WalletConnect Cloud project id — powers the fallback. */
|
|
68
75
|
walletConnectProjectId: string;
|
|
69
76
|
}
|
|
70
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Input to {@link LydianConnect.connect} — one of two operations:
|
|
79
|
+
*
|
|
80
|
+
* - `chainId` **pins**: requests target that chain and EVM wallets switch onto it.
|
|
81
|
+
* - `chains` **discovers**: propose several chains, the wallet approves a subset
|
|
82
|
+
* (see {@link Connection.approvedChains}), nothing is pinned. Connect again
|
|
83
|
+
* with `chainId` once the user picks one — a WalletConnect session that
|
|
84
|
+
* approved it is reused without a second prompt.
|
|
85
|
+
*/
|
|
86
|
+
type ConnectInput = {
|
|
71
87
|
walletId: string;
|
|
72
88
|
/** Chain to connect on — a number (EVM, e.g. 137) or a CAIP-2 id ('eip155:137'). */
|
|
73
89
|
chainId: number | string;
|
|
74
90
|
/** Cancel a pending connection. */
|
|
75
91
|
signal?: AbortSignal;
|
|
76
|
-
}
|
|
92
|
+
} | {
|
|
93
|
+
walletId: string;
|
|
94
|
+
/** Chains to discover across — same formats as `chainId`; must be non-empty. */
|
|
95
|
+
chains: readonly (number | string)[];
|
|
96
|
+
/** Cancel a pending connection. */
|
|
97
|
+
signal?: AbortSignal;
|
|
98
|
+
};
|
|
77
99
|
type LydianConnectEvent =
|
|
78
100
|
/**
|
|
79
101
|
* WalletConnect only — the wc: URI.
|
package/dist/index.d.ts
CHANGED
|
@@ -46,6 +46,13 @@ interface Connection {
|
|
|
46
46
|
readonly account: string;
|
|
47
47
|
/** CAIP-2 chain id, e.g. "eip155:1". */
|
|
48
48
|
readonly chainId: string;
|
|
49
|
+
/**
|
|
50
|
+
* The CAIP-2 chains the wallet's session granted, across all namespaces.
|
|
51
|
+
* WalletConnect only — SDK and injected connections leave it undefined, since
|
|
52
|
+
* switching (`wallet_switchEthereumChain`) has no approval concept and any
|
|
53
|
+
* chain in the provider's family is reachable anyway.
|
|
54
|
+
*/
|
|
55
|
+
readonly approvedChains?: readonly string[];
|
|
49
56
|
request<T = unknown>(args: {
|
|
50
57
|
method: string;
|
|
51
58
|
params?: unknown;
|
|
@@ -67,13 +74,28 @@ interface LydianConnectConfig extends AppConfig {
|
|
|
67
74
|
/** WalletConnect Cloud project id — powers the fallback. */
|
|
68
75
|
walletConnectProjectId: string;
|
|
69
76
|
}
|
|
70
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Input to {@link LydianConnect.connect} — one of two operations:
|
|
79
|
+
*
|
|
80
|
+
* - `chainId` **pins**: requests target that chain and EVM wallets switch onto it.
|
|
81
|
+
* - `chains` **discovers**: propose several chains, the wallet approves a subset
|
|
82
|
+
* (see {@link Connection.approvedChains}), nothing is pinned. Connect again
|
|
83
|
+
* with `chainId` once the user picks one — a WalletConnect session that
|
|
84
|
+
* approved it is reused without a second prompt.
|
|
85
|
+
*/
|
|
86
|
+
type ConnectInput = {
|
|
71
87
|
walletId: string;
|
|
72
88
|
/** Chain to connect on — a number (EVM, e.g. 137) or a CAIP-2 id ('eip155:137'). */
|
|
73
89
|
chainId: number | string;
|
|
74
90
|
/** Cancel a pending connection. */
|
|
75
91
|
signal?: AbortSignal;
|
|
76
|
-
}
|
|
92
|
+
} | {
|
|
93
|
+
walletId: string;
|
|
94
|
+
/** Chains to discover across — same formats as `chainId`; must be non-empty. */
|
|
95
|
+
chains: readonly (number | string)[];
|
|
96
|
+
/** Cancel a pending connection. */
|
|
97
|
+
signal?: AbortSignal;
|
|
98
|
+
};
|
|
77
99
|
type LydianConnectEvent =
|
|
78
100
|
/**
|
|
79
101
|
* WalletConnect only — the wc: URI.
|
package/dist/index.js
CHANGED
|
@@ -150,6 +150,20 @@ function buildNamespace(chainId) {
|
|
|
150
150
|
}
|
|
151
151
|
};
|
|
152
152
|
}
|
|
153
|
+
function buildNamespaces(chains) {
|
|
154
|
+
const byName = /* @__PURE__ */ new Map();
|
|
155
|
+
chains.forEach((chain) => {
|
|
156
|
+
const single = buildNamespace(chain);
|
|
157
|
+
const caip = single.value.chains?.[0];
|
|
158
|
+
const merged = byName.get(single.name);
|
|
159
|
+
if (!merged) {
|
|
160
|
+
byName.set(single.name, single);
|
|
161
|
+
} else if (caip && !merged.value.chains?.includes(caip)) {
|
|
162
|
+
merged.value.chains = [...merged.value.chains ?? [], caip];
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
return [...byName.values()];
|
|
166
|
+
}
|
|
153
167
|
|
|
154
168
|
// node_modules/@lydianpay/lydianconnect-catalog/dist/index.js
|
|
155
169
|
var ICON_BASE = "https://wallet-assets.lydian.com/wallets";
|
|
@@ -247,7 +261,7 @@ var WALLET_CATALOG = WALLETS.map((w) => ({
|
|
|
247
261
|
|
|
248
262
|
// src/core/connector.ts
|
|
249
263
|
function requestedChain(req) {
|
|
250
|
-
return req.
|
|
264
|
+
return req.pinned;
|
|
251
265
|
}
|
|
252
266
|
var BaseConnector = class {
|
|
253
267
|
constructor() {
|
|
@@ -607,9 +621,8 @@ function rpcFor2(provider) {
|
|
|
607
621
|
return ({ method, params }) => rpc(provider, method, params);
|
|
608
622
|
}
|
|
609
623
|
function evmChainIds(req) {
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
return Number.isFinite(n) && n > 0 ? [n] : void 0;
|
|
624
|
+
const ids = (req.namespace.value.chains ?? []).map((chain) => Number(chain.split(":")[1])).filter((n) => Number.isFinite(n) && n > 0);
|
|
625
|
+
return ids.length > 0 ? ids : void 0;
|
|
613
626
|
}
|
|
614
627
|
|
|
615
628
|
// src/connectors/injected/connector.ts
|
|
@@ -1303,8 +1316,11 @@ var WalletConnectConnector = class extends BaseConnector {
|
|
|
1303
1316
|
const client = await this.getClient();
|
|
1304
1317
|
const reused = await this.tryReuse(client, req);
|
|
1305
1318
|
if (reused) return reused;
|
|
1319
|
+
const proposed = [req.namespace, ...req.extraNamespaces ?? []];
|
|
1306
1320
|
const { uri, approval } = await client.connect({
|
|
1307
|
-
|
|
1321
|
+
optionalNamespaces: Object.fromEntries(
|
|
1322
|
+
proposed.map((ns) => [ns.name, ns.value])
|
|
1323
|
+
)
|
|
1308
1324
|
});
|
|
1309
1325
|
if (!uri) throw new Error("WalletConnect did not return a pairing URI");
|
|
1310
1326
|
const link = isMobile() ? this.links[req.walletId] : void 0;
|
|
@@ -1336,7 +1352,8 @@ var WalletConnectConnector = class extends BaseConnector {
|
|
|
1336
1352
|
client,
|
|
1337
1353
|
req.walletId,
|
|
1338
1354
|
session,
|
|
1339
|
-
req.namespace
|
|
1355
|
+
req.namespace,
|
|
1356
|
+
req.pinned
|
|
1340
1357
|
);
|
|
1341
1358
|
this.topics.set(req.walletId, session.topic);
|
|
1342
1359
|
this.persist();
|
|
@@ -1403,21 +1420,32 @@ var WalletConnectConnector = class extends BaseConnector {
|
|
|
1403
1420
|
return null;
|
|
1404
1421
|
}
|
|
1405
1422
|
const ns = session.namespaces[req.namespace.name];
|
|
1406
|
-
|
|
1407
|
-
if (
|
|
1408
|
-
return this.toConnection(
|
|
1423
|
+
if (!ns) return null;
|
|
1424
|
+
if (req.pinned && !grantedChains(ns).includes(req.pinned)) return null;
|
|
1425
|
+
return this.toConnection(
|
|
1426
|
+
client,
|
|
1427
|
+
req.walletId,
|
|
1428
|
+
session,
|
|
1429
|
+
req.namespace,
|
|
1430
|
+
req.pinned
|
|
1431
|
+
);
|
|
1409
1432
|
}
|
|
1410
|
-
toConnection(client, walletId, session, namespace) {
|
|
1433
|
+
toConnection(client, walletId, session, namespace, wanted) {
|
|
1411
1434
|
const ns = session.namespaces[namespace.name];
|
|
1412
1435
|
const account = (ns?.accounts ?? []).map((a) => a.split(":")[2]).find((a) => !!a) ?? "";
|
|
1413
|
-
const approved =
|
|
1414
|
-
const wanted = namespace.value.chains?.[0];
|
|
1436
|
+
const approved = grantedChains(ns);
|
|
1415
1437
|
const chainId = wanted && approved.includes(wanted) ? wanted : approved[0] ?? `${namespace.name}:1`;
|
|
1438
|
+
const approvedChains = [
|
|
1439
|
+
...new Set(
|
|
1440
|
+
Object.values(session.namespaces).flatMap((n) => grantedChains(n))
|
|
1441
|
+
)
|
|
1442
|
+
];
|
|
1416
1443
|
const topic = session.topic;
|
|
1417
1444
|
return {
|
|
1418
1445
|
walletId,
|
|
1419
1446
|
account,
|
|
1420
1447
|
chainId,
|
|
1448
|
+
approvedChains,
|
|
1421
1449
|
request: (args) => client.request({
|
|
1422
1450
|
topic,
|
|
1423
1451
|
chainId,
|
|
@@ -1478,6 +1506,11 @@ var WalletConnectConnector = class extends BaseConnector {
|
|
|
1478
1506
|
}
|
|
1479
1507
|
}
|
|
1480
1508
|
};
|
|
1509
|
+
function grantedChains(ns) {
|
|
1510
|
+
if (!ns) return [];
|
|
1511
|
+
if (ns.chains?.length) return ns.chains;
|
|
1512
|
+
return (ns.accounts ?? []).map((a) => a.split(":").slice(0, 2).join(":"));
|
|
1513
|
+
}
|
|
1481
1514
|
function firstNamespace(session) {
|
|
1482
1515
|
const name = Object.keys(session.namespaces)[0];
|
|
1483
1516
|
if (!name) return null;
|
|
@@ -1522,14 +1555,35 @@ var LydianConnect = class {
|
|
|
1522
1555
|
return this.manager.init();
|
|
1523
1556
|
}
|
|
1524
1557
|
async connect(input) {
|
|
1525
|
-
|
|
1558
|
+
const chains = "chains" in input ? input.chains : void 0;
|
|
1559
|
+
const chainId = "chainId" in input ? input.chainId : void 0;
|
|
1560
|
+
if (chains !== void 0 && chainId !== void 0) {
|
|
1561
|
+
throw new Error(
|
|
1562
|
+
"connect() takes either chainId (pinned) or chains (discovery), not both"
|
|
1563
|
+
);
|
|
1564
|
+
}
|
|
1565
|
+
if (chains !== void 0) {
|
|
1566
|
+
const [primary, ...extra] = buildNamespaces(chains);
|
|
1567
|
+
if (!primary) {
|
|
1568
|
+
throw new Error("connect() discovery requires a non-empty chains list");
|
|
1569
|
+
}
|
|
1570
|
+
return this.manager.connect({
|
|
1571
|
+
walletId: input.walletId,
|
|
1572
|
+
namespace: primary,
|
|
1573
|
+
extraNamespaces: extra.length > 0 ? extra : void 0,
|
|
1574
|
+
signal: input.signal
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
if (chainId === void 0 || chainId === null) {
|
|
1526
1578
|
throw new Error(
|
|
1527
|
-
'connect() requires a chainId (a number like 137 or an "eip155:<id>" string)'
|
|
1579
|
+
'connect() requires a chainId (a number like 137 or an "eip155:<id>" string) or a chains list'
|
|
1528
1580
|
);
|
|
1529
1581
|
}
|
|
1582
|
+
const namespace = buildNamespace(chainId);
|
|
1530
1583
|
return this.manager.connect({
|
|
1531
1584
|
walletId: input.walletId,
|
|
1532
|
-
namespace
|
|
1585
|
+
namespace,
|
|
1586
|
+
pinned: namespace.value.chains?.[0],
|
|
1533
1587
|
signal: input.signal
|
|
1534
1588
|
});
|
|
1535
1589
|
}
|