@cartridge/controller 0.7.7 → 0.7.8
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/.turbo/turbo-build$colon$deps.log +23 -23
- package/.turbo/turbo-build.log +31 -31
- package/dist/controller.cjs +472 -3
- package/dist/controller.cjs.map +1 -1
- package/dist/controller.d.cts +1 -1
- package/dist/controller.d.ts +1 -1
- package/dist/controller.js +472 -3
- package/dist/controller.js.map +1 -1
- package/dist/index.cjs +1908 -1214
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -3
- package/dist/index.d.ts +46 -3
- package/dist/index.js +1905 -1215
- package/dist/index.js.map +1 -1
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +2 -2
- package/dist/node/index.d.ts +2 -2
- package/dist/node/index.js +1 -1
- package/dist/node/index.js.map +1 -1
- package/dist/{provider-CTDncg8U.d.cts → provider-BeCgS86X.d.cts} +64 -1
- package/dist/{provider-CTDncg8U.d.ts → provider-BeCgS86X.d.ts} +64 -1
- package/dist/session/index.cjs +1 -1
- package/dist/session/index.cjs.map +1 -1
- package/dist/session/index.d.cts +2 -2
- package/dist/session/index.d.ts +2 -2
- package/dist/session/index.js +1 -1
- package/dist/session/index.js.map +1 -1
- package/package.json +8 -5
- package/src/iframe/base.ts +1 -1
- package/src/iframe/keychain.ts +11 -0
- package/src/index.ts +1 -0
- package/src/types.ts +24 -0
- package/src/wallets/argent/index.ts +122 -0
- package/src/wallets/bridge.ts +165 -0
- package/src/wallets/index.ts +5 -0
- package/src/wallets/metamask/index.ts +210 -0
- package/src/wallets/phantom/index.ts +124 -0
- package/src/wallets/types.ts +32 -0
package/dist/controller.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { shortString, WalletAccount, constants, Provider } from 'starknet';
|
|
2
2
|
import { connectToChild } from '@cartridge/penpal';
|
|
3
|
+
import { MetaMaskSDK } from '@metamask/sdk';
|
|
4
|
+
import { connect } from 'starknetkit';
|
|
5
|
+
import { InjectedConnector } from 'starknetkit/injected';
|
|
3
6
|
import { Permission } from '@starknet-io/types-js';
|
|
4
7
|
|
|
5
8
|
// src/account.ts
|
|
@@ -174,7 +177,7 @@ var IFrame = class {
|
|
|
174
177
|
this.container = container;
|
|
175
178
|
connectToChild({
|
|
176
179
|
iframe: this.iframe,
|
|
177
|
-
methods: { close: () => this.close(), ...methods }
|
|
180
|
+
methods: { close: (_origin) => () => this.close(), ...methods }
|
|
178
181
|
}).promise.then(onConnect);
|
|
179
182
|
this.resize();
|
|
180
183
|
window.addEventListener("resize", () => this.resize());
|
|
@@ -238,11 +241,472 @@ var IFrame = class {
|
|
|
238
241
|
// src/constants.ts
|
|
239
242
|
var KEYCHAIN_URL = "https://x.cartridge.gg";
|
|
240
243
|
var PROFILE_URL = "https://profile.cartridge.gg";
|
|
244
|
+
var MetaMaskWallet = class {
|
|
245
|
+
type = "metamask";
|
|
246
|
+
platform = "ethereum";
|
|
247
|
+
MMSDK;
|
|
248
|
+
account = void 0;
|
|
249
|
+
constructor() {
|
|
250
|
+
this.MMSDK = new MetaMaskSDK({
|
|
251
|
+
dappMetadata: {
|
|
252
|
+
name: "Cartridge Controller",
|
|
253
|
+
url: window.location.href
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
isAvailable() {
|
|
258
|
+
return typeof window !== "undefined" && !!window.ethereum?.isMetaMask;
|
|
259
|
+
}
|
|
260
|
+
getInfo() {
|
|
261
|
+
const available = this.isAvailable();
|
|
262
|
+
return {
|
|
263
|
+
type: this.type,
|
|
264
|
+
available,
|
|
265
|
+
version: available ? window.ethereum?.version || "Unknown" : void 0,
|
|
266
|
+
chainId: available ? window.ethereum?.chainId : void 0,
|
|
267
|
+
name: "MetaMask",
|
|
268
|
+
platform: this.platform
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
async connect() {
|
|
272
|
+
if (this.account) {
|
|
273
|
+
return { success: true, wallet: this.type, account: this.account };
|
|
274
|
+
}
|
|
275
|
+
try {
|
|
276
|
+
if (!this.isAvailable()) {
|
|
277
|
+
throw new Error("MetaMask is not available");
|
|
278
|
+
}
|
|
279
|
+
const accounts = await this.MMSDK.connect();
|
|
280
|
+
if (accounts && accounts.length > 0) {
|
|
281
|
+
this.account = accounts[0];
|
|
282
|
+
return { success: true, wallet: this.type, account: this.account };
|
|
283
|
+
}
|
|
284
|
+
throw new Error("No accounts found");
|
|
285
|
+
} catch (error) {
|
|
286
|
+
console.error(`Error connecting to MetaMask:`, error);
|
|
287
|
+
return {
|
|
288
|
+
success: false,
|
|
289
|
+
wallet: this.type,
|
|
290
|
+
error: error.message || "Unknown error"
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
async signTransaction(transaction) {
|
|
295
|
+
try {
|
|
296
|
+
if (!this.isAvailable() || !this.account) {
|
|
297
|
+
throw new Error("MetaMask is not connected");
|
|
298
|
+
}
|
|
299
|
+
const ethereum = this.MMSDK.getProvider();
|
|
300
|
+
if (!ethereum) {
|
|
301
|
+
throw new Error("MetaMask is not connected");
|
|
302
|
+
}
|
|
303
|
+
const result = await ethereum.request({
|
|
304
|
+
method: "eth_sendTransaction",
|
|
305
|
+
params: [transaction]
|
|
306
|
+
});
|
|
307
|
+
return { success: true, wallet: this.type, result };
|
|
308
|
+
} catch (error) {
|
|
309
|
+
console.error(`Error signing transaction with MetaMask:`, error);
|
|
310
|
+
return {
|
|
311
|
+
success: false,
|
|
312
|
+
wallet: this.type,
|
|
313
|
+
error: error.message || "Unknown error"
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
async signMessage(message) {
|
|
318
|
+
try {
|
|
319
|
+
if (!this.isAvailable() || !this.account) {
|
|
320
|
+
throw new Error("MetaMask is not connected");
|
|
321
|
+
}
|
|
322
|
+
const result = await this.MMSDK.connectAndSign({
|
|
323
|
+
msg: message
|
|
324
|
+
});
|
|
325
|
+
return { success: true, wallet: this.type, result };
|
|
326
|
+
} catch (error) {
|
|
327
|
+
console.error(`Error signing message with MetaMask:`, error);
|
|
328
|
+
return {
|
|
329
|
+
success: false,
|
|
330
|
+
wallet: this.type,
|
|
331
|
+
error: error.message || "Unknown error"
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
async signTypedData(data) {
|
|
336
|
+
try {
|
|
337
|
+
if (!this.isAvailable() || !this.account) {
|
|
338
|
+
throw new Error("MetaMask is not connected");
|
|
339
|
+
}
|
|
340
|
+
const ethereum = this.MMSDK.getProvider();
|
|
341
|
+
if (!ethereum) {
|
|
342
|
+
throw new Error("MetaMask is not connected");
|
|
343
|
+
}
|
|
344
|
+
const result = await ethereum.request({
|
|
345
|
+
method: "eth_signTypedData_v4",
|
|
346
|
+
params: [this.account, JSON.stringify(data)]
|
|
347
|
+
});
|
|
348
|
+
return { success: true, wallet: this.type, result };
|
|
349
|
+
} catch (error) {
|
|
350
|
+
console.error(`Error signing typed data with MetaMask:`, error);
|
|
351
|
+
return {
|
|
352
|
+
success: false,
|
|
353
|
+
wallet: this.type,
|
|
354
|
+
error: error.message || "Unknown error"
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
async switchChain(chainId) {
|
|
359
|
+
try {
|
|
360
|
+
if (!this.isAvailable()) {
|
|
361
|
+
throw new Error("MetaMask is not available");
|
|
362
|
+
}
|
|
363
|
+
const ethereum = this.MMSDK.getProvider();
|
|
364
|
+
if (!ethereum) {
|
|
365
|
+
throw new Error("MetaMask is not connected");
|
|
366
|
+
}
|
|
367
|
+
try {
|
|
368
|
+
await ethereum.request({
|
|
369
|
+
method: "wallet_switchEthereumChain",
|
|
370
|
+
params: [{ chainId }]
|
|
371
|
+
});
|
|
372
|
+
return true;
|
|
373
|
+
} catch (error) {
|
|
374
|
+
if (error.code === 4902) {
|
|
375
|
+
console.warn("Chain not added to MetaMask");
|
|
376
|
+
}
|
|
377
|
+
throw error;
|
|
378
|
+
}
|
|
379
|
+
} catch (error) {
|
|
380
|
+
console.error(`Error switching chain for MetaMask:`, error);
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
async getBalance(tokenAddress) {
|
|
385
|
+
try {
|
|
386
|
+
if (!this.isAvailable() || !this.account) {
|
|
387
|
+
throw new Error("MetaMask is not connected");
|
|
388
|
+
}
|
|
389
|
+
if (tokenAddress) {
|
|
390
|
+
return {
|
|
391
|
+
success: false,
|
|
392
|
+
wallet: this.type,
|
|
393
|
+
error: "Not implemented for ERC20"
|
|
394
|
+
};
|
|
395
|
+
} else {
|
|
396
|
+
const ethereum = this.MMSDK.getProvider();
|
|
397
|
+
if (!ethereum) {
|
|
398
|
+
throw new Error("MetaMask is not connected");
|
|
399
|
+
}
|
|
400
|
+
const balance = await ethereum.request({
|
|
401
|
+
method: "eth_getBalance",
|
|
402
|
+
params: [this.account, "latest"]
|
|
403
|
+
});
|
|
404
|
+
return { success: true, wallet: this.type, result: balance };
|
|
405
|
+
}
|
|
406
|
+
} catch (error) {
|
|
407
|
+
console.error(`Error getting balance from MetaMask:`, error);
|
|
408
|
+
return {
|
|
409
|
+
success: false,
|
|
410
|
+
wallet: this.type,
|
|
411
|
+
error: error.message || "Unknown error"
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
// src/wallets/phantom/index.ts
|
|
418
|
+
var PhantomWallet = class {
|
|
419
|
+
type = "phantom";
|
|
420
|
+
platform = "solana";
|
|
421
|
+
account = void 0;
|
|
422
|
+
isAvailable() {
|
|
423
|
+
return typeof window !== "undefined" && !!window.solana?.isPhantom;
|
|
424
|
+
}
|
|
425
|
+
getInfo() {
|
|
426
|
+
const available = this.isAvailable();
|
|
427
|
+
return {
|
|
428
|
+
type: this.type,
|
|
429
|
+
available,
|
|
430
|
+
version: "Unknown",
|
|
431
|
+
name: "Phantom",
|
|
432
|
+
platform: this.platform
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
async connect() {
|
|
436
|
+
if (this.account) {
|
|
437
|
+
return { success: true, wallet: this.type, account: this.account };
|
|
438
|
+
}
|
|
439
|
+
try {
|
|
440
|
+
if (!this.isAvailable()) {
|
|
441
|
+
throw new Error("Phantom is not available");
|
|
442
|
+
}
|
|
443
|
+
const response = await window.solana.connect();
|
|
444
|
+
if (response.publicKey) {
|
|
445
|
+
this.account = response.publicKey.toString();
|
|
446
|
+
return { success: true, wallet: this.type, account: this.account };
|
|
447
|
+
}
|
|
448
|
+
throw new Error("No accounts found");
|
|
449
|
+
} catch (error) {
|
|
450
|
+
console.error(`Error connecting to Phantom:`, error);
|
|
451
|
+
return {
|
|
452
|
+
success: false,
|
|
453
|
+
wallet: this.type,
|
|
454
|
+
error: error.message || "Unknown error"
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
async signTransaction(transaction) {
|
|
459
|
+
try {
|
|
460
|
+
if (!this.isAvailable() || !this.account) {
|
|
461
|
+
throw new Error("Phantom is not connected");
|
|
462
|
+
}
|
|
463
|
+
const result = await window.solana.signTransaction(transaction);
|
|
464
|
+
return { success: true, wallet: this.type, result };
|
|
465
|
+
} catch (error) {
|
|
466
|
+
console.error(`Error signing transaction with Phantom:`, error);
|
|
467
|
+
return {
|
|
468
|
+
success: false,
|
|
469
|
+
wallet: this.type,
|
|
470
|
+
error: error.message || "Unknown error"
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
async signMessage(message) {
|
|
475
|
+
try {
|
|
476
|
+
if (!this.isAvailable() || !this.account) {
|
|
477
|
+
throw new Error("Phantom is not connected");
|
|
478
|
+
}
|
|
479
|
+
const encodedMessage = new TextEncoder().encode(message);
|
|
480
|
+
const result = await window.solana.signMessage(encodedMessage, "utf8");
|
|
481
|
+
return { success: true, wallet: this.type, result };
|
|
482
|
+
} catch (error) {
|
|
483
|
+
console.error(`Error signing message with Phantom:`, error);
|
|
484
|
+
return {
|
|
485
|
+
success: false,
|
|
486
|
+
wallet: this.type,
|
|
487
|
+
error: error.message || "Unknown error"
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
async switchChain(_chainId) {
|
|
492
|
+
console.warn("Chain switching not supported for Phantom");
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
async getBalance(_tokenAddress) {
|
|
496
|
+
try {
|
|
497
|
+
if (!this.isAvailable() || !this.account) {
|
|
498
|
+
throw new Error("Phantom is not connected");
|
|
499
|
+
}
|
|
500
|
+
return {
|
|
501
|
+
success: true,
|
|
502
|
+
wallet: this.type,
|
|
503
|
+
result: "Implement based on Phantom API"
|
|
504
|
+
};
|
|
505
|
+
} catch (error) {
|
|
506
|
+
console.error(`Error getting balance from Phantom:`, error);
|
|
507
|
+
return {
|
|
508
|
+
success: false,
|
|
509
|
+
wallet: this.type,
|
|
510
|
+
error: error.message || "Unknown error"
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
};
|
|
515
|
+
var ArgentWallet = class {
|
|
516
|
+
type = "argent";
|
|
517
|
+
platform = "starknet";
|
|
518
|
+
wallet = void 0;
|
|
519
|
+
account = void 0;
|
|
520
|
+
isAvailable() {
|
|
521
|
+
return typeof window !== "undefined" && !!window.starknet_argentX;
|
|
522
|
+
}
|
|
523
|
+
getInfo() {
|
|
524
|
+
const available = this.isAvailable();
|
|
525
|
+
return {
|
|
526
|
+
type: this.type,
|
|
527
|
+
available,
|
|
528
|
+
version: available ? window.starknet_argentX?.version || "Unknown" : void 0,
|
|
529
|
+
chainId: available ? window.starknet_argentX?.chainId : void 0,
|
|
530
|
+
name: "Argent",
|
|
531
|
+
platform: this.platform
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
async connect() {
|
|
535
|
+
if (this.account) {
|
|
536
|
+
return { success: true, wallet: this.type, account: this.account };
|
|
537
|
+
}
|
|
538
|
+
try {
|
|
539
|
+
if (!this.isAvailable()) {
|
|
540
|
+
throw new Error("Argent is not available");
|
|
541
|
+
}
|
|
542
|
+
const { wallet, connectorData } = await connect({
|
|
543
|
+
connectors: [new InjectedConnector({ options: { id: "argentX" } })]
|
|
544
|
+
});
|
|
545
|
+
if (!wallet) {
|
|
546
|
+
throw new Error("No wallet found");
|
|
547
|
+
}
|
|
548
|
+
this.wallet = wallet;
|
|
549
|
+
this.account = connectorData?.account;
|
|
550
|
+
return { success: true, wallet: this.type, account: this.account };
|
|
551
|
+
} catch (error) {
|
|
552
|
+
console.error(`Error connecting to Argent:`, error);
|
|
553
|
+
return {
|
|
554
|
+
success: false,
|
|
555
|
+
wallet: this.type,
|
|
556
|
+
error: error.message || "Unknown error"
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
async signTypedData(data) {
|
|
561
|
+
try {
|
|
562
|
+
if (!this.isAvailable() || !this.wallet) {
|
|
563
|
+
throw new Error("Argent is not connected");
|
|
564
|
+
}
|
|
565
|
+
console.log("signTypedData", data);
|
|
566
|
+
const sig = await this.wallet.request({
|
|
567
|
+
type: "wallet_signTypedData",
|
|
568
|
+
params: data
|
|
569
|
+
});
|
|
570
|
+
return { success: true, wallet: this.type, result: sig };
|
|
571
|
+
} catch (error) {
|
|
572
|
+
console.error(`Error signing typed data with Argent:`, error);
|
|
573
|
+
return {
|
|
574
|
+
success: false,
|
|
575
|
+
wallet: this.type,
|
|
576
|
+
error: error.message || "Unknown error"
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
async switchChain(_chainId) {
|
|
581
|
+
console.warn(
|
|
582
|
+
"Chain switching for Argent may require custom implementation"
|
|
583
|
+
);
|
|
584
|
+
return false;
|
|
585
|
+
}
|
|
586
|
+
async getBalance(_tokenAddress) {
|
|
587
|
+
try {
|
|
588
|
+
if (!this.isAvailable() || !this.wallet) {
|
|
589
|
+
throw new Error("Argent is not connected");
|
|
590
|
+
}
|
|
591
|
+
return {
|
|
592
|
+
success: true,
|
|
593
|
+
wallet: this.type,
|
|
594
|
+
result: "Implement based on Argent API"
|
|
595
|
+
};
|
|
596
|
+
} catch (error) {
|
|
597
|
+
console.error(`Error getting balance from Argent:`, error);
|
|
598
|
+
return {
|
|
599
|
+
success: false,
|
|
600
|
+
wallet: this.type,
|
|
601
|
+
error: error.message || "Unknown error"
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
// src/wallets/bridge.ts
|
|
608
|
+
var WalletBridge = class {
|
|
609
|
+
walletAdapters;
|
|
610
|
+
connectedWallets = /* @__PURE__ */ new Map();
|
|
611
|
+
constructor() {
|
|
612
|
+
this.walletAdapters = /* @__PURE__ */ new Map();
|
|
613
|
+
this.walletAdapters.set("metamask", new MetaMaskWallet());
|
|
614
|
+
this.walletAdapters.set("phantom", new PhantomWallet());
|
|
615
|
+
this.walletAdapters.set("argent", new ArgentWallet());
|
|
616
|
+
if (typeof window !== "undefined") {
|
|
617
|
+
window.wallet_bridge = this;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
getIFrameMethods() {
|
|
621
|
+
return {
|
|
622
|
+
externalDetectWallets: (_origin) => () => this.detectWallets(),
|
|
623
|
+
externalConnectWallet: (_origin) => (type) => this.connectWallet(type),
|
|
624
|
+
externalSignMessage: (_origin) => (type, message) => this.signMessage(type, message),
|
|
625
|
+
externalSignTypedData: (_origin) => (type, data) => this.signTypedData(type, data),
|
|
626
|
+
externalGetBalance: (_origin) => (type, tokenAddress) => this.getBalance(type, tokenAddress)
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
async detectWallets() {
|
|
630
|
+
const wallets = Array.from(this.walletAdapters.values()).map(
|
|
631
|
+
(adapter) => adapter.getInfo()
|
|
632
|
+
);
|
|
633
|
+
return wallets;
|
|
634
|
+
}
|
|
635
|
+
getWalletAdapter(type) {
|
|
636
|
+
const adapter = this.walletAdapters.get(type);
|
|
637
|
+
if (!adapter) {
|
|
638
|
+
throw new Error(`Unsupported wallet type: ${type}`);
|
|
639
|
+
}
|
|
640
|
+
return adapter;
|
|
641
|
+
}
|
|
642
|
+
handleError(type, error, operation) {
|
|
643
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
644
|
+
console.error(`Error ${operation} with ${type} wallet:`, error);
|
|
645
|
+
return { success: false, wallet: type, error: errorMessage };
|
|
646
|
+
}
|
|
647
|
+
async connectWallet(type) {
|
|
648
|
+
try {
|
|
649
|
+
if (this.connectedWallets.has(type)) {
|
|
650
|
+
const wallet2 = this.connectedWallets.get(type);
|
|
651
|
+
return { success: true, wallet: type, account: wallet2.type };
|
|
652
|
+
}
|
|
653
|
+
const wallet = this.getWalletAdapter(type);
|
|
654
|
+
const response = await wallet.connect();
|
|
655
|
+
if (response.success) {
|
|
656
|
+
this.connectedWallets.set(type, wallet);
|
|
657
|
+
}
|
|
658
|
+
return response;
|
|
659
|
+
} catch (error) {
|
|
660
|
+
return this.handleError(type, error, "connecting to");
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
async signMessage(type, message) {
|
|
664
|
+
try {
|
|
665
|
+
if (!this.connectedWallets.has(type)) {
|
|
666
|
+
throw new Error(`Wallet ${type} is not connected`);
|
|
667
|
+
}
|
|
668
|
+
const wallet = this.connectedWallets.get(type);
|
|
669
|
+
if (!wallet.signMessage) {
|
|
670
|
+
throw new Error(`Wallet ${type} does not support signing messages`);
|
|
671
|
+
}
|
|
672
|
+
return await wallet.signMessage(message);
|
|
673
|
+
} catch (error) {
|
|
674
|
+
return this.handleError(type, error, "signing message with");
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
async signTypedData(type, data) {
|
|
678
|
+
try {
|
|
679
|
+
if (!this.connectedWallets.has(type)) {
|
|
680
|
+
throw new Error(`Wallet ${type} is not connected`);
|
|
681
|
+
}
|
|
682
|
+
const wallet = this.connectedWallets.get(type);
|
|
683
|
+
if (!wallet.signTypedData) {
|
|
684
|
+
throw new Error(`Wallet ${type} does not support signing typed data`);
|
|
685
|
+
}
|
|
686
|
+
return await wallet.signTypedData(data);
|
|
687
|
+
} catch (error) {
|
|
688
|
+
return this.handleError(type, error, "signing typed data with");
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
async getBalance(type, tokenAddress) {
|
|
692
|
+
try {
|
|
693
|
+
if (!this.connectedWallets.has(type)) {
|
|
694
|
+
throw new Error(`Wallet ${type} is not connected`);
|
|
695
|
+
}
|
|
696
|
+
const wallet = this.connectedWallets.get(type);
|
|
697
|
+
return await wallet.getBalance(tokenAddress);
|
|
698
|
+
} catch (error) {
|
|
699
|
+
return this.handleError(type, error, "getting balance from");
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
};
|
|
241
703
|
|
|
242
704
|
// src/iframe/keychain.ts
|
|
243
705
|
var KeychainIFrame = class extends IFrame {
|
|
706
|
+
walletBridge;
|
|
244
707
|
constructor({ url, policies, ...iframeOptions }) {
|
|
245
708
|
const _url = new URL(url ?? KEYCHAIN_URL);
|
|
709
|
+
const walletBridge = new WalletBridge();
|
|
246
710
|
if (policies) {
|
|
247
711
|
_url.searchParams.set(
|
|
248
712
|
"policies",
|
|
@@ -252,8 +716,13 @@ var KeychainIFrame = class extends IFrame {
|
|
|
252
716
|
super({
|
|
253
717
|
...iframeOptions,
|
|
254
718
|
id: "controller-keychain",
|
|
255
|
-
url: _url
|
|
719
|
+
url: _url,
|
|
720
|
+
methods: walletBridge.getIFrameMethods()
|
|
256
721
|
});
|
|
722
|
+
this.walletBridge = walletBridge;
|
|
723
|
+
}
|
|
724
|
+
getWalletBridge() {
|
|
725
|
+
return this.walletBridge;
|
|
257
726
|
}
|
|
258
727
|
};
|
|
259
728
|
|
|
@@ -315,7 +784,7 @@ var NotReadyToConnect = class _NotReadyToConnect extends Error {
|
|
|
315
784
|
|
|
316
785
|
// package.json
|
|
317
786
|
var package_default = {
|
|
318
|
-
version: "0.7.
|
|
787
|
+
version: "0.7.8"};
|
|
319
788
|
|
|
320
789
|
// src/icon.ts
|
|
321
790
|
var icon = "data:image/png;base64,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";
|