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