@lydianpay/lydianconnect 1.0.0 → 1.1.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.cjs CHANGED
@@ -8,20 +8,26 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
8
  var SignClient__default = /*#__PURE__*/_interopDefault(SignClient);
9
9
 
10
10
  // src/core/manager.ts
11
- var LydianConnect = class {
12
- constructor(config) {
11
+ var ConnectManager = class {
12
+ constructor(connectors) {
13
13
  this.byWallet = /* @__PURE__ */ new Map();
14
14
  this.connections = /* @__PURE__ */ new Map();
15
15
  this.handlers = /* @__PURE__ */ new Set();
16
16
  this.unsubs = [];
17
17
  this.started = false;
18
- this.fallback = config.fallback;
19
- this.all = [...config.connectors ?? [], config.fallback];
20
- for (const connector of config.connectors ?? []) {
18
+ const fallbacks = connectors.filter((c) => c.walletIds.length === 0);
19
+ if (fallbacks.length !== 1) {
20
+ throw new Error(
21
+ `LydianConnect requires exactly one fallback connector (empty walletIds); found ${fallbacks.length}`
22
+ );
23
+ }
24
+ this.fallback = fallbacks[0];
25
+ this.all = connectors;
26
+ for (const connector of connectors) {
21
27
  for (const id of connector.walletIds) this.byWallet.set(id, connector);
22
28
  }
23
29
  }
24
- /** Wire connector event forwarding, once. Safe to call repeatedly. */
30
+ /** Wire connector event forwarding, once. */
25
31
  async init() {
26
32
  if (this.started) return;
27
33
  this.started = true;
@@ -29,18 +35,17 @@ var LydianConnect = class {
29
35
  this.unsubs.push(connector.on((event) => this.handle(event)));
30
36
  }
31
37
  }
32
- /** SDK connector if one claims this walletId, else the WC fallback. The host app is oblivious. */
38
+ /** SDK connector if one claims this walletId, else the fallback. The host app is oblivious. */
33
39
  resolve(walletId) {
34
40
  return this.byWallet.get(walletId) ?? this.fallback;
35
41
  }
36
- async connect(input) {
42
+ async connect(req) {
37
43
  if (!this.started) await this.init();
38
- const connection = await this.resolve(input.walletId).connect(input);
39
- this.connections.set(input.walletId, connection);
40
- this.emit({ type: "connect", walletId: input.walletId, connection });
44
+ const connection = await this.resolve(req.walletId).connect(req);
45
+ this.connections.set(req.walletId, connection);
46
+ this.emit({ type: "connect", walletId: req.walletId, connection });
41
47
  return connection;
42
48
  }
43
- /** Resume any live sessions across all connectors (e.g. after a page reload). */
44
49
  async restore() {
45
50
  if (!this.started) await this.init();
46
51
  const restored = [];
@@ -66,7 +71,6 @@ var LydianConnect = class {
66
71
  await Promise.allSettled([...this.connections.values()].map((c) => c.disconnect()));
67
72
  this.connections.clear();
68
73
  }
69
- /** Disconnect everything and clear all connector-held state. */
70
74
  async reset() {
71
75
  await this.disconnect();
72
76
  await Promise.allSettled(this.all.map((c) => c.reset()));
@@ -84,6 +88,28 @@ var LydianConnect = class {
84
88
  }
85
89
  };
86
90
 
91
+ // src/core/namespace.ts
92
+ var DEFAULT_EVM_METHODS = [
93
+ "eth_sendTransaction",
94
+ "personal_sign",
95
+ "eth_signTypedData_v4",
96
+ "wallet_switchEthereumChain"
97
+ ];
98
+ var DEFAULT_EVM_EVENTS = ["chainChanged", "accountsChanged"];
99
+ function buildNamespace(chainId) {
100
+ const caip = typeof chainId === "number" ? `eip155:${chainId}` : chainId;
101
+ const [name, reference] = caip.split(":");
102
+ if (name !== "eip155" || !reference || !/^\d+$/.test(reference) || Number(reference) <= 0) {
103
+ throw new Error(
104
+ `Unsupported chain "${caip}". lydianconnect is EVM-only for now \u2014 pass a positive number or an "eip155:<id>" string.`
105
+ );
106
+ }
107
+ return {
108
+ name,
109
+ value: { chains: [caip], methods: DEFAULT_EVM_METHODS, events: DEFAULT_EVM_EVENTS }
110
+ };
111
+ }
112
+
87
113
  // src/core/connector.ts
88
114
  var BaseConnector = class {
89
115
  constructor() {
@@ -104,41 +130,262 @@ var BaseConnector = class {
104
130
  }
105
131
  };
106
132
 
133
+ // src/core/app.ts
134
+ function deriveUrl() {
135
+ return typeof window !== "undefined" ? window.location.origin : "";
136
+ }
137
+
138
+ // src/connectors/metamask/connector.ts
139
+ var WALLET_ID = "metamask";
140
+ var MetaMaskConnector = class extends BaseConnector {
141
+ constructor(app) {
142
+ super();
143
+ this.app = app;
144
+ this.type = "sdk";
145
+ this.walletIds = [WALLET_ID];
146
+ this.sdk = null;
147
+ this.provider = null;
148
+ this.listenersBound = false;
149
+ }
150
+ isAvailable() {
151
+ return true;
152
+ }
153
+ async getProvider() {
154
+ if (this.provider) return this.provider;
155
+ const { MetaMaskSDK } = await import('@metamask/sdk');
156
+ const dappMetadata = {
157
+ name: this.app.appName,
158
+ url: deriveUrl(),
159
+ ...this.app.icon ? { iconUrl: this.app.icon } : {}
160
+ };
161
+ const sdk = new MetaMaskSDK({ dappMetadata });
162
+ await sdk.init();
163
+ const provider = sdk.getProvider();
164
+ if (!provider) throw new Error("MetaMask provider unavailable");
165
+ this.sdk = sdk;
166
+ this.provider = provider;
167
+ this.bindEvents(provider);
168
+ return provider;
169
+ }
170
+ bindEvents(provider) {
171
+ if (this.listenersBound) return;
172
+ this.listenersBound = true;
173
+ provider.on("chainChanged", (hex) => {
174
+ this.emit({ type: "chainChanged", walletId: WALLET_ID, chainId: toCaip(String(hex)) });
175
+ });
176
+ provider.on("accountsChanged", (accounts) => {
177
+ const account = Array.isArray(accounts) ? accounts[0] : void 0;
178
+ if (account) this.emit({ type: "accountsChanged", walletId: WALLET_ID, account });
179
+ else this.emit({ type: "disconnect", walletId: WALLET_ID });
180
+ });
181
+ provider.on("disconnect", () => this.emit({ type: "disconnect", walletId: WALLET_ID }));
182
+ }
183
+ async connect(req) {
184
+ const provider = await this.getProvider();
185
+ const accounts = await provider.request({ method: "eth_requestAccounts" });
186
+ const account = accounts?.[0];
187
+ if (!account) throw new Error("MetaMask returned no account");
188
+ await this.ensureChain(provider, req);
189
+ const chainId = toCaip(await provider.request({ method: "eth_chainId" }));
190
+ return this.toConnection(provider, account, chainId);
191
+ }
192
+ async restore() {
193
+ const provider = await this.getProvider().catch(() => null);
194
+ if (!provider) return [];
195
+ const accounts = await provider.request({ method: "eth_accounts" }).catch(() => []);
196
+ const account = accounts?.[0];
197
+ if (!account) return [];
198
+ const chainId = toCaip(
199
+ await provider.request({ method: "eth_chainId" }).catch(() => "0x1")
200
+ );
201
+ return [this.toConnection(provider, account, chainId)];
202
+ }
203
+ async reset() {
204
+ await this.sdk?.terminate();
205
+ this.provider = null;
206
+ this.listenersBound = false;
207
+ }
208
+ /** Best-effort switch to the requested chain; leaves the wallet as-is if it's unknown to it. */
209
+ async ensureChain(provider, req) {
210
+ const wanted = req.namespace.value.chains?.[0];
211
+ const wantedNum = wanted ? Number(wanted.split(":")[1]) : NaN;
212
+ if (!Number.isFinite(wantedNum) || wantedNum <= 0) return;
213
+ const current = parseInt(
214
+ await provider.request({ method: "eth_chainId" }).catch(() => "0x0") ?? "0x0",
215
+ 16
216
+ );
217
+ if (current === wantedNum) return;
218
+ await provider.request({
219
+ method: "wallet_switchEthereumChain",
220
+ params: [{ chainId: `0x${wantedNum.toString(16)}` }]
221
+ }).catch(() => {
222
+ });
223
+ }
224
+ toConnection(provider, account, chainId) {
225
+ return {
226
+ walletId: WALLET_ID,
227
+ account,
228
+ chainId,
229
+ request: async (args) => await provider.request({ method: args.method, params: args.params }),
230
+ openWallet: () => {
231
+ },
232
+ // MetaMask SDK foregrounds the wallet on request
233
+ disconnect: async () => {
234
+ await this.sdk?.terminate();
235
+ this.provider = null;
236
+ this.listenersBound = false;
237
+ this.emit({ type: "disconnect", walletId: WALLET_ID });
238
+ }
239
+ };
240
+ }
241
+ };
242
+ function toCaip(hexChainId) {
243
+ if (!hexChainId) return "eip155:1";
244
+ const num = hexChainId.startsWith("0x") ? parseInt(hexChainId, 16) : Number(hexChainId);
245
+ return `eip155:${Number.isFinite(num) ? num : 1}`;
246
+ }
247
+
248
+ // src/connectors/coinbase/connector.ts
249
+ function rpc(provider, method, params) {
250
+ return provider.request({ method, params });
251
+ }
252
+ var WALLET_ID2 = "coinbase";
253
+ var CoinbaseConnector = class extends BaseConnector {
254
+ constructor(app) {
255
+ super();
256
+ this.app = app;
257
+ this.type = "sdk";
258
+ this.walletIds = [WALLET_ID2];
259
+ this.provider = null;
260
+ this.listenersBound = false;
261
+ }
262
+ isAvailable() {
263
+ return true;
264
+ }
265
+ async getProvider(appChainIds) {
266
+ if (this.provider) return this.provider;
267
+ const { CoinbaseWalletSDK } = await import('@coinbase/wallet-sdk');
268
+ const sdk = new CoinbaseWalletSDK({
269
+ appName: this.app.appName,
270
+ appLogoUrl: this.app.icon,
271
+ appChainIds
272
+ // one-time SDK-init hint; ensureChain enforces the actual chain per connect
273
+ });
274
+ const provider = sdk.makeWeb3Provider();
275
+ this.provider = provider;
276
+ this.bindEvents(provider);
277
+ return provider;
278
+ }
279
+ bindEvents(provider) {
280
+ if (this.listenersBound) return;
281
+ this.listenersBound = true;
282
+ provider.on("chainChanged", (hex) => {
283
+ this.emit({ type: "chainChanged", walletId: WALLET_ID2, chainId: toCaip2(String(hex)) });
284
+ });
285
+ provider.on("accountsChanged", (accounts) => {
286
+ const account = Array.isArray(accounts) ? accounts[0] : void 0;
287
+ if (account) this.emit({ type: "accountsChanged", walletId: WALLET_ID2, account });
288
+ else this.emit({ type: "disconnect", walletId: WALLET_ID2 });
289
+ });
290
+ provider.on("disconnect", () => this.emit({ type: "disconnect", walletId: WALLET_ID2 }));
291
+ }
292
+ async connect(req) {
293
+ const provider = await this.getProvider(evmChainIds(req));
294
+ const accounts = await rpc(provider, "eth_requestAccounts");
295
+ const account = accounts?.[0];
296
+ if (!account) throw new Error("Coinbase Wallet returned no account");
297
+ await this.ensureChain(provider, req);
298
+ const chainId = toCaip2(await rpc(provider, "eth_chainId"));
299
+ return this.toConnection(provider, account, chainId);
300
+ }
301
+ async restore() {
302
+ const provider = await this.getProvider().catch(() => null);
303
+ if (!provider) return [];
304
+ const accounts = await rpc(provider, "eth_accounts").catch(() => []);
305
+ const account = accounts?.[0];
306
+ if (!account) return [];
307
+ const chainId = toCaip2(await rpc(provider, "eth_chainId").catch(() => "0x1"));
308
+ return [this.toConnection(provider, account, chainId)];
309
+ }
310
+ async reset() {
311
+ await this.provider?.disconnect().catch(() => {
312
+ });
313
+ this.provider = null;
314
+ this.listenersBound = false;
315
+ }
316
+ async ensureChain(provider, req) {
317
+ const wanted = req.namespace.value.chains?.[0];
318
+ const wantedNum = wanted ? Number(wanted.split(":")[1]) : NaN;
319
+ if (!Number.isFinite(wantedNum) || wantedNum <= 0) return;
320
+ const current = parseInt(
321
+ await rpc(provider, "eth_chainId").catch(() => "0x0") ?? "0x0",
322
+ 16
323
+ );
324
+ if (current === wantedNum) return;
325
+ await rpc(provider, "wallet_switchEthereumChain", [{ chainId: `0x${wantedNum.toString(16)}` }]).catch(
326
+ () => {
327
+ }
328
+ );
329
+ }
330
+ toConnection(provider, account, chainId) {
331
+ return {
332
+ walletId: WALLET_ID2,
333
+ account,
334
+ chainId,
335
+ request: (args) => rpc(provider, args.method, args.params),
336
+ openWallet: () => {
337
+ },
338
+ // Coinbase SDK foregrounds the wallet on request
339
+ disconnect: async () => {
340
+ await provider.disconnect().catch(() => {
341
+ });
342
+ this.provider = null;
343
+ this.listenersBound = false;
344
+ this.emit({ type: "disconnect", walletId: WALLET_ID2 });
345
+ }
346
+ };
347
+ }
348
+ };
349
+ function toCaip2(hexChainId) {
350
+ if (!hexChainId) return "eip155:1";
351
+ const num = hexChainId.startsWith("0x") ? parseInt(hexChainId, 16) : Number(hexChainId);
352
+ return `eip155:${Number.isFinite(num) ? num : 1}`;
353
+ }
354
+ function evmChainIds(req) {
355
+ const wanted = req.namespace.value.chains?.[0];
356
+ const n = wanted ? Number(wanted.split(":")[1]) : NaN;
357
+ return Number.isFinite(n) && n > 0 ? [n] : void 0;
358
+ }
359
+
107
360
  // src/connectors/walletconnect/wallet-links.generated.ts
108
361
  var GENERATED_WALLET_LINKS = {
109
- metamask: { "scheme": "metamask://wc", "universal": "https://metamask.app.link/wc", "store": { "ios": "https://apps.apple.com/us/app/metamask/id1438144202", "android": "https://play.google.com/store/apps/details?id=io.metamask" } },
110
- trust: { "scheme": "trust://wc", "universal": "https://link.trustwallet.com/wc", "store": { "ios": "https://apps.apple.com/app/apple-store/id1288339409", "android": "https://play.google.com/store/apps/details?id=com.wallet.crypto.trustapp" } },
111
- rainbow: { "scheme": "rainbow://wc", "universal": "https://rnbwapp.com/wc", "store": { "ios": "https://apps.apple.com/app/apple-store/id1457119021?pt=119997837&ct=wc&mt=8", "android": "https://play.google.com/store/apps/details?id=me.rainbow&referrer=utm_source%3Dwc%26utm_medium%3Dconnector%26utm_campaign%3Dwc" } },
362
+ metamask: { "native": "metamask://", "scheme": "metamask://wc", "universal": "https://metamask.app.link/wc", "store": { "ios": "https://apps.apple.com/us/app/metamask/id1438144202", "android": "https://play.google.com/store/apps/details?id=io.metamask" } },
363
+ trust: { "native": "trust://", "scheme": "trust://wc", "universal": "https://link.trustwallet.com/wc", "store": { "ios": "https://apps.apple.com/app/apple-store/id1288339409", "android": "https://play.google.com/store/apps/details?id=com.wallet.crypto.trustapp" } },
364
+ rainbow: { "native": "rainbow://", "scheme": "rainbow://wc", "universal": "https://rnbwapp.com/wc", "store": { "ios": "https://apps.apple.com/app/apple-store/id1457119021?pt=119997837&ct=wc&mt=8", "android": "https://play.google.com/store/apps/details?id=me.rainbow&referrer=utm_source%3Dwc%26utm_medium%3Dconnector%26utm_campaign%3Dwc" } },
112
365
  coinbase: { "store": { "ios": "https://apps.apple.com/us/app/base-formerly-coinbase-wallet/id1278383455" } },
113
- zerion: { "scheme": "zerion://wc", "universal": "https://wallet.zerion.io/wc/wc", "store": { "ios": "https://apps.apple.com/app/id1456732565", "android": "https://play.google.com/store/apps/details?id=io.zerion.android&hl=en&gl=US" } },
114
- tokenpocket: { "scheme": "tpoutside://wc", "store": { "ios": "https://apps.apple.com/us/app/tp-wallet/id6444625622?l=en", "android": "https://play.google.com/store/apps/details?id=vip.mytokenpocket" } },
115
- blockchaincom: { "scheme": "blockchain-wallet://wc", "universal": "https://login.blockchain.com/app/wc", "store": { "ios": "https://apps.apple.com/us/app/blockchain-bitcoin-wallet/id493253309", "android": "https://play.google.com/store/apps/details?id=piuk.blockchain.android" } },
116
- exodus: { "scheme": "exodus://wc", "universal": "https://exodus.com/m/wc", "store": { "ios": "https://apps.apple.com/us/app/exodus-crypto-bitcoin-wallet/id1414384820", "android": "https://play.google.com/store/apps/details?id=exodusmovement.exodus&hl=en&gl=US" } },
366
+ zerion: { "native": "zerion://", "scheme": "zerion://wc", "universal": "https://wallet.zerion.io/wc/wc", "store": { "ios": "https://apps.apple.com/app/id1456732565", "android": "https://play.google.com/store/apps/details?id=io.zerion.android&hl=en&gl=US" } },
367
+ tokenpocket: { "native": "tpoutside://", "scheme": "tpoutside://wc", "store": { "ios": "https://apps.apple.com/us/app/tp-wallet/id6444625622?l=en", "android": "https://play.google.com/store/apps/details?id=vip.mytokenpocket" } },
368
+ blockchaincom: { "native": "blockchain-wallet://", "scheme": "blockchain-wallet://wc", "universal": "https://login.blockchain.com/app/wc", "store": { "ios": "https://apps.apple.com/us/app/blockchain-bitcoin-wallet/id493253309", "android": "https://play.google.com/store/apps/details?id=piuk.blockchain.android" } },
369
+ exodus: { "native": "exodus://", "scheme": "exodus://wc", "universal": "https://exodus.com/m/wc", "store": { "ios": "https://apps.apple.com/us/app/exodus-crypto-bitcoin-wallet/id1414384820", "android": "https://play.google.com/store/apps/details?id=exodusmovement.exodus&hl=en&gl=US" } },
117
370
  phantom: { "store": { "ios": "https://apps.apple.com/us/app/phantom-crypto-wallet/id1598432977", "android": "https://play.google.com/store/apps/details?id=app.phantom&hl=en" } },
118
- okx: { "scheme": "okex://main/wc", "universal": "https://www.okx.com/download?appendQuery=true&deeplink=okx://web3/wallet/walletConnect/wc", "store": { "ios": "https://apps.apple.com/us/app/okx-buy-bitcoin-eth-crypto/id1327268470", "android": "https://play.google.com/store/apps/details?id=com.okinc.okex.gp" } },
119
- cryptocom: { "scheme": "dfw://wc", "universal": "https://wallet.crypto.com/deeplink/wc", "store": { "ios": "https://apps.apple.com/US/app/id1512048310?mt=8", "android": "https://play.google.com/store/apps/details?id=com.defi.wallet" } },
120
- argent: { "scheme": "argent://app/wc", "universal": "https://www.argent.xyz/app/wc", "store": { "ios": "https://apps.apple.com/us/app/argent-defi-in-a-tap/id1358741926", "android": "https://play.google.com/store/apps/details?id=im.argent.contractwalletclient&hl=en&gl=US&pli=1" } },
121
- safepal: { "scheme": "safepalwallet://wc", "universal": "https://link.safepal.io/wc", "store": { "ios": "https://apps.apple.com/app/safepal-wallet/id1548297139", "android": "https://play.google.com/store/apps/details?id=io.safepal.wallet" } },
122
- imtoken: { "scheme": "imtokenv2://wc", "store": { "ios": "https://apps.apple.com/us/app/imtoken2/id1384798940", "android": "https://play.google.com/store/apps/details?id=im.token.app" } },
123
- ronin: { "scheme": "roninwallet://wc", "universal": "https://wallet.roninchain.com/wc", "store": { "ios": "https://apps.apple.com/us/app/ronin-wallet/id1592675001", "android": "https://play.google.com/store/apps/details?id=com.skymavis.genesis" } },
124
- coin98: { "scheme": "coin98://wc", "universal": "https://coin98.com/wc", "store": { "ios": "https://apps.apple.com/vn/app/coin98-wallet/id1561969966", "android": "https://play.google.com/store/apps/details?id=coin98.crypto.finance.media&hl=vi&gl=US" } },
125
- bitkeep: { "scheme": "bitkeep://wc", "universal": "https://bkapp.vip/wc", "store": { "ios": "https://web3.bitget.com/en/wallet-download?type=0", "android": "https://web3.bitget.com/en/wallet-download?type=0" } },
126
- "1inch": { "scheme": "oneinch://open/nobodywilleveruseit/wc", "universal": "https://wallet.1inch.io/app/nobodywilleveruseit/wc", "store": { "ios": "https://apps.apple.com/us/app/1inch-defi-wallet/id1546049391", "android": "https://play.google.com/store/apps/details?id=io.oneinch.android" } },
127
- ledgerlive: { "scheme": "ledgerlive://wc", "store": { "ios": "https://itunes.apple.com/app/id1361671700", "android": "https://play.google.com/store/apps/details?id=com.ledger.live" } },
128
- atomic: { "scheme": "atomicwallet://wc", "store": { "ios": "https://apps.apple.com/us/app/atomic-wallet/id1478257827", "android": "https://play.google.com/store/apps/details?id=io.atomicwallet" } },
129
- alpha: { "scheme": "awallet://wc", "universal": "https://aw.app/wc", "store": { "ios": "https://apps.apple.com/us/app/alphawallet-eth-wallet/id1358230430", "android": "https://play.google.com/store/apps/details?id=io.stormbird.wallet" } },
130
- math: { "scheme": "mathwallet://wc", "universal": "https://www.mathwallet.org/wc", "store": { "ios": "https://apps.apple.com/us/app/mathwallet5/id1582612388", "android": "https://play.google.com/store/apps/details?id=com.mathwallet.android" } },
131
- bitpay: { "scheme": "bitpay://wc", "universal": "https://link.bitpay.com/wc", "store": { "ios": "https://bitpay.onelink.me/Cenw/ejjaw7bs", "android": "https://bitpay.onelink.me/Cenw/ejjaw7bs" } }
371
+ okx: { "native": "okex://main", "scheme": "okex://main/wc", "universal": "https://www.okx.com/download?appendQuery=true&deeplink=okx://web3/wallet/walletConnect/wc", "store": { "ios": "https://apps.apple.com/us/app/okx-buy-bitcoin-eth-crypto/id1327268470", "android": "https://play.google.com/store/apps/details?id=com.okinc.okex.gp" } },
372
+ cryptocom: { "native": "dfw://", "scheme": "dfw://wc", "universal": "https://wallet.crypto.com/deeplink/wc", "store": { "ios": "https://apps.apple.com/US/app/id1512048310?mt=8", "android": "https://play.google.com/store/apps/details?id=com.defi.wallet" } },
373
+ argent: { "native": "argent://app/", "scheme": "argent://app/wc", "universal": "https://www.argent.xyz/app/wc", "store": { "ios": "https://apps.apple.com/us/app/argent-defi-in-a-tap/id1358741926", "android": "https://play.google.com/store/apps/details?id=im.argent.contractwalletclient&hl=en&gl=US&pli=1" } },
374
+ safepal: { "native": "safepalwallet://", "scheme": "safepalwallet://wc", "universal": "https://link.safepal.io/wc", "store": { "ios": "https://apps.apple.com/app/safepal-wallet/id1548297139", "android": "https://play.google.com/store/apps/details?id=io.safepal.wallet" } },
375
+ imtoken: { "native": "imtokenv2://", "scheme": "imtokenv2://wc", "store": { "ios": "https://apps.apple.com/us/app/imtoken2/id1384798940", "android": "https://play.google.com/store/apps/details?id=im.token.app" } },
376
+ ronin: { "native": "roninwallet://", "scheme": "roninwallet://wc", "universal": "https://wallet.roninchain.com/wc", "store": { "ios": "https://apps.apple.com/us/app/ronin-wallet/id1592675001", "android": "https://play.google.com/store/apps/details?id=com.skymavis.genesis" } },
377
+ coin98: { "native": "coin98://", "scheme": "coin98://wc", "universal": "https://coin98.com/wc", "store": { "ios": "https://apps.apple.com/vn/app/coin98-wallet/id1561969966", "android": "https://play.google.com/store/apps/details?id=coin98.crypto.finance.media&hl=vi&gl=US" } },
378
+ bitkeep: { "native": "bitkeep://", "scheme": "bitkeep://wc", "universal": "https://bkapp.vip/wc", "store": { "ios": "https://web3.bitget.com/en/wallet-download?type=0", "android": "https://web3.bitget.com/en/wallet-download?type=0" } },
379
+ "1inch": { "native": "oneinch://open/nobodywilleveruseit", "scheme": "oneinch://open/nobodywilleveruseit/wc", "universal": "https://wallet.1inch.io/app/nobodywilleveruseit/wc", "store": { "ios": "https://apps.apple.com/us/app/1inch-defi-wallet/id1546049391", "android": "https://play.google.com/store/apps/details?id=io.oneinch.android" } },
380
+ ledgerlive: { "native": "ledgerlive://", "scheme": "ledgerlive://wc", "store": { "ios": "https://itunes.apple.com/app/id1361671700", "android": "https://play.google.com/store/apps/details?id=com.ledger.live" } },
381
+ atomic: { "native": "atomicwallet://", "scheme": "atomicwallet://wc", "store": { "ios": "https://apps.apple.com/us/app/atomic-wallet/id1478257827", "android": "https://play.google.com/store/apps/details?id=io.atomicwallet" } },
382
+ alpha: { "native": "awallet://", "scheme": "awallet://wc", "universal": "https://aw.app/wc", "store": { "ios": "https://apps.apple.com/us/app/alphawallet-eth-wallet/id1358230430", "android": "https://play.google.com/store/apps/details?id=io.stormbird.wallet" } },
383
+ math: { "native": "mathwallet://", "scheme": "mathwallet://wc", "universal": "https://www.mathwallet.org/wc", "store": { "ios": "https://apps.apple.com/us/app/mathwallet5/id1582612388", "android": "https://play.google.com/store/apps/details?id=com.mathwallet.android" } },
384
+ bitpay: { "native": "bitpay://", "scheme": "bitpay://wc", "universal": "https://link.bitpay.com/wc", "store": { "ios": "https://bitpay.onelink.me/Cenw/ejjaw7bs", "android": "https://bitpay.onelink.me/Cenw/ejjaw7bs" } }
132
385
  };
133
386
 
134
387
  // src/connectors/walletconnect/registry.ts
135
- var MANUAL_WALLET_LINKS = {
136
- infinity: { scheme: "infinity://wc" }
137
- };
138
- var DEFAULT_WALLET_LINKS = {
139
- ...MANUAL_WALLET_LINKS,
140
- ...GENERATED_WALLET_LINKS
141
- };
388
+ var DEFAULT_WALLET_LINKS = GENERATED_WALLET_LINKS;
142
389
 
143
390
  // src/connectors/walletconnect/deeplink.ts
144
391
  function isMobile() {
@@ -159,6 +406,11 @@ function openWallet(link, uri) {
159
406
  openHref(buildLink(link.scheme, uri), false);
160
407
  }
161
408
  }
409
+ function openWalletApp(link) {
410
+ if (typeof document === "undefined") return;
411
+ if (!link.native) return;
412
+ openHref(link.native, false);
413
+ }
162
414
  function openHref(href, newContext) {
163
415
  const a = document.createElement("a");
164
416
  a.href = href;
@@ -196,9 +448,10 @@ function detectAppOpen(timeoutMs) {
196
448
  // src/connectors/walletconnect/connector.ts
197
449
  var STORAGE_KEY = "lydianconnect.wc.topics";
198
450
  var WalletConnectConnector = class extends BaseConnector {
199
- constructor(config) {
451
+ constructor(app, options) {
200
452
  super();
201
- this.config = config;
453
+ this.app = app;
454
+ this.options = options;
202
455
  this.type = "walletconnect";
203
456
  this.walletIds = [];
204
457
  // claims any wallet not served by an SDK connector
@@ -206,7 +459,7 @@ var WalletConnectConnector = class extends BaseConnector {
206
459
  this.topics = /* @__PURE__ */ new Map();
207
460
  this.warm = null;
208
461
  this.warming = null;
209
- this.links = { ...DEFAULT_WALLET_LINKS, ...config.walletLinks ?? {} };
462
+ this.links = { ...DEFAULT_WALLET_LINKS, ...options.walletLinks ?? {} };
210
463
  }
211
464
  isAvailable() {
212
465
  return true;
@@ -214,9 +467,14 @@ var WalletConnectConnector = class extends BaseConnector {
214
467
  async getClient() {
215
468
  if (this.client) return this.client;
216
469
  const client = await SignClient__default.default.init({
217
- projectId: this.config.projectId,
218
- metadata: this.config.metadata,
219
- relayUrl: this.config.relayUrl
470
+ projectId: this.options.projectId,
471
+ metadata: {
472
+ name: this.app.appName,
473
+ description: this.app.description ?? this.app.appName,
474
+ url: deriveUrl(),
475
+ icons: this.app.icon ? [this.app.icon] : []
476
+ },
477
+ relayUrl: this.options.relayUrl
220
478
  });
221
479
  client.on("session_delete", ({ topic }) => {
222
480
  const walletId = this.walletForTopic(topic);
@@ -266,7 +524,7 @@ var WalletConnectConnector = class extends BaseConnector {
266
524
  const link = this.links[req.walletId];
267
525
  if (link) {
268
526
  openWallet(link, warm.uri);
269
- void detectAppOpen(this.config.openTimeoutMs ?? 2e3).then((opened) => {
527
+ void detectAppOpen(this.options.openTimeoutMs ?? 2e3).then((opened) => {
270
528
  if (!opened) this.emit({ type: "wallet_open_failed", walletId: req.walletId, uri: warm.uri });
271
529
  });
272
530
  }
@@ -339,6 +597,11 @@ var WalletConnectConnector = class extends BaseConnector {
339
597
  chainId,
340
598
  request: { method: args.method, params: args.params }
341
599
  }),
600
+ openWallet: () => {
601
+ if (!isMobile()) return;
602
+ const link = this.links[walletId];
603
+ if (link) openWalletApp(link);
604
+ },
342
605
  disconnect: async () => {
343
606
  await client.disconnect({ topic, reason: utils.getSdkError("USER_DISCONNECTED") }).catch(() => {
344
607
  });
@@ -405,216 +668,53 @@ function withSignal(promise, signal, onAbort) {
405
668
  });
406
669
  }
407
670
 
408
- // src/connectors/metamask/connector.ts
409
- var WALLET_ID = "metamask";
410
- var MetaMaskConnector = class extends BaseConnector {
411
- constructor(config) {
412
- super();
413
- this.config = config;
414
- this.type = "sdk";
415
- this.walletIds = [WALLET_ID];
416
- this.sdk = null;
417
- this.provider = null;
418
- this.listenersBound = false;
419
- }
420
- isAvailable() {
421
- return true;
422
- }
423
- async getProvider() {
424
- if (this.provider) return this.provider;
425
- const { MetaMaskSDK } = await import('@metamask/sdk');
426
- const sdk = new MetaMaskSDK({
427
- dappMetadata: this.config.dappMetadata,
428
- ...this.config.sdkOptions
429
- });
430
- await sdk.init();
431
- const provider = sdk.getProvider();
432
- if (!provider) throw new Error("MetaMask provider unavailable");
433
- this.sdk = sdk;
434
- this.provider = provider;
435
- this.bindEvents(provider);
436
- return provider;
437
- }
438
- bindEvents(provider) {
439
- if (this.listenersBound) return;
440
- this.listenersBound = true;
441
- provider.on("chainChanged", (hex) => {
442
- this.emit({ type: "chainChanged", walletId: WALLET_ID, chainId: toCaip(String(hex)) });
443
- });
444
- provider.on("accountsChanged", (accounts) => {
445
- const account = Array.isArray(accounts) ? accounts[0] : void 0;
446
- if (account) this.emit({ type: "accountsChanged", walletId: WALLET_ID, account });
447
- else this.emit({ type: "disconnect", walletId: WALLET_ID });
448
- });
449
- provider.on("disconnect", () => this.emit({ type: "disconnect", walletId: WALLET_ID }));
450
- }
451
- async connect(req) {
452
- const provider = await this.getProvider();
453
- const accounts = await provider.request({ method: "eth_requestAccounts" });
454
- const account = accounts?.[0];
455
- if (!account) throw new Error("MetaMask returned no account");
456
- await this.ensureChain(provider, req);
457
- const chainId = toCaip(await provider.request({ method: "eth_chainId" }));
458
- return this.toConnection(provider, account, chainId);
459
- }
460
- async restore() {
461
- const provider = await this.getProvider().catch(() => null);
462
- if (!provider) return [];
463
- const accounts = await provider.request({ method: "eth_accounts" }).catch(() => []);
464
- const account = accounts?.[0];
465
- if (!account) return [];
466
- const chainId = toCaip(
467
- await provider.request({ method: "eth_chainId" }).catch(() => "0x1")
468
- );
469
- return [this.toConnection(provider, account, chainId)];
470
- }
471
- async reset() {
472
- await this.sdk?.terminate();
473
- this.provider = null;
474
- this.listenersBound = false;
475
- }
476
- /** Best-effort switch to the requested chain; leaves the wallet as-is if it's unknown to it. */
477
- async ensureChain(provider, req) {
478
- const wanted = req.namespace.value.chains?.[0];
479
- const wantedNum = wanted ? Number(wanted.split(":")[1]) : NaN;
480
- if (!Number.isFinite(wantedNum) || wantedNum <= 0) return;
481
- const current = parseInt(
482
- await provider.request({ method: "eth_chainId" }).catch(() => "0x0") ?? "0x0",
483
- 16
484
- );
485
- if (current === wantedNum) return;
486
- await provider.request({
487
- method: "wallet_switchEthereumChain",
488
- params: [{ chainId: `0x${wantedNum.toString(16)}` }]
489
- }).catch(() => {
490
- });
491
- }
492
- toConnection(provider, account, chainId) {
493
- return {
494
- walletId: WALLET_ID,
495
- account,
496
- chainId,
497
- request: async (args) => await provider.request({ method: args.method, params: args.params }),
498
- disconnect: async () => {
499
- await this.sdk?.terminate();
500
- this.provider = null;
501
- this.listenersBound = false;
502
- this.emit({ type: "disconnect", walletId: WALLET_ID });
503
- }
504
- };
505
- }
506
- };
507
- function toCaip(hexChainId) {
508
- if (!hexChainId) return "eip155:1";
509
- const num = hexChainId.startsWith("0x") ? parseInt(hexChainId, 16) : Number(hexChainId);
510
- return `eip155:${Number.isFinite(num) ? num : 1}`;
511
- }
512
-
513
- // src/connectors/coinbase/connector.ts
514
- function rpc(provider, method, params) {
515
- return provider.request({ method, params });
671
+ // src/core/lydian-connect.ts
672
+ function createConnectors(config) {
673
+ const app = {
674
+ appName: config.appName,
675
+ icon: config.icon,
676
+ description: config.description
677
+ };
678
+ return [
679
+ new MetaMaskConnector(app),
680
+ new CoinbaseConnector(app),
681
+ new WalletConnectConnector(app, { projectId: config.walletConnectProjectId })
682
+ ];
516
683
  }
517
- var WALLET_ID2 = "coinbase";
518
- var CoinbaseConnector = class extends BaseConnector {
684
+ var LydianConnect = class {
519
685
  constructor(config) {
520
- super();
521
- this.config = config;
522
- this.type = "sdk";
523
- this.walletIds = [WALLET_ID2];
524
- this.provider = null;
525
- this.listenersBound = false;
686
+ this.manager = new ConnectManager(createConnectors(config));
526
687
  }
527
- isAvailable() {
528
- return true;
688
+ init() {
689
+ return this.manager.init();
529
690
  }
530
- async getProvider() {
531
- if (this.provider) return this.provider;
532
- const { CoinbaseWalletSDK } = await import('@coinbase/wallet-sdk');
533
- const sdk = new CoinbaseWalletSDK({
534
- appName: this.config.appName,
535
- appLogoUrl: this.config.appLogoUrl,
536
- appChainIds: this.config.appChainIds
691
+ async connect(input) {
692
+ if (input.chainId === void 0 || input.chainId === null) {
693
+ throw new Error('connect() requires a chainId (a number like 137 or an "eip155:<id>" string)');
694
+ }
695
+ return this.manager.connect({
696
+ walletId: input.walletId,
697
+ namespace: buildNamespace(input.chainId),
698
+ signal: input.signal
537
699
  });
538
- const provider = sdk.makeWeb3Provider();
539
- this.provider = provider;
540
- this.bindEvents(provider);
541
- return provider;
542
700
  }
543
- bindEvents(provider) {
544
- if (this.listenersBound) return;
545
- this.listenersBound = true;
546
- provider.on("chainChanged", (hex) => {
547
- this.emit({ type: "chainChanged", walletId: WALLET_ID2, chainId: toCaip2(String(hex)) });
548
- });
549
- provider.on("accountsChanged", (accounts) => {
550
- const account = Array.isArray(accounts) ? accounts[0] : void 0;
551
- if (account) this.emit({ type: "accountsChanged", walletId: WALLET_ID2, account });
552
- else this.emit({ type: "disconnect", walletId: WALLET_ID2 });
553
- });
554
- provider.on("disconnect", () => this.emit({ type: "disconnect", walletId: WALLET_ID2 }));
701
+ restore() {
702
+ return this.manager.restore();
555
703
  }
556
- async connect(req) {
557
- const provider = await this.getProvider();
558
- const accounts = await rpc(provider, "eth_requestAccounts");
559
- const account = accounts?.[0];
560
- if (!account) throw new Error("Coinbase Wallet returned no account");
561
- await this.ensureChain(provider, req);
562
- const chainId = toCaip2(await rpc(provider, "eth_chainId"));
563
- return this.toConnection(provider, account, chainId);
704
+ disconnect(walletId) {
705
+ return this.manager.disconnect(walletId);
564
706
  }
565
- async restore() {
566
- const provider = await this.getProvider().catch(() => null);
567
- if (!provider) return [];
568
- const accounts = await rpc(provider, "eth_accounts").catch(() => []);
569
- const account = accounts?.[0];
570
- if (!account) return [];
571
- const chainId = toCaip2(await rpc(provider, "eth_chainId").catch(() => "0x1"));
572
- return [this.toConnection(provider, account, chainId)];
573
- }
574
- async reset() {
575
- await this.provider?.disconnect().catch(() => {
576
- });
577
- this.provider = null;
578
- this.listenersBound = false;
707
+ reset() {
708
+ return this.manager.reset();
579
709
  }
580
- async ensureChain(provider, req) {
581
- const wanted = req.namespace.value.chains?.[0];
582
- const wantedNum = wanted ? Number(wanted.split(":")[1]) : NaN;
583
- if (!Number.isFinite(wantedNum) || wantedNum <= 0) return;
584
- const current = parseInt(await rpc(provider, "eth_chainId").catch(() => "0x0"), 16);
585
- if (current === wantedNum) return;
586
- await rpc(provider, "wallet_switchEthereumChain", [{ chainId: `0x${wantedNum.toString(16)}` }]).catch(
587
- () => {
588
- }
589
- );
710
+ get(walletId) {
711
+ return this.manager.get(walletId);
590
712
  }
591
- toConnection(provider, account, chainId) {
592
- return {
593
- walletId: WALLET_ID2,
594
- account,
595
- chainId,
596
- request: (args) => rpc(provider, args.method, args.params),
597
- disconnect: async () => {
598
- await provider.disconnect().catch(() => {
599
- });
600
- this.provider = null;
601
- this.listenersBound = false;
602
- this.emit({ type: "disconnect", walletId: WALLET_ID2 });
603
- }
604
- };
713
+ on(handler) {
714
+ return this.manager.on(handler);
605
715
  }
606
716
  };
607
- function toCaip2(hexChainId) {
608
- if (!hexChainId) return "eip155:1";
609
- const num = hexChainId.startsWith("0x") ? parseInt(hexChainId, 16) : Number(hexChainId);
610
- return `eip155:${Number.isFinite(num) ? num : 1}`;
611
- }
612
717
 
613
- exports.BaseConnector = BaseConnector;
614
- exports.CoinbaseConnector = CoinbaseConnector;
615
- exports.DEFAULT_WALLET_LINKS = DEFAULT_WALLET_LINKS;
616
718
  exports.LydianConnect = LydianConnect;
617
- exports.MetaMaskConnector = MetaMaskConnector;
618
- exports.WalletConnectConnector = WalletConnectConnector;
619
719
  //# sourceMappingURL=index.cjs.map
620
720
  //# sourceMappingURL=index.cjs.map