@cartridge/controller 0.7.13-alpha.3 → 0.7.13

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/types.d.ts CHANGED
@@ -93,7 +93,7 @@ export interface Keychain {
93
93
  switchChain(rpcUrl: string): Promise<void>;
94
94
  openStarterPack(starterpackId: string): void;
95
95
  externalDetectWallets(): Promise<ExternalWallet[]>;
96
- externalConnectWallet(type: ExternalWalletType): Promise<ExternalWalletResponse>;
96
+ externalConnectWallet(type: ExternalWalletType, address?: string): Promise<ExternalWalletResponse>;
97
97
  externalSignMessage(type: ExternalWalletType, message: string): Promise<ExternalWalletResponse>;
98
98
  externalSignTypedData(type: ExternalWalletType, data: any): Promise<ExternalWalletResponse>;
99
99
  externalGetBalance(type: ExternalWalletType, tokenAddress?: string): Promise<ExternalWalletResponse>;
@@ -1,13 +1,15 @@
1
- import { WalletAdapter, ExternalWallet, ExternalWalletResponse, ExternalWalletType, ExternalPlatform } from '../types';
2
1
  import { TypedData } from '@starknet-io/types-js';
2
+ import { ExternalPlatform, ExternalWallet, ExternalWalletResponse, ExternalWalletType, WalletAdapter } from '../types';
3
3
  export declare class ArgentWallet implements WalletAdapter {
4
4
  readonly type: ExternalWalletType;
5
5
  readonly platform: ExternalPlatform;
6
6
  private wallet;
7
7
  private account;
8
+ private connectedAccounts;
8
9
  isAvailable(): boolean;
9
10
  getInfo(): ExternalWallet;
10
11
  connect(): Promise<ExternalWalletResponse<any>>;
12
+ getConnectedAccounts(): string[];
11
13
  signTypedData(data: TypedData): Promise<ExternalWalletResponse<any>>;
12
14
  sendTransaction(_txn: any): Promise<ExternalWalletResponse<any>>;
13
15
  switchChain(_chainId: string): Promise<boolean>;
@@ -1,12 +1,10 @@
1
1
  import { ExternalWallet, ExternalWalletResponse, ExternalWalletType } from './types';
2
2
  export declare class WalletBridge {
3
3
  private readonly walletAdapters;
4
- private readonly connectedWalletsByType;
5
- private readonly connectedWalletsByAddress;
6
4
  constructor();
7
5
  getIFrameMethods(): {
8
6
  externalDetectWallets: (_origin: string) => () => Promise<ExternalWallet[]>;
9
- externalConnectWallet: (_origin: string) => (type: ExternalWalletType) => Promise<ExternalWalletResponse<unknown>>;
7
+ externalConnectWallet: (_origin: string) => (type: ExternalWalletType, address?: string) => Promise<ExternalWalletResponse<unknown>>;
10
8
  externalSignMessage: (_origin: string) => (identifier: ExternalWalletType | string, message: string) => Promise<ExternalWalletResponse<unknown>>;
11
9
  externalSignTypedData: (_origin: string) => (identifier: ExternalWalletType | string, data: any) => Promise<ExternalWalletResponse<unknown>>;
12
10
  externalSendTransaction: (_origin: string) => (identifier: ExternalWalletType | string, txn: any) => Promise<ExternalWalletResponse<unknown>>;
@@ -15,7 +13,7 @@ export declare class WalletBridge {
15
13
  detectWallets(): Promise<ExternalWallet[]>;
16
14
  private getWalletAdapterByType;
17
15
  private handleError;
18
- connectWallet(type: ExternalWalletType): Promise<ExternalWalletResponse>;
16
+ connectWallet(type: ExternalWalletType, address?: string): Promise<ExternalWalletResponse>;
19
17
  private getConnectedWalletAdapter;
20
18
  signMessage(identifier: ExternalWalletType | string, message: string): Promise<ExternalWalletResponse>;
21
19
  signTypedData(identifier: ExternalWalletType | string, data: any): Promise<ExternalWalletResponse>;
@@ -3,12 +3,14 @@ export declare class MetaMaskWallet implements WalletAdapter {
3
3
  readonly type: ExternalWalletType;
4
4
  readonly platform: ExternalPlatform;
5
5
  private MMSDK;
6
+ private store;
6
7
  private account;
7
8
  private connectedAccounts;
8
9
  constructor();
9
10
  isAvailable(): boolean;
10
11
  getInfo(): ExternalWallet;
11
- connect(): Promise<ExternalWalletResponse<any>>;
12
+ connect(address?: string): Promise<ExternalWalletResponse<any>>;
13
+ getConnectedAccounts(): string[];
12
14
  signTransaction(transaction: any): Promise<ExternalWalletResponse<any>>;
13
15
  signMessage(message: string): Promise<ExternalWalletResponse<any>>;
14
16
  signTypedData(data: any): Promise<ExternalWalletResponse<any>>;
@@ -1,12 +1,14 @@
1
- import { WalletAdapter, ExternalWallet, ExternalWalletResponse, ExternalWalletType, ExternalPlatform } from '../types';
1
+ import { ExternalPlatform, ExternalWallet, ExternalWalletResponse, ExternalWalletType, WalletAdapter } from '../types';
2
2
  export declare class PhantomWallet implements WalletAdapter {
3
3
  readonly type: ExternalWalletType;
4
4
  readonly platform: ExternalPlatform;
5
5
  private account;
6
+ private connectedAccounts;
6
7
  private getProvider;
7
8
  isAvailable(): boolean;
8
9
  getInfo(): ExternalWallet;
9
10
  connect(): Promise<ExternalWalletResponse<any>>;
11
+ getConnectedAccounts(): string[];
10
12
  signMessage(message: string): Promise<ExternalWalletResponse<any>>;
11
13
  sendTransaction(serailized_txn: Uint8Array): Promise<ExternalWalletResponse<any>>;
12
14
  switchChain(_chainId: string): Promise<boolean>;
@@ -9,7 +9,8 @@ export declare class RabbyWallet implements WalletAdapter {
9
9
  constructor();
10
10
  isAvailable(): boolean;
11
11
  getInfo(): ExternalWallet;
12
- connect(): Promise<ExternalWalletResponse<any>>;
12
+ connect(address?: string): Promise<ExternalWalletResponse<any>>;
13
+ getConnectedAccounts(): string[];
13
14
  signTransaction(transaction: any): Promise<ExternalWalletResponse<any>>;
14
15
  signMessage(message: `0x${string}`): Promise<ExternalWalletResponse<any>>;
15
16
  signTypedData(data: any): Promise<ExternalWalletResponse<any>>;
@@ -10,6 +10,7 @@ export declare class TurnkeyWallet implements WalletAdapter {
10
10
  isAvailable(): boolean;
11
11
  getInfo(): ExternalWallet;
12
12
  connect(): Promise<ExternalWalletResponse<any>>;
13
+ getConnectedAccounts(): string[];
13
14
  signTransaction(transaction: any): Promise<ExternalWalletResponse<any>>;
14
15
  signMessage(message: string): Promise<ExternalWalletResponse<any>>;
15
16
  signTypedData(data: any): Promise<ExternalWalletResponse<any>>;
@@ -21,7 +21,8 @@ export interface WalletAdapter {
21
21
  platform: ExternalPlatform;
22
22
  isAvailable(): boolean;
23
23
  getInfo(): ExternalWallet;
24
- connect(): Promise<ExternalWalletResponse<any>>;
24
+ getConnectedAccounts(): string[];
25
+ connect(address?: string): Promise<ExternalWalletResponse<any>>;
25
26
  signMessage?(message: string): Promise<ExternalWalletResponse<any>>;
26
27
  signTypedData?(data: any): Promise<ExternalWalletResponse<any>>;
27
28
  sendTransaction(tx: any): Promise<ExternalWalletResponse<any>>;
@@ -5,7 +5,8 @@ export declare class WalletConnectWallet implements WalletAdapter {
5
5
  readonly type: ExternalWalletType;
6
6
  readonly platform: ExternalPlatform;
7
7
  private account;
8
- constructor(provider: Provider, account?: string);
8
+ constructor(provider: Provider, address?: string);
9
+ getConnectedAccounts(): string[];
9
10
  isAvailable(): boolean;
10
11
  getInfo(): ExternalWallet;
11
12
  connect(): Promise<ExternalWalletResponse<any>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cartridge/controller",
3
- "version": "0.7.13-alpha.3",
3
+ "version": "0.7.13",
4
4
  "description": "Cartridge Controller",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -36,8 +36,8 @@
36
36
  "cbor-x": "^1.5.0",
37
37
  "mipd": "^0.0.7",
38
38
  "@walletconnect/ethereum-provider": "^2.20.0",
39
- "@cartridge/account-wasm": "0.7.13-alpha.3",
40
- "@cartridge/utils": "0.7.13-alpha.3"
39
+ "@cartridge/account-wasm": "0.7.13",
40
+ "@cartridge/utils": "0.7.13"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/jest": "^29.5.14",
@@ -53,7 +53,7 @@
53
53
  "vite-plugin-node-polyfills": "^0.22.0",
54
54
  "vite-plugin-top-level-await": "^1.4.4",
55
55
  "vite-plugin-wasm": "^3.4.1",
56
- "@cartridge/tsconfig": "0.7.13-alpha.3"
56
+ "@cartridge/tsconfig": "0.7.13"
57
57
  },
58
58
  "scripts": {
59
59
  "build:deps": "pnpm build",
package/src/types.ts CHANGED
@@ -145,6 +145,7 @@ export interface Keychain {
145
145
  externalDetectWallets(): Promise<ExternalWallet[]>;
146
146
  externalConnectWallet(
147
147
  type: ExternalWalletType,
148
+ address?: string,
148
149
  ): Promise<ExternalWalletResponse>;
149
150
  externalSignMessage(
150
151
  type: ExternalWalletType,
@@ -1,19 +1,20 @@
1
+ import { TypedData } from "@starknet-io/types-js";
2
+ import { connect, StarknetWindowObject } from "starknetkit";
3
+ import { InjectedConnector } from "starknetkit/injected";
1
4
  import {
2
- WalletAdapter,
5
+ ExternalPlatform,
3
6
  ExternalWallet,
4
7
  ExternalWalletResponse,
5
8
  ExternalWalletType,
6
- ExternalPlatform,
9
+ WalletAdapter,
7
10
  } from "../types";
8
- import { connect, StarknetWindowObject } from "starknetkit";
9
- import { InjectedConnector } from "starknetkit/injected";
10
- import { TypedData } from "@starknet-io/types-js";
11
11
 
12
12
  export class ArgentWallet implements WalletAdapter {
13
13
  readonly type: ExternalWalletType = "argent";
14
14
  readonly platform: ExternalPlatform = "starknet";
15
15
  private wallet: StarknetWindowObject | undefined = undefined;
16
16
  private account: string | undefined = undefined;
17
+ private connectedAccounts: string[] = [];
17
18
 
18
19
  isAvailable(): boolean {
19
20
  return typeof window !== "undefined" && !!window.starknet_argentX;
@@ -65,6 +66,10 @@ export class ArgentWallet implements WalletAdapter {
65
66
  }
66
67
  }
67
68
 
69
+ getConnectedAccounts(): string[] {
70
+ return this.connectedAccounts;
71
+ }
72
+
68
73
  async signTypedData(data: TypedData): Promise<ExternalWalletResponse<any>> {
69
74
  try {
70
75
  if (!this.isAvailable() || !this.wallet) {
@@ -11,21 +11,19 @@ import {
11
11
 
12
12
  export class WalletBridge {
13
13
  private readonly walletAdapters: Map<ExternalWalletType, WalletAdapter>;
14
- private readonly connectedWalletsByType: Map<
15
- ExternalWalletType,
16
- WalletAdapter
17
- > = new Map();
18
- private readonly connectedWalletsByAddress: Map<string, WalletAdapter> =
19
- new Map();
20
14
 
21
15
  constructor() {
22
16
  this.walletAdapters = new Map<ExternalWalletType, WalletAdapter>();
17
+
23
18
  const metamask = new MetaMaskWallet();
24
19
  metamask.isAvailable() && this.walletAdapters.set("metamask", metamask);
20
+
25
21
  const phantom = new PhantomWallet();
26
22
  phantom.isAvailable() && this.walletAdapters.set("phantom", phantom);
23
+
27
24
  const argent = new ArgentWallet();
28
25
  argent.isAvailable() && this.walletAdapters.set("argent", argent);
26
+
29
27
  const rabby = new RabbyWallet();
30
28
  rabby.isAvailable() && this.walletAdapters.set("rabby", rabby);
31
29
 
@@ -37,8 +35,9 @@ export class WalletBridge {
37
35
  getIFrameMethods() {
38
36
  return {
39
37
  externalDetectWallets: (_origin: string) => () => this.detectWallets(),
40
- externalConnectWallet: (_origin: string) => (type: ExternalWalletType) =>
41
- this.connectWallet(type),
38
+ externalConnectWallet:
39
+ (_origin: string) => (type: ExternalWalletType, address?: string) =>
40
+ this.connectWallet(type, address),
42
41
  externalSignMessage:
43
42
  (_origin: string) =>
44
43
  (identifier: ExternalWalletType | string, message: string) =>
@@ -84,7 +83,7 @@ export class WalletBridge {
84
83
  error instanceof Error ? error.message : "Unknown error";
85
84
  let walletType: ExternalWalletType | string = "unknown";
86
85
  if (typeof identifier === "string") {
87
- const adapter = this.connectedWalletsByAddress.get(identifier);
86
+ const adapter = this.getConnectedWalletAdapter(identifier);
88
87
  walletType = responseType ?? adapter?.type ?? identifier;
89
88
  } else {
90
89
  walletType = identifier;
@@ -100,14 +99,13 @@ export class WalletBridge {
100
99
 
101
100
  async connectWallet(
102
101
  type: ExternalWalletType,
102
+ address?: string,
103
103
  ): Promise<ExternalWalletResponse> {
104
104
  try {
105
105
  const wallet = this.getWalletAdapterByType(type);
106
- const response = await wallet.connect();
106
+ const response = await wallet.connect(address);
107
107
 
108
108
  if (response.success && response.account) {
109
- this.connectedWalletsByType.set(type, wallet);
110
- this.connectedWalletsByAddress.set(response.account, wallet);
111
109
  console.log(
112
110
  `Wallet ${type} connected with address ${response.account}`,
113
111
  );
@@ -133,15 +131,22 @@ export class WalletBridge {
133
131
  ): WalletAdapter {
134
132
  let wallet: WalletAdapter | undefined;
135
133
  if (typeof identifier === "string") {
136
- wallet = this.connectedWalletsByAddress.get(identifier);
134
+ // this is an address
135
+ wallet = this.walletAdapters
136
+ .values()
137
+ .find((adapter) =>
138
+ adapter.getConnectedAccounts().includes(identifier.toLowerCase()),
139
+ );
137
140
  } else {
138
- wallet = this.connectedWalletsByType.get(identifier);
141
+ wallet = this.walletAdapters.get(identifier);
139
142
  }
140
143
 
141
144
  if (!wallet && typeof identifier === "string") {
142
- wallet = this.connectedWalletsByType.get(
143
- identifier as ExternalWalletType,
144
- );
145
+ wallet = this.walletAdapters
146
+ .values()
147
+ .find((adapter) =>
148
+ adapter.getConnectedAccounts().includes(identifier.toLowerCase()),
149
+ );
145
150
  }
146
151
 
147
152
  if (!wallet) {
@@ -1,4 +1,5 @@
1
1
  import { MetaMaskSDK } from "@metamask/sdk";
2
+ import { createStore } from "mipd";
2
3
  import {
3
4
  ExternalPlatform,
4
5
  ExternalWallet,
@@ -11,6 +12,7 @@ export class MetaMaskWallet implements WalletAdapter {
11
12
  readonly type: ExternalWalletType = "metamask";
12
13
  readonly platform: ExternalPlatform = "ethereum";
13
14
  private MMSDK: MetaMaskSDK;
15
+ private store = createStore();
14
16
  private account: string | undefined = undefined;
15
17
  private connectedAccounts: string[] = [];
16
18
 
@@ -21,23 +23,35 @@ export class MetaMaskWallet implements WalletAdapter {
21
23
  url: window.location.href,
22
24
  },
23
25
  });
24
- this.MMSDK.sdkInitPromise?.then(() => {
25
- this.MMSDK.getProvider()
26
- ?.request({
27
- method: "eth_accounts",
28
- })
29
- .then((accounts: any) => {
30
- if (accounts && accounts.length > 0) {
31
- console.log(accounts);
32
- this.account = accounts[0];
26
+ if (this.isAvailable()) {
27
+ this.MMSDK.sdkInitPromise?.then(() => {
28
+ this.MMSDK.getProvider()
29
+ ?.request({
30
+ method: "eth_accounts",
31
+ })
32
+ .then((accounts: any) => {
33
+ if (accounts && accounts.length > 0) {
34
+ this.account = accounts[0];
35
+ this.connectedAccounts = accounts;
36
+ }
37
+ });
38
+ this.MMSDK.getProvider()?.on("accountsChanged", (accounts: any) => {
39
+ if (Array.isArray(accounts)) {
40
+ this.account = accounts?.[0];
33
41
  this.connectedAccounts = accounts;
34
42
  }
35
43
  });
36
- });
44
+ });
45
+ }
37
46
  }
38
47
 
39
48
  isAvailable(): boolean {
40
- return typeof window !== "undefined" && !!window.ethereum?.isMetaMask;
49
+ return (
50
+ typeof window !== "undefined" &&
51
+ this.store
52
+ .getProviders()
53
+ .some((provider) => provider.info.rdns === "io.metamask")
54
+ );
41
55
  }
42
56
 
43
57
  getInfo(): ExternalWallet {
@@ -54,7 +68,11 @@ export class MetaMaskWallet implements WalletAdapter {
54
68
  };
55
69
  }
56
70
 
57
- async connect(): Promise<ExternalWalletResponse<any>> {
71
+ async connect(address?: string): Promise<ExternalWalletResponse<any>> {
72
+ if (address && this.connectedAccounts.includes(address)) {
73
+ this.account = address;
74
+ }
75
+
58
76
  if (this.account) {
59
77
  return { success: true, wallet: this.type, account: this.account };
60
78
  }
@@ -82,6 +100,10 @@ export class MetaMaskWallet implements WalletAdapter {
82
100
  }
83
101
  }
84
102
 
103
+ getConnectedAccounts(): string[] {
104
+ return this.connectedAccounts;
105
+ }
106
+
85
107
  async signTransaction(
86
108
  transaction: any,
87
109
  ): Promise<ExternalWalletResponse<any>> {
@@ -1,10 +1,10 @@
1
1
  import { PublicKey, Transaction, VersionedTransaction } from "@solana/web3.js";
2
2
  import {
3
- WalletAdapter,
3
+ ExternalPlatform,
4
4
  ExternalWallet,
5
5
  ExternalWalletResponse,
6
6
  ExternalWalletType,
7
- ExternalPlatform,
7
+ WalletAdapter,
8
8
  } from "../types";
9
9
 
10
10
  interface PhantomProvider {
@@ -38,6 +38,7 @@ export class PhantomWallet implements WalletAdapter {
38
38
  readonly type: ExternalWalletType = "phantom";
39
39
  readonly platform: ExternalPlatform = "solana";
40
40
  private account: string | undefined = undefined;
41
+ private connectedAccounts: string[] = [];
41
42
 
42
43
  private getProvider(): PhantomProvider {
43
44
  if (typeof window === "undefined") {
@@ -96,6 +97,10 @@ export class PhantomWallet implements WalletAdapter {
96
97
  }
97
98
  }
98
99
 
100
+ getConnectedAccounts(): string[] {
101
+ return this.connectedAccounts;
102
+ }
103
+
99
104
  async signMessage(message: string): Promise<ExternalWalletResponse<any>> {
100
105
  try {
101
106
  if (!this.isAvailable() || !this.account) {
@@ -28,6 +28,15 @@ export class RabbyWallet implements WalletAdapter {
28
28
  .then((accounts) => {
29
29
  this.connectedAccounts = accounts;
30
30
  });
31
+ this.provider?.provider?.on("accountsChanged", (accounts: string[]) => {
32
+ if (accounts) {
33
+ // rabby doesn't allow multiple accounts to be connected at the same time
34
+ this.connectedAccounts = accounts.map((account) =>
35
+ account.toLowerCase(),
36
+ );
37
+ this.account = accounts?.[0]?.toLowerCase();
38
+ }
39
+ });
31
40
  }
32
41
 
33
42
  isAvailable(): boolean {
@@ -48,7 +57,11 @@ export class RabbyWallet implements WalletAdapter {
48
57
  };
49
58
  }
50
59
 
51
- async connect(): Promise<ExternalWalletResponse<any>> {
60
+ async connect(address?: string): Promise<ExternalWalletResponse<any>> {
61
+ if (address && this.connectedAccounts.includes(address.toLowerCase())) {
62
+ this.account = address.toLowerCase();
63
+ }
64
+
52
65
  if (this.account) {
53
66
  return { success: true, wallet: this.type, account: this.account };
54
67
  }
@@ -78,6 +91,10 @@ export class RabbyWallet implements WalletAdapter {
78
91
  }
79
92
  }
80
93
 
94
+ getConnectedAccounts(): string[] {
95
+ return this.connectedAccounts;
96
+ }
97
+
81
98
  async signTransaction(
82
99
  transaction: any,
83
100
  ): Promise<ExternalWalletResponse<any>> {
@@ -114,7 +131,6 @@ export class RabbyWallet implements WalletAdapter {
114
131
  if (!this.isAvailable() || !this.account) {
115
132
  throw new Error("Rabby is not connected");
116
133
  }
117
-
118
134
  const result = await this.provider?.provider.request({
119
135
  method: "personal_sign",
120
136
  params: [this.account!, message] as any,
@@ -68,6 +68,10 @@ export class TurnkeyWallet implements WalletAdapter {
68
68
  }
69
69
  }
70
70
 
71
+ getConnectedAccounts(): string[] {
72
+ return this.account ? [this.account] : [];
73
+ }
74
+
71
75
  async signTransaction(
72
76
  transaction: any,
73
77
  ): Promise<ExternalWalletResponse<any>> {
@@ -26,7 +26,8 @@ export interface WalletAdapter {
26
26
  // Methods
27
27
  isAvailable(): boolean;
28
28
  getInfo(): ExternalWallet;
29
- connect(): Promise<ExternalWalletResponse<any>>;
29
+ getConnectedAccounts(): string[];
30
+ connect(address?: string): Promise<ExternalWalletResponse<any>>;
30
31
  signMessage?(message: string): Promise<ExternalWalletResponse<any>>;
31
32
  signTypedData?(data: any): Promise<ExternalWalletResponse<any>>;
32
33
  sendTransaction(tx: any): Promise<ExternalWalletResponse<any>>;
@@ -7,6 +7,7 @@ import {
7
7
  WalletAdapter,
8
8
  } from "../types";
9
9
 
10
+ // TODO(tedison): move wallet to inside the keychain
10
11
  export class WalletConnectWallet implements WalletAdapter {
11
12
  readonly type: ExternalWalletType = "walletconnect" as ExternalWalletType;
12
13
  readonly platform: ExternalPlatform = "ethereum";
@@ -14,9 +15,13 @@ export class WalletConnectWallet implements WalletAdapter {
14
15
 
15
16
  constructor(
16
17
  private provider: Provider,
17
- account?: string,
18
+ address?: string,
18
19
  ) {
19
- this.account = account;
20
+ this.account = address?.toLowerCase();
21
+ }
22
+
23
+ getConnectedAccounts(): string[] {
24
+ return this.account ? [this.account] : [];
20
25
  }
21
26
 
22
27
  isAvailable(): boolean {
@@ -100,7 +105,7 @@ export class WalletConnectWallet implements WalletAdapter {
100
105
 
101
106
  const result = await this.provider.request({
102
107
  method: "personal_sign",
103
- params: [this.account!, message] as any,
108
+ params: [message, this.account!],
104
109
  });
105
110
 
106
111
  return { success: true, wallet: this.type, result };
@@ -1 +0,0 @@
1
- {"version":3,"file":"provider-M8-BWFF8.js","sources":["../src/types.ts","../src/utils.ts","../src/constants.ts","../src/errors.ts","../../../node_modules/.pnpm/@starknet-io+types-js@0.7.10/node_modules/@starknet-io/types-js/dist/esm/wallet-api/constants.js","../src/icon.ts","../src/mutex.ts","../src/provider.ts"],"sourcesContent":["import {\n constants,\n BigNumberish,\n Call,\n Abi,\n InvocationsDetails,\n} from \"starknet\";\nimport {\n AddInvokeTransactionResult,\n ChainId,\n Signature,\n TypedData,\n} from \"@starknet-io/types-js\";\nimport { KeychainIFrame, ProfileIFrame } from \"./iframe\";\nimport { Policy, SessionPolicies } from \"@cartridge/presets\";\nimport {\n ExternalWallet,\n ExternalWalletResponse,\n ExternalWalletType,\n} from \"./wallets/types\";\n\nexport type Session = {\n chainId: constants.StarknetChainId;\n policies: Policy[];\n maxFee: BigNumberish;\n expiresAt: bigint;\n credentials: {\n authorization: string[];\n privateKey: string;\n };\n};\n\nexport enum ResponseCodes {\n SUCCESS = \"SUCCESS\",\n NOT_CONNECTED = \"NOT_CONNECTED\",\n ERROR = \"ERROR\",\n CANCELED = \"CANCELED\",\n USER_INTERACTION_REQUIRED = \"USER_INTERACTION_REQUIRED\",\n}\n\nexport type ConnectError = {\n code: ResponseCodes;\n message: string;\n error?: ControllerError;\n};\n\nexport type ControllerError = {\n code: Number;\n message: string;\n data?: any;\n};\n\nexport type ConnectReply = {\n code: ResponseCodes.SUCCESS;\n address: string;\n policies?: SessionPolicies;\n};\n\nexport type ExecuteReply =\n | (AddInvokeTransactionResult & {\n code: ResponseCodes.SUCCESS;\n })\n | {\n code: ResponseCodes.USER_INTERACTION_REQUIRED;\n };\n\nexport type ProbeReply = {\n code: ResponseCodes.SUCCESS;\n address: string;\n rpcUrl?: string;\n};\n\nexport type DeployReply = {\n code: ResponseCodes.SUCCESS;\n transaction_hash: string;\n};\n\nexport type IFrames = {\n keychain: KeychainIFrame;\n profile?: ProfileIFrame;\n version?: number;\n};\n\nexport interface LookupRequest {\n usernames?: string[];\n addresses?: string[];\n}\n\nexport interface LookupResult {\n username: string;\n addresses: string[];\n}\n\nexport interface LookupResponse {\n results: LookupResult[];\n}\n\nexport enum FeeSource {\n PAYMASTER = \"PAYMASTER\",\n CREDITS = \"CREDITS\",\n}\n\ntype ContractAddress = string;\ntype CartridgeID = string;\nexport type ControllerAccounts = Record<ContractAddress, CartridgeID>;\n\nexport interface Keychain {\n probe(rpcUrl: string): Promise<ProbeReply | ConnectError>;\n connect(\n policies: SessionPolicies,\n rpcUrl: string,\n ): Promise<ConnectReply | ConnectError>;\n disconnect(): void;\n\n reset(): void;\n revoke(origin: string): void;\n\n deploy(): Promise<DeployReply | ConnectError>;\n execute(\n calls: Call | Call[],\n abis?: Abi[],\n transactionsDetail?: InvocationsDetails,\n sync?: boolean,\n feeSource?: any,\n error?: ControllerError,\n ): Promise<ExecuteReply | ConnectError>;\n signMessage(\n typedData: TypedData,\n account: string,\n async?: boolean,\n ): Promise<Signature | ConnectError>;\n openSettings(): Promise<void | ConnectError>;\n session(): Promise<Session>;\n sessions(): Promise<{\n [key: string]: Session;\n }>;\n delegateAccount(): string;\n username(): string;\n openPurchaseCredits(): void;\n openExecute(calls: Call[]): Promise<void>;\n switchChain(rpcUrl: string): Promise<void>;\n openStarterPack(starterpackId: string): void;\n\n // External wallet methods\n externalDetectWallets(): Promise<ExternalWallet[]>;\n externalConnectWallet(\n type: ExternalWalletType,\n ): Promise<ExternalWalletResponse>;\n externalSignMessage(\n type: ExternalWalletType,\n message: string,\n ): Promise<ExternalWalletResponse>;\n externalSignTypedData(\n type: ExternalWalletType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n data: any,\n ): Promise<ExternalWalletResponse>;\n externalGetBalance(\n type: ExternalWalletType,\n tokenAddress?: string,\n ): Promise<ExternalWalletResponse>;\n}\n\nexport interface Profile {\n navigate(path: string): void;\n switchChain(rpcUrl: string): Promise<void>;\n}\n\nexport interface Modal {\n open: () => void;\n close: () => void;\n}\n\n/**\n * Options for configuring the controller\n */\nexport type ControllerOptions = ProviderOptions &\n KeychainOptions &\n ProfileOptions;\n\nexport type IFrameOptions = {\n /** The ID of the starter pack to use */\n starterPackId?: string;\n /** The preset to use */\n preset?: string;\n};\n\nexport type Chain = {\n rpcUrl: string;\n};\n\nexport type ProviderOptions = {\n defaultChainId: ChainId;\n chains: Chain[];\n};\n\nexport type KeychainOptions = IFrameOptions & {\n policies?: SessionPolicies;\n /** The URL of keychain */\n url?: string;\n /** The origin of keychain */\n origin?: string;\n /** Propagate transaction errors back to caller instead of showing modal */\n propagateSessionErrors?: boolean;\n /** The fee source to use for execute from outside */\n feeSource?: FeeSource;\n};\n\nexport type ProfileOptions = IFrameOptions & {\n /** The URL of profile. Mainly for internal development purpose */\n profileUrl?: string;\n /** The project name of Slot instance. */\n slot?: string;\n /** The namespace to use to fetch trophies data from indexer. Will be mandatory once profile page is in production */\n namespace?: string;\n /** The tokens to be listed on Inventory modal */\n tokens?: Tokens;\n /** The policies to use for the profile */\n policies?: SessionPolicies;\n};\n\nexport type ProfileContextTypeVariant =\n | \"inventory\"\n | \"trophies\"\n | \"achievements\"\n | \"leaderboard\"\n | \"activity\";\n\nexport type Tokens = {\n erc20?: string[];\n};\n","import {\n addAddressPadding,\n Call,\n CallData,\n constants,\n getChecksumAddress,\n hash,\n Provider,\n shortString,\n typedData,\n TypedDataRevision,\n} from \"starknet\";\nimport wasm from \"@cartridge/account-wasm/controller\";\nimport { Policies, SessionPolicies } from \"@cartridge/presets\";\nimport { ChainId } from \"@starknet-io/types-js\";\nimport { ParsedSessionPolicies } from \"./policies\";\n\n// Whitelist of allowed property names to prevent prototype pollution\nconst ALLOWED_PROPERTIES = new Set([\n \"contracts\",\n \"messages\",\n \"target\",\n \"method\",\n \"name\",\n \"description\",\n \"types\",\n \"domain\",\n \"primaryType\",\n]);\n\nconst LOCAL_HOSTNAMES = [\"localhost\", \"127.0.0.1\", \"0.0.0.0\"];\n\nfunction validatePropertyName(prop: string): void {\n if (!ALLOWED_PROPERTIES.has(prop)) {\n throw new Error(`Invalid property name: ${prop}`);\n }\n}\n\nfunction safeObjectAccess<T>(obj: any, prop: string): T {\n validatePropertyName(prop);\n return obj[prop];\n}\n\nexport function normalizeCalls(calls: Call | Call[]) {\n return toArray(calls).map((call) => {\n return {\n entrypoint: call.entrypoint,\n contractAddress: addAddressPadding(call.contractAddress),\n calldata: CallData.toHex(call.calldata),\n };\n });\n}\n\nexport function toSessionPolicies(policies: Policies): SessionPolicies {\n return Array.isArray(policies)\n ? policies.reduce<SessionPolicies>(\n (prev, p) => {\n if (safeObjectAccess<string>(p, \"target\")) {\n const target = getChecksumAddress(\n safeObjectAccess<string>(p, \"target\"),\n );\n const entrypoint = safeObjectAccess<string>(p, \"method\");\n const contracts = safeObjectAccess<Record<string, any>>(\n prev,\n \"contracts\",\n );\n const item = {\n name: humanizeString(entrypoint),\n entrypoint: entrypoint,\n description: safeObjectAccess<string>(p, \"description\"),\n };\n\n if (target in contracts) {\n const methods = toArray(contracts[target].methods);\n contracts[target] = {\n methods: [...methods, item],\n };\n } else {\n contracts[target] = {\n methods: [item],\n };\n }\n } else {\n const messages = safeObjectAccess<any[]>(prev, \"messages\");\n messages.push(p);\n }\n\n return prev;\n },\n { contracts: {}, messages: [] },\n )\n : policies;\n}\n\nexport function toWasmPolicies(policies: ParsedSessionPolicies): wasm.Policy[] {\n return [\n ...Object.entries(policies.contracts ?? {}).flatMap(\n ([target, { methods }]) =>\n toArray(methods).map((m) => ({\n target,\n method: m.entrypoint,\n authorized: m.authorized,\n })),\n ),\n ...(policies.messages ?? []).map((p) => {\n const domainHash = typedData.getStructHash(\n p.types,\n \"StarknetDomain\",\n p.domain,\n TypedDataRevision.ACTIVE,\n );\n const typeHash = typedData.getTypeHash(\n p.types,\n p.primaryType,\n TypedDataRevision.ACTIVE,\n );\n\n return {\n scope_hash: hash.computePoseidonHash(domainHash, typeHash),\n authorized: p.authorized,\n };\n }),\n ];\n}\n\nexport function toArray<T>(val: T | T[]): T[] {\n return Array.isArray(val) ? val : [val];\n}\n\nexport function humanizeString(str: string): string {\n return (\n str\n // Convert from camelCase or snake_case\n .replace(/([a-z])([A-Z])/g, \"$1 $2\") // camelCase to spaces\n .replace(/_/g, \" \") // snake_case to spaces\n .toLowerCase()\n // Capitalize first letter\n .replace(/^\\w/, (c) => c.toUpperCase())\n );\n}\n\nexport async function parseChainId(url: URL): Promise<ChainId> {\n const parts = url.pathname.split(\"/\");\n\n if (parts.includes(\"starknet\")) {\n if (parts.includes(\"mainnet\")) {\n return constants.StarknetChainId.SN_MAIN;\n } else if (parts.includes(\"sepolia\")) {\n return constants.StarknetChainId.SN_SEPOLIA;\n }\n } else if (parts.length >= 3) {\n const projectName = parts[2];\n if (parts.includes(\"katana\")) {\n return shortString.encodeShortString(\n `WP_${projectName.toUpperCase().replace(/-/g, \"_\")}`,\n ) as ChainId;\n } else if (parts.includes(\"mainnet\")) {\n return shortString.encodeShortString(\n `GG_${projectName.toUpperCase().replace(/-/g, \"_\")}`,\n ) as ChainId;\n }\n }\n\n if (LOCAL_HOSTNAMES.includes(url.hostname)) {\n const provider = new Provider({\n nodeUrl: url.toString(),\n });\n return await provider.getChainId();\n }\n\n throw new Error(`Chain ${url.toString()} not supported`);\n}\n","export const KEYCHAIN_URL = \"https://x.cartridge.gg\";\nexport const PROFILE_URL = \"https://profile.cartridge.gg\";\nexport const API_URL = \"https://api.cartridge.gg\";\n","export class NotReadyToConnect extends Error {\n constructor() {\n super(\"Not ready to connect\");\n\n Object.setPrototypeOf(this, NotReadyToConnect.prototype);\n }\n}\n","export const Permission = {\n ACCOUNTS: 'accounts',\n};\n//# sourceMappingURL=constants.js.map","export const icon =\n \"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODAwIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGZpbHRlcj0idXJsKCNmaWx0ZXIwX2RfNTExMl83ODIpIj4KPHBhdGggZD0iTTQ2OS4yMzYgNzBDNDgyLjM5IDcwIDQ5My4wNTMgODAuNjYzIDQ5My4wNTMgOTMuODE2NFYxNDcuMTQ3TDUxNS4zMzggMTQ3LjE0N0w1MTUuNDI4IDE0Ny4xNDdMNTE1LjU1NCAxNDcuMTQ3TDUxNS44MjYgMTQ3LjE0OUM1MTYuMDE2IDE0Ny4xNTEgNTE2LjIyNSAxNDcuMTUzIDUxNi40NTEgMTQ3LjE1N0M1MTYuOTA0IDE0Ny4xNjQgNTE3LjQyOCAxNDcuMTc2IDUxOC4wMiAxNDcuMTk1QzUxOS4yMDEgMTQ3LjIzNCA1MjAuNjYgMTQ3LjMwNCA1MjIuMzYxIDE0Ny40MjRDNTI1Ljc0MSAxNDcuNjYzIDUzMC4xODUgMTQ4LjExNCA1MzUuMzYzIDE0OC45NjlDNTQ1LjAwMSAxNTAuNTYyIDU1OC41NTYgMTUzLjc4IDU3Mi45MTggMTYwLjYwM0w3MzAuNDIgMjI2LjY3MUw3MzIuMTAxIDIyNy41MDVDNzcxLjc4NyAyNDcuMTc3IDc4OS45OTMgMjg2LjI5NiA3ODkuOTkzIDMyMi4wMzZWNTg1Ljg2NUM3ODkuOTkzIDU4Ni4wNTQgNzg5Ljk5NCA1ODYuMjU0IDc4OS45OTQgNTg2LjQ2M0w3ODkuOTk2IDU4Ni45MTNDNzkwLjAzOCA1OTcuMDk2IDc5MC4xNjEgNjI2Ljk5NiA3NjQuMjMxIDY1Mi44MjNMNzE0Ljc2IDcwMi4wOTVMNzE0LjY0MSA3MDIuMjE1QzcwNC42MDEgNzEyLjI3NSA2OTIuMTIzIDcyMC42NTIgNjc2LjI4NCA3MjQuODc5QzY2NC4zOSA3MjguMDU0IDY1Mi44MjcgNzI3Ljk2NiA2NDguNjM3IDcyNy45MzRMNjQ4LjYxOSA3MjcuOTMzQzY0OC40MDkgNzI3LjkzMiA2NDguMjE5IDcyNy45MyA2NDguMDQ3IDcyNy45M0w2NDcuNzUyIDcyNy45MjlINDgwLjcyMUM0NzQuMDk0IDcyNy45MjkgNDY4LjcyMSA3MjIuNTU2IDQ2OC43MjEgNzE1LjkyOVY2NjguMzg4SDMyOC41ODZDMzI4LjU4NiA2NzIuNjI5IDMyOC41NzIgNjk4LjA1MiAzMjguNTYxIDcxNS45NDRDMzI4LjU1NyA3MjIuNTY5IDMyMy4xODYgNzI3LjkyOSAzMTYuNTYxIDcyNy45MjlIMTUyLjI0NkMxNTIuMTA0IDcyNy45MjkgMTUxLjk0MiA3MjcuOTI5IDE1MS43NjIgNzI3LjkzMUwxNTEuMzYyIDcyNy45MzRDMTQ3LjE3MiA3MjcuOTY2IDEzNS42MDkgNzI4LjA1NCAxMjMuNzE0IDcyNC44NzlDMTA3Ljg3MyA3MjAuNjUxIDk1LjM5MzggNzEyLjI3MiA4NS4zNTI5IDcwMi4yMUw4NS4yMzg2IDcwMi4wOTVMMzUuNjcgNjUyLjcyNUwzNS41NzIzIDY1Mi42MjdDOS44NjI0MiA2MjYuNzggOS45NjY3IDU5Ny4xODUgMTAuMDAzIDU4Ni44NzRDMTAuMDA0MyA1ODYuNTEzIDEwLjAwNTUgNTg2LjE3NyAxMC4wMDU1IDU4NS44NjVWMzIyLjAzNkMxMC4wMDU1IDI4Ni40MyAyOC4xNjYyIDI0Ny4xOTkgNjcuODk3NyAyMjcuNTA1TDY5LjU3OSAyMjYuNjcxTDIyNy4wODEgMTYwLjYwM0MyNDEuNDQzIDE1My43OCAyNTQuOTk4IDE1MC41NjIgMjY0LjYzNiAxNDguOTY5QzI2OS44MTQgMTQ4LjExNCAyNzQuMjU4IDE0Ny42NjMgMjc3LjYzOCAxNDcuNDI0QzI3OS4zMzggMTQ3LjMwNCAyODAuNzk4IDE0Ny4yMzQgMjgxLjk3OSAxNDcuMTk1QzI4Mi41NzEgMTQ3LjE3NiAyODMuMDk1IDE0Ny4xNjQgMjgzLjU0NyAxNDcuMTU3TDI4My45MTcgMTQ3LjE1MkwyODQuMTczIDE0Ny4xNDlMMjg0LjQ0NSAxNDcuMTQ3TDI4NC41NzEgMTQ3LjE0N0wyODQuNjYgMTQ3LjE0N0wzMDYuOTQyIDE0Ny4xNDdWOTMuODE2NEMzMDYuOTQyIDgwLjY2MyAzMTcuNjA1IDcwIDMzMC43NTggNzBINDY5LjIzNloiIGZpbGw9IiMxOTFBMUEiLz4KPHBhdGggZD0iTTM2Ni40ODMgMTI5LjU0SDQzMy41MTJWMjA2LjY4N0gzNjYuNDgzVjEyOS41NFoiIGZpbGw9IiNGQkNCNEEiLz4KPHBhdGggZD0iTTI2OS4wMSA2MDIuNDI5SDE0NC4wMDhDMTM1Ljc2OCA2MDIuNDI5IDEzNS43NjggNTk0LjE0NiAxMzUuNzY4IDU5NC4xNDZWMjgwLjg1QzEzNS43NjggMjgwLjg1IDEzNS43NjggMjcyLjY0NCAxNDQuMDA4IDI3Mi42NDRIMzY2LjQ4M0wzNjYuNDgzIDIwNi42ODdIMjg0LjY5QzI4NC42OSAyMDYuNjg3IDI2OC4xMzQgMjA2LjY4NyAyNTEuNTc5IDIxNC44OTNMOTQuMzQxNCAyODAuODVDNzcuNzg2MSAyODkuMDU3IDY5LjU0NjkgMzA1LjYyMyA2OS41NDY5IDMyMi4wMzVWNTg1Ljg2M0M2OS41NDY5IDU5NC4xNDcgNjkuNTQ2OSA2MDIuMzUzIDc3Ljc4NjEgNjEwLjYzNkwxMjcuNDUyIDY2MC4xMDRDMTM1LjY5MSA2NjguMzg3IDE0MS45MjggNjY4LjM4NyAxNTIuMjQ3IDY2OC4zODdIMjY5LjAyOUMyNjkuMDM3IDY0OC4zNCAyNjkuMDQ2IDYyNC42NTUgMjY5LjA1NCA2MDIuODg3SDUyOC4wMTNWNjY4LjM4N0g2NDcuNzUzQzY1OC4wNzEgNjY4LjM4NyA2NjQuMzA4IDY2OC4zODcgNjcyLjU0NyA2NjAuMTA0TDcyMi4yMTMgNjEwLjYzNkM3MzAuNDUzIDYwMi40MjkgNzMwLjQ1MyA1OTQuMTQ3IDczMC40NTMgNTg1Ljg2M1YzMjIuMDM1QzczMC40NTMgMzA1LjU0NiA3MjIuMjEzIDI4OS4wNTcgNzA1LjY1OCAyODAuODVMNTQ4LjQyMSAyMTQuODkzQzUzMS44NjUgMjA2LjY4NyA1MTUuMzEgMjA2LjY4NyA1MTUuMzEgMjA2LjY4N0g0MzMuNTEyTDQzMy41MTIgMjcyLjY0NEg2NTYuMDY5QzY2NC4zMDggMjcyLjY0NCA2NjQuMzA4IDI4MC44NSA2NjQuMzA4IDI4MC44NVY1OTQuMTQ2QzY2NC4zMDggNTk0LjE0NiA2NjQuMzA4IDYwMi40MjkgNjU2LjA2OSA2MDIuNDI5SDUyOC4yNjJWNTM3LjM5NkgyNjkuMDc1QzI2OS4wNzUgNTQzLjcwNyAyNjkuMDE3IDU5Ni45MTIgMjY5LjAxIDYwMi40MjlaIiBmaWxsPSIjRkJDQjRBIi8+CjxwYXRoIGQ9Ik0yNjkuMDA5IDQzNi4xNzJINTI4LjI2MlYzNzAuNjgxSDI2OS4wNzVDMjY5LjA3NSAzNzcuMzczIDI2OS4wMDkgNDM2Ljc4OCAyNjkuMDA5IDQzNi4xNzJaIiBmaWxsPSIjRkJDQjRBIi8+CjwvZz4KPGRlZnM+CjxmaWx0ZXIgaWQ9ImZpbHRlcjBfZF81MTEyXzc4MiIgeD0iLTQiIHk9IjAiIHdpZHRoPSI4MDgiIGhlaWdodD0iODA4IiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+CjxmZUNvbG9yTWF0cml4IGluPSJTb3VyY2VBbHBoYSIgdHlwZT0ibWF0cml4IiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDEyNyAwIiByZXN1bHQ9ImhhcmRBbHBoYSIvPgo8ZmVPZmZzZXQgZHk9IjQiLz4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMiIvPgo8ZmVDb21wb3NpdGUgaW4yPSJoYXJkQWxwaGEiIG9wZXJhdG9yPSJvdXQiLz4KPGZlQ29sb3JNYXRyaXggdHlwZT0ibWF0cml4IiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAuMjUgMCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9ImVmZmVjdDFfZHJvcFNoYWRvd181MTEyXzc4MiIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9ImVmZmVjdDFfZHJvcFNoYWRvd181MTEyXzc4MiIgcmVzdWx0PSJzaGFwZSIvPgo8L2ZpbHRlcj4KPC9kZWZzPgo8L3N2Zz4K\";\n","function releaseStub() {}\n\n/**\n * A simple mutual exclusion lock. It allows you to obtain and release a lock,\n * ensuring that only one task can access a critical section at a time.\n */\nexport class Mutex {\n private m_lastPromise: Promise<void> = Promise.resolve();\n\n /**\n * Acquire lock\n * @param [bypass=false] option to skip lock acquisition\n */\n public async obtain(bypass = false): Promise<() => void> {\n let release = releaseStub;\n if (bypass) return release;\n const lastPromise = this.m_lastPromise;\n this.m_lastPromise = new Promise<void>((resolve) => (release = resolve));\n await lastPromise;\n return release;\n }\n}\n","import { WalletAccount } from \"starknet\";\nimport {\n AddInvokeTransactionParameters,\n AddStarknetChainParameters,\n Errors,\n Permission,\n RequestAccountsParameters,\n RequestFn,\n StarknetWindowObject,\n SwitchStarknetChainParameters,\n TypedData,\n WalletEventHandlers,\n WalletEventListener,\n WalletEvents,\n} from \"@starknet-io/types-js\";\nimport manifest from \"../package.json\";\n\nimport { icon } from \"./icon\";\nimport { Mutex } from \"./mutex\";\n\nconst mutex = new Mutex();\n\nexport default abstract class BaseProvider implements StarknetWindowObject {\n public id = \"controller\";\n public name = \"Controller\";\n public version = manifest.version;\n public icon = icon;\n\n public account?: WalletAccount;\n public subscriptions: WalletEvents[] = [];\n\n private _probePromise: Promise<WalletAccount | undefined> | null = null;\n\n protected async safeProbe(): Promise<WalletAccount | undefined> {\n // If we already have an account, return it\n if (this.account) {\n return this.account;\n }\n\n // If we're already probing, wait for the existing probe\n if (this._probePromise) {\n return this._probePromise;\n }\n\n const release = await mutex.obtain();\n return await new Promise<WalletAccount | undefined>(async (resolve) => {\n try {\n this._probePromise = this.probe();\n const result = await this._probePromise;\n resolve(result);\n } finally {\n this._probePromise = null;\n }\n }).finally(() => {\n release();\n });\n }\n\n request: RequestFn = async (call) => {\n switch (call.type) {\n case \"wallet_getPermissions\":\n await this.safeProbe();\n\n if (this.account) {\n return [Permission.ACCOUNTS];\n }\n\n return [];\n\n case \"wallet_requestAccounts\": {\n if (this.account) {\n return [this.account.address];\n }\n\n const silentMode =\n call.params && (call.params as RequestAccountsParameters).silent_mode;\n\n this.account = await this.safeProbe();\n\n if (!this.account && !silentMode) {\n this.account = await this.connect();\n }\n\n if (this.account) {\n return [this.account.address];\n }\n\n return [];\n }\n\n case \"wallet_watchAsset\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_watchAsset not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_addStarknetChain\": {\n let params = call.params as AddStarknetChainParameters;\n return this.addStarknetChain(params);\n }\n\n case \"wallet_switchStarknetChain\": {\n let params = call.params as SwitchStarknetChainParameters;\n return this.switchStarknetChain(params.chainId);\n }\n\n case \"wallet_requestChainId\":\n if (!this.account) {\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"Account not initialized\",\n } as Errors.UNEXPECTED_ERROR;\n }\n\n return await this.account.getChainId();\n\n case \"wallet_deploymentData\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_deploymentData not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_addInvokeTransaction\":\n if (!this.account) {\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"Account not initialized\",\n } as Errors.UNEXPECTED_ERROR;\n }\n\n let params = call.params as AddInvokeTransactionParameters;\n return await this.account.execute(\n params.calls.map((call) => ({\n contractAddress: call.contract_address,\n entrypoint: call.entry_point,\n calldata: call.calldata,\n })),\n );\n\n case \"wallet_addDeclareTransaction\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_addDeclareTransaction not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_signTypedData\": {\n if (!this.account) {\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"Account not initialized\",\n } as Errors.UNEXPECTED_ERROR;\n }\n\n return await this.account.signMessage(call.params as TypedData);\n }\n\n case \"wallet_supportedSpecs\":\n return [];\n case \"wallet_supportedWalletApi\":\n return [];\n default:\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: `Unknown RPC call type: ${call.type}`,\n } as Errors.UNEXPECTED_ERROR;\n }\n };\n\n on: WalletEventListener = <E extends keyof WalletEventHandlers>(\n event: E,\n handler: WalletEventHandlers[E],\n ): void => {\n if (event !== \"accountsChanged\" && event !== \"networkChanged\") {\n throw new Error(`Unknown event: ${event}`);\n }\n this.subscriptions.push({ type: event, handler } as WalletEvents);\n };\n\n off: WalletEventListener = <E extends keyof WalletEventHandlers>(\n event: E,\n handler: WalletEventHandlers[E],\n ): void => {\n if (event !== \"accountsChanged\" && event !== \"networkChanged\") {\n throw new Error(`Unknown event: ${event}`);\n }\n const idx = this.subscriptions.findIndex(\n (sub) => sub.type === event && sub.handler === handler,\n );\n if (idx >= 0) {\n this.subscriptions.splice(idx, 1);\n }\n };\n\n protected emitNetworkChanged(chainId: string) {\n this.subscriptions\n .filter((sub) => sub.type === \"networkChanged\")\n .forEach((sub) => {\n (sub.handler as WalletEventHandlers[\"networkChanged\"])(chainId);\n });\n }\n\n protected emitAccountsChanged(accounts: string[]) {\n this.subscriptions\n .filter((sub) => sub.type === \"accountsChanged\")\n .forEach((sub) => {\n (sub.handler as WalletEventHandlers[\"accountsChanged\"])(accounts);\n });\n }\n\n abstract probe(): Promise<WalletAccount | undefined>;\n abstract connect(): Promise<WalletAccount | undefined>;\n abstract switchStarknetChain(chainId: string): Promise<boolean>;\n abstract addStarknetChain(\n chain: AddStarknetChainParameters,\n ): Promise<boolean>;\n}\n"],"names":["ResponseCodes","FeeSource","ALLOWED_PROPERTIES","LOCAL_HOSTNAMES","validatePropertyName","prop","safeObjectAccess","obj","normalizeCalls","calls","toArray","call","addAddressPadding","CallData","toSessionPolicies","policies","prev","p","target","getChecksumAddress","entrypoint","contracts","item","humanizeString","methods","toWasmPolicies","m","domainHash","typedData","TypedDataRevision","typeHash","hash","val","str","c","parseChainId","url","parts","constants","projectName","shortString","Provider","KEYCHAIN_URL","PROFILE_URL","API_URL","NotReadyToConnect","Permission","icon","releaseStub","Mutex","bypass","release","lastPromise","resolve","mutex","BaseProvider","manifest","result","silentMode","params","event","handler","idx","sub","chainId","accounts"],"mappings":"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","x_google_ignoreList":[4]}