@cartridge/controller 0.8.0 → 0.9.1

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 (45) hide show
  1. package/.turbo/turbo-build$colon$deps.log +51 -49
  2. package/.turbo/turbo-build.log +47 -45
  3. package/dist/account.d.ts +2 -3
  4. package/dist/controller.d.ts +2 -3
  5. package/dist/iframe/base.d.ts +1 -0
  6. package/dist/iframe/index.d.ts +0 -1
  7. package/dist/iframe/keychain.d.ts +4 -2
  8. package/dist/index.js +466 -518
  9. package/dist/index.js.map +1 -1
  10. package/dist/node/index.cjs +2 -2
  11. package/dist/node/index.cjs.map +1 -1
  12. package/dist/node/index.d.cts +2 -2
  13. package/dist/node/index.d.ts +2 -2
  14. package/dist/node/index.js +2 -2
  15. package/dist/node/index.js.map +1 -1
  16. package/dist/{provider-ClUbos7A.js → provider-iltRv2Q1.js} +21 -22
  17. package/dist/provider-iltRv2Q1.js.map +1 -0
  18. package/dist/provider.d.ts +1 -1
  19. package/dist/session.js +10 -10
  20. package/dist/session.js.map +1 -1
  21. package/dist/stats.html +1 -1
  22. package/dist/types.d.ts +4 -8
  23. package/dist/wallets/bridge.d.ts +2 -2
  24. package/dist/wallets/metamask/index.d.ts +2 -2
  25. package/dist/wallets/rabby/index.d.ts +1 -1
  26. package/dist/wallets/types.d.ts +2 -2
  27. package/package.json +7 -6
  28. package/src/account.ts +5 -8
  29. package/src/controller.ts +32 -74
  30. package/src/iframe/base.ts +6 -24
  31. package/src/iframe/index.ts +0 -1
  32. package/src/iframe/keychain.ts +32 -2
  33. package/src/node/account.ts +1 -1
  34. package/src/provider.ts +9 -9
  35. package/src/session/account.ts +1 -2
  36. package/src/types.ts +3 -11
  37. package/src/wallets/bridge.ts +5 -18
  38. package/src/wallets/metamask/index.ts +9 -13
  39. package/src/wallets/rabby/index.ts +9 -4
  40. package/src/wallets/types.ts +5 -2
  41. package/.turbo/turbo-format$colon$check.log +0 -7
  42. package/.turbo/turbo-format.log +0 -44
  43. package/dist/iframe/profile.d.ts +0 -12
  44. package/dist/provider-ClUbos7A.js.map +0 -1
  45. package/src/iframe/profile.ts +0 -59
package/dist/types.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Policy, SessionPolicies } from '@cartridge/presets';
2
2
  import { AddInvokeTransactionResult, ChainId, Signature, TypedData } from '@starknet-io/types-js';
3
3
  import { Abi, BigNumberish, Call, constants, InvocationsDetails } from 'starknet';
4
- import { KeychainIFrame, ProfileIFrame } from './iframe';
4
+ import { KeychainIFrame } from './iframe';
5
5
  import { ExternalWallet, ExternalWalletResponse, ExternalWalletType } from './wallets/types';
6
6
  export type Session = {
7
7
  chainId: constants.StarknetChainId;
@@ -53,7 +53,6 @@ export type DeployReply = {
53
53
  };
54
54
  export type IFrames = {
55
55
  keychain: KeychainIFrame;
56
- profile?: ProfileIFrame;
57
56
  version?: number;
58
57
  };
59
58
  export interface LookupRequest {
@@ -76,7 +75,7 @@ type CartridgeID = string;
76
75
  export type ControllerAccounts = Record<ContractAddress, CartridgeID>;
77
76
  export interface Keychain {
78
77
  probe(rpcUrl: string): Promise<ProbeReply | ConnectError>;
79
- connect(policies: SessionPolicies, rpcUrl: string, signupOptions?: AuthOptions, version?: string): Promise<ConnectReply | ConnectError>;
78
+ connect(policies: SessionPolicies, rpcUrl: string, signupOptions?: AuthOptions): Promise<ConnectReply | ConnectError>;
80
79
  disconnect(): void;
81
80
  reset(): void;
82
81
  revoke(origin: string): void;
@@ -94,6 +93,7 @@ export interface Keychain {
94
93
  openExecute(calls: Call[]): Promise<void>;
95
94
  switchChain(rpcUrl: string): Promise<void>;
96
95
  openStarterPack(starterpackId: string): void;
96
+ navigate(path: string): Promise<void>;
97
97
  externalDetectWallets(): Promise<ExternalWallet[]>;
98
98
  externalConnectWallet(type: ExternalWalletType, address?: string): Promise<ExternalWalletResponse>;
99
99
  externalSignMessage(type: ExternalWalletType, message: string): Promise<ExternalWalletResponse>;
@@ -111,7 +111,7 @@ export interface Modal {
111
111
  /**
112
112
  * Options for configuring the controller
113
113
  */
114
- export type ControllerOptions = ProviderOptions & KeychainOptions & ProfileOptions;
114
+ export type ControllerOptions = ProviderOptions & KeychainOptions;
115
115
  export type IFrameOptions = {
116
116
  /** The ID of the starter pack to use */
117
117
  starterPackId?: string;
@@ -139,10 +139,6 @@ export type KeychainOptions = IFrameOptions & {
139
139
  signupOptions?: AuthOptions;
140
140
  /** When true, manually provided policies will override preset policies. Default is false. */
141
141
  shouldOverridePresetPolicies?: boolean;
142
- };
143
- export type ProfileOptions = IFrameOptions & {
144
- /** The URL of profile. Mainly for internal development purpose */
145
- profileUrl?: string;
146
142
  /** The project name of Slot instance. */
147
143
  slot?: string;
148
144
  /** The namespace to use to fetch trophies data from indexer. Will be mandatory once profile page is in production */
@@ -4,7 +4,7 @@ export declare class WalletBridge {
4
4
  constructor();
5
5
  getIFrameMethods(): {
6
6
  externalDetectWallets: (_origin: string) => () => Promise<ExternalWallet[]>;
7
- externalConnectWallet: (_origin: string) => (type: ExternalWalletType, address?: string) => Promise<ExternalWalletResponse<unknown>>;
7
+ externalConnectWallet: (_origin: string) => (type: ExternalWalletType) => Promise<ExternalWalletResponse<unknown>>;
8
8
  externalSignMessage: (_origin: string) => (identifier: ExternalWalletType | string, message: string) => Promise<ExternalWalletResponse<unknown>>;
9
9
  externalSignTypedData: (_origin: string) => (identifier: ExternalWalletType | string, data: any) => Promise<ExternalWalletResponse<unknown>>;
10
10
  externalSendTransaction: (_origin: string) => (identifier: ExternalWalletType | string, txn: any) => Promise<ExternalWalletResponse<unknown>>;
@@ -13,7 +13,7 @@ export declare class WalletBridge {
13
13
  detectWallets(): Promise<ExternalWallet[]>;
14
14
  private getWalletAdapterByType;
15
15
  private handleError;
16
- connectWallet(type: ExternalWalletType, address?: string): Promise<ExternalWalletResponse>;
16
+ connectWallet(type: ExternalWalletType): Promise<ExternalWalletResponse>;
17
17
  private getConnectedWalletAdapter;
18
18
  signMessage(identifier: ExternalWalletType | string, message: string): Promise<ExternalWalletResponse>;
19
19
  signTypedData(identifier: ExternalWalletType | string, data: any): Promise<ExternalWalletResponse>;
@@ -9,10 +9,10 @@ export declare class MetaMaskWallet implements WalletAdapter {
9
9
  constructor();
10
10
  isAvailable(): boolean;
11
11
  getInfo(): ExternalWallet;
12
- connect(address?: string): Promise<ExternalWalletResponse<any>>;
12
+ connect(): Promise<ExternalWalletResponse<any>>;
13
13
  getConnectedAccounts(): string[];
14
14
  signTransaction(transaction: any): Promise<ExternalWalletResponse<any>>;
15
- signMessage(message: string): Promise<ExternalWalletResponse<any>>;
15
+ signMessage(message: string, address?: string): Promise<ExternalWalletResponse<any>>;
16
16
  signTypedData(data: any): Promise<ExternalWalletResponse<any>>;
17
17
  sendTransaction(_txn: any): Promise<ExternalWalletResponse<any>>;
18
18
  switchChain(chainId: string): Promise<boolean>;
@@ -12,7 +12,7 @@ export declare class RabbyWallet implements WalletAdapter {
12
12
  connect(address?: string): Promise<ExternalWalletResponse<any>>;
13
13
  getConnectedAccounts(): string[];
14
14
  signTransaction(transaction: any): Promise<ExternalWalletResponse<any>>;
15
- signMessage(message: `0x${string}`): Promise<ExternalWalletResponse<any>>;
15
+ signMessage(message: `0x${string}`, address?: string): Promise<ExternalWalletResponse<any>>;
16
16
  signTypedData(data: any): Promise<ExternalWalletResponse<any>>;
17
17
  sendTransaction(_txn: any): Promise<ExternalWalletResponse<any>>;
18
18
  switchChain(chainId: string): Promise<boolean>;
@@ -22,8 +22,8 @@ export interface WalletAdapter {
22
22
  isAvailable(): boolean;
23
23
  getInfo(): ExternalWallet;
24
24
  getConnectedAccounts(): string[];
25
- connect(address?: string): Promise<ExternalWalletResponse<any>>;
26
- signMessage?(message: string): Promise<ExternalWalletResponse<any>>;
25
+ connect(): Promise<ExternalWalletResponse<any>>;
26
+ signMessage?(message: string, address?: string): Promise<ExternalWalletResponse<any>>;
27
27
  signTypedData?(data: any): Promise<ExternalWalletResponse<any>>;
28
28
  sendTransaction(tx: any): Promise<ExternalWalletResponse<any>>;
29
29
  getBalance(tokenAddress?: string): Promise<ExternalWalletResponse<any>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cartridge/controller",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "description": "Cartridge Controller",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -24,14 +24,14 @@
24
24
  "@metamask/sdk": "^0.32.1",
25
25
  "@solana/web3.js": "^1.98.0",
26
26
  "open": "^10.1.0",
27
- "starknet": "^6.21.0",
27
+ "starknet": "^7.6.2",
28
28
  "starknetkit": "^2.6.1"
29
29
  },
30
30
  "dependencies": {
31
- "@cartridge/controller-wasm": "0.1.7",
31
+ "@cartridge/controller-wasm": "^0.2.3",
32
32
  "@cartridge/penpal": "^6.2.4",
33
33
  "ethers": "^6.13.5",
34
- "@starknet-io/types-js": "^0.7.7",
34
+ "@starknet-io/types-js": "^0.8.4",
35
35
  "@telegram-apps/sdk": "^2.4.0",
36
36
  "@turnkey/sdk-browser": "^4.0.0",
37
37
  "cbor-x": "^1.5.0",
@@ -50,10 +50,10 @@
50
50
  "typescript": "^5.7.3",
51
51
  "vite": "^6.0.0",
52
52
  "vite-plugin-dts": "^4.5.3",
53
- "vite-plugin-node-polyfills": "^0.22.0",
53
+ "vite-plugin-node-polyfills": "^0.23.0",
54
54
  "vite-plugin-top-level-await": "^1.4.4",
55
55
  "vite-plugin-wasm": "^3.4.1",
56
- "@cartridge/tsconfig": "0.8.0"
56
+ "@cartridge/tsconfig": "0.9.1"
57
57
  },
58
58
  "scripts": {
59
59
  "build:deps": "pnpm build",
@@ -61,6 +61,7 @@
61
61
  "build:browser": "vite build",
62
62
  "build:node": "tsup --config tsup.node.config.ts",
63
63
  "build": "pnpm build:browser && pnpm build:node",
64
+ "build:compat": "pnpm build:browser && pnpm build:node",
64
65
  "format": "prettier --write \"src/**/*.ts\"",
65
66
  "format:check": "prettier --check \"src/**/*.ts\"",
66
67
  "test": "jest",
package/src/account.ts CHANGED
@@ -6,8 +6,6 @@ import {
6
6
  AllowArray,
7
7
  } from "starknet";
8
8
 
9
- import { SPEC } from "@starknet-io/types-js";
10
-
11
9
  import {
12
10
  ConnectError,
13
11
  Keychain,
@@ -18,9 +16,9 @@ import {
18
16
  import { AsyncMethodReturns } from "@cartridge/penpal";
19
17
  import BaseProvider from "./provider";
20
18
  import { toArray } from "./utils";
19
+ import { SIGNATURE } from "@starknet-io/types-js";
21
20
 
22
21
  class ControllerAccount extends WalletAccount {
23
- address: string;
24
22
  private keychain: AsyncMethodReturns<Keychain>;
25
23
  private modal: Modal;
26
24
  private options?: KeychainOptions;
@@ -33,9 +31,8 @@ class ControllerAccount extends WalletAccount {
33
31
  options: KeychainOptions,
34
32
  modal: Modal,
35
33
  ) {
36
- super({ nodeUrl: rpcUrl }, provider);
34
+ super({ nodeUrl: rpcUrl }, provider, address);
37
35
 
38
- this.address = address;
39
36
  this.keychain = keychain;
40
37
  this.options = options;
41
38
  this.modal = modal;
@@ -111,13 +108,13 @@ class ControllerAccount extends WalletAccount {
111
108
  * @returns the signature of the JSON object
112
109
  * @throws {Error} if the JSON object is not a valid JSON
113
110
  */
114
- async signMessage(typedData: TypedData): Promise<SPEC.SIGNATURE> {
111
+ async signMessage(typedData: TypedData): Promise<SIGNATURE> {
115
112
  return new Promise(async (resolve, reject) => {
116
113
  const sessionSign = await this.keychain.signMessage(typedData, "", true);
117
114
 
118
115
  // Session sign succeeded
119
116
  if (!("code" in sessionSign)) {
120
- resolve(sessionSign as SPEC.SIGNATURE);
117
+ resolve(sessionSign as SIGNATURE);
121
118
  return;
122
119
  }
123
120
 
@@ -126,7 +123,7 @@ class ControllerAccount extends WalletAccount {
126
123
  const manualSign = await this.keychain.signMessage(typedData, "", false);
127
124
 
128
125
  if (!("code" in manualSign)) {
129
- resolve(manualSign as SPEC.SIGNATURE);
126
+ resolve(manualSign as SIGNATURE);
130
127
  } else {
131
128
  reject((manualSign as ConnectError).error);
132
129
  }
package/src/controller.ts CHANGED
@@ -10,7 +10,7 @@ import { constants, shortString, WalletAccount } from "starknet";
10
10
  import { version } from "../package.json";
11
11
  import ControllerAccount from "./account";
12
12
  import { NotReadyToConnect } from "./errors";
13
- import { KeychainIFrame, ProfileIFrame } from "./iframe";
13
+ import { KeychainIFrame } from "./iframe";
14
14
  import BaseProvider from "./provider";
15
15
  import {
16
16
  Chain,
@@ -20,7 +20,6 @@ import {
20
20
  IFrames,
21
21
  Keychain,
22
22
  ProbeReply,
23
- Profile,
24
23
  ProfileContextTypeVariant,
25
24
  ResponseCodes,
26
25
  } from "./types";
@@ -28,7 +27,6 @@ import { parseChainId } from "./utils";
28
27
 
29
28
  export default class ControllerProvider extends BaseProvider {
30
29
  private keychain?: AsyncMethodReturns<Keychain>;
31
- private profile?: AsyncMethodReturns<Profile>;
32
30
  private options: ControllerOptions;
33
31
  private iframes: IFrames;
34
32
  private selectedChain: ChainId;
@@ -38,7 +36,7 @@ export default class ControllerProvider extends BaseProvider {
38
36
  return !!this.keychain;
39
37
  }
40
38
 
41
- constructor(options: ControllerOptions) {
39
+ constructor(options: ControllerOptions = {}) {
42
40
  super();
43
41
 
44
42
  // Default Cartridge chains that are always available
@@ -63,6 +61,7 @@ export default class ControllerProvider extends BaseProvider {
63
61
  onConnect: (keychain) => {
64
62
  this.keychain = keychain;
65
63
  },
64
+ version: version,
66
65
  }),
67
66
  };
68
67
 
@@ -134,26 +133,6 @@ export default class ControllerProvider extends BaseProvider {
134
133
  return;
135
134
  }
136
135
 
137
- if (!this.iframes.profile) {
138
- const username = await this.keychain.username();
139
-
140
- this.iframes.profile = new ProfileIFrame({
141
- ...this.options,
142
- onConnect: (profile) => {
143
- this.profile = profile;
144
- },
145
- methods: {
146
- openSettings: () => this.openSettings.bind(this),
147
- openPurchaseCredits: () => this.openPurchaseCredits.bind(this),
148
- openExecute: () => this.openExecute.bind(this),
149
- logout: () => this.logout.bind(this),
150
- },
151
- rpcUrl: this.rpcUrl(),
152
- username,
153
- version: this.version,
154
- });
155
- }
156
-
157
136
  return this.account;
158
137
  }
159
138
 
@@ -189,7 +168,6 @@ export default class ControllerProvider extends BaseProvider {
189
168
  : this.options.policies || {},
190
169
  this.rpcUrl(),
191
170
  this.options.signupOptions,
192
- version,
193
171
  );
194
172
  if (response.code !== ResponseCodes.SUCCESS) {
195
173
  throw new Error(response.message);
@@ -228,7 +206,6 @@ export default class ControllerProvider extends BaseProvider {
228
206
  }
229
207
 
230
208
  await this.keychain.switchChain(this.rpcUrl());
231
- await this.profile?.switchChain(this.rpcUrl());
232
209
  } catch (e) {
233
210
  console.error(e);
234
211
  return false;
@@ -260,22 +237,27 @@ export default class ControllerProvider extends BaseProvider {
260
237
  }
261
238
 
262
239
  async openProfile(tab: ProfileContextTypeVariant = "inventory") {
263
- if (!this.profile || !this.iframes.profile?.url) {
264
- console.error("Profile is not ready");
240
+ // Profile functionality is now integrated into keychain
241
+ // Navigate keychain iframe to profile page
242
+ if (!this.keychain || !this.iframes.keychain) {
243
+ console.error(new NotReadyToConnect().message);
265
244
  return;
266
245
  }
267
246
  if (!this.account) {
268
247
  console.error("Account is not ready");
269
248
  return;
270
249
  }
250
+ const username = await this.keychain.username();
271
251
 
272
- this.profile.navigate(`${this.iframes.profile.url?.pathname}/${tab}`);
273
- this.iframes.profile.open();
252
+ // Navigate first, then open to avoid flash
253
+ await this.keychain.navigate(`/account/${username}/${tab}`);
254
+ this.iframes.keychain.open();
274
255
  }
275
256
 
276
257
  async openProfileTo(to: string) {
277
- if (!this.profile || !this.iframes.profile?.url) {
278
- console.error("Profile is not ready");
258
+ // Profile functionality is now integrated into keychain
259
+ if (!this.keychain || !this.iframes.keychain) {
260
+ console.error(new NotReadyToConnect().message);
279
261
  return;
280
262
  }
281
263
  if (!this.account) {
@@ -283,13 +265,15 @@ export default class ControllerProvider extends BaseProvider {
283
265
  return;
284
266
  }
285
267
 
286
- this.profile.navigate(`${this.iframes.profile.url?.pathname}/${to}`);
287
- this.iframes.profile.open();
268
+ const username = await this.keychain.username();
269
+ await this.keychain.navigate(`/account/${username}/${to}`);
270
+ this.iframes.keychain.open();
288
271
  }
289
272
 
290
273
  async openProfileAt(at: string) {
291
- if (!this.profile || !this.iframes.profile?.url) {
292
- console.error("Profile is not ready");
274
+ // Profile functionality is now integrated into keychain
275
+ if (!this.keychain || !this.iframes.keychain) {
276
+ console.error(new NotReadyToConnect().message);
293
277
  return;
294
278
  }
295
279
  if (!this.account) {
@@ -297,28 +281,17 @@ export default class ControllerProvider extends BaseProvider {
297
281
  return;
298
282
  }
299
283
 
300
- this.profile.navigate(at);
301
- this.iframes.profile.open();
284
+ await this.keychain.navigate(at);
285
+ this.iframes.keychain.open();
302
286
  }
303
287
 
304
- async openSettings() {
288
+ openSettings() {
305
289
  if (!this.keychain || !this.iframes.keychain) {
306
290
  console.error(new NotReadyToConnect().message);
307
- return null;
308
- }
309
- if (this.iframes.profile?.sendBackward) {
310
- this.iframes.profile?.sendBackward();
311
- } else {
312
- this.iframes.profile?.close();
291
+ return;
313
292
  }
314
293
  this.iframes.keychain.open();
315
- const res = await this.keychain.openSettings();
316
- this.iframes.keychain.close();
317
- this.iframes.profile?.sendForward?.();
318
- if (res && (res as ConnectError).code === ResponseCodes.NOT_CONNECTED) {
319
- return false;
320
- }
321
- return true;
294
+ this.keychain.openSettings();
322
295
  }
323
296
 
324
297
  revoke(origin: string, _policy: Policy[]) {
@@ -357,11 +330,6 @@ export default class ControllerProvider extends BaseProvider {
357
330
  console.error(new NotReadyToConnect().message);
358
331
  return;
359
332
  }
360
- if (!this.iframes.profile) {
361
- console.error("Profile is not ready");
362
- return;
363
- }
364
- this.iframes.profile.close();
365
333
  this.iframes.keychain.open();
366
334
  this.keychain.openPurchaseCredits();
367
335
  }
@@ -371,13 +339,11 @@ export default class ControllerProvider extends BaseProvider {
371
339
  console.error(new NotReadyToConnect().message);
372
340
  return;
373
341
  }
374
- if (!this.iframes.profile) {
375
- console.error("Profile is not ready");
376
- return;
377
- }
378
- this.iframes.profile.close();
379
- this.iframes.keychain.open();
380
- this.keychain.openStarterPack(starterpackId);
342
+
343
+ // Navigate first, then open the iframe
344
+ this.keychain.navigate(`/starter-pack/${starterpackId}`).then(() => {
345
+ this.iframes.keychain.open();
346
+ });
381
347
  }
382
348
 
383
349
  async openExecute(calls: any, chainId?: string) {
@@ -385,25 +351,17 @@ export default class ControllerProvider extends BaseProvider {
385
351
  console.error(new NotReadyToConnect().message);
386
352
  return;
387
353
  }
388
- if (!this.iframes.profile) {
389
- console.error("Profile is not ready");
390
- return;
391
- }
392
354
  // Switch to the chain if provided
393
355
  let currentChainId = this.selectedChain;
394
356
  if (chainId) {
395
357
  this.switchStarknetChain(chainId);
396
358
  }
397
- // Switch iframes
398
- this.iframes.profile?.sendBackward();
359
+ // Open keychain
399
360
  this.iframes.keychain.open();
400
- this.iframes.profile?.close();
401
361
  // Invoke execute
402
362
  const res = await this.keychain.execute(calls, undefined, undefined, true);
403
- // Switch back iframes
404
- this.iframes.profile?.open();
363
+ // Close keychain
405
364
  this.iframes.keychain.close();
406
- this.iframes.profile?.sendForward();
407
365
  // Switch back to the original chain
408
366
  if (chainId) {
409
367
  this.switchStarknetChain(currentChainId);
@@ -94,22 +94,6 @@ export class IFrame<CallSender extends {}> implements Modal {
94
94
  iframe: this.iframe,
95
95
  methods: {
96
96
  close: (_origin: string) => () => this.close(),
97
- closeAll: (_origin: string) => () => {
98
- // Close all iframes
99
- const iframes = document.querySelectorAll(
100
- 'iframe[id^="controller-"]',
101
- );
102
- iframes.forEach((iframe) => {
103
- const container = iframe.parentElement;
104
- if (container) {
105
- container.style.visibility = "hidden";
106
- container.style.opacity = "0";
107
- }
108
- });
109
- if (document.body) {
110
- document.body.style.overflow = "auto";
111
- }
112
- },
113
97
  reload: (_origin: string) => () => window.location.reload(),
114
98
  ...methods,
115
99
  },
@@ -125,10 +109,7 @@ export class IFrame<CallSender extends {}> implements Modal {
125
109
  if (typeof document === "undefined") return;
126
110
  const existingController = document.getElementById("controller");
127
111
  if (document.body) {
128
- if (
129
- (id === "controller-keychain" && !existingController) ||
130
- id === "controller-profile"
131
- ) {
112
+ if (id === "controller-keychain" && !existingController) {
132
113
  document.body.appendChild(container);
133
114
  observer.disconnect();
134
115
  }
@@ -142,10 +123,7 @@ export class IFrame<CallSender extends {}> implements Modal {
142
123
 
143
124
  const existingController = document.getElementById("controller");
144
125
  if (document.body) {
145
- if (
146
- (id === "controller-keychain" && !existingController) ||
147
- id === "controller-profile"
148
- ) {
126
+ if (id === "controller-keychain" && !existingController) {
149
127
  document.body.appendChild(container);
150
128
  }
151
129
  }
@@ -199,4 +177,8 @@ export class IFrame<CallSender extends {}> implements Modal {
199
177
  this.iframe.style.width = "432px";
200
178
  this.iframe.style.borderRadius = "8px";
201
179
  }
180
+
181
+ isOpen() {
182
+ return this.iframe?.style.display !== "none";
183
+ }
202
184
  }
@@ -1,3 +1,2 @@
1
1
  export * from "./base";
2
2
  export * from "./keychain";
3
- export * from "./profile";
@@ -3,12 +3,23 @@ import { Keychain, KeychainOptions } from "../types";
3
3
  import { WalletBridge } from "../wallets/bridge";
4
4
  import { IFrame, IFrameOptions } from "./base";
5
5
 
6
- type KeychainIframeOptions = IFrameOptions<Keychain> & KeychainOptions;
6
+ type KeychainIframeOptions = IFrameOptions<Keychain> &
7
+ KeychainOptions & {
8
+ version?: string;
9
+ };
7
10
 
8
11
  export class KeychainIFrame extends IFrame<Keychain> {
9
12
  private walletBridge: WalletBridge;
10
13
 
11
- constructor({ url, policies, ...iframeOptions }: KeychainIframeOptions) {
14
+ constructor({
15
+ url,
16
+ policies,
17
+ version,
18
+ slot,
19
+ namespace,
20
+ tokens,
21
+ ...iframeOptions
22
+ }: KeychainIframeOptions) {
12
23
  const _url = new URL(url ?? KEYCHAIN_URL);
13
24
  const walletBridge = new WalletBridge();
14
25
 
@@ -19,6 +30,25 @@ export class KeychainIFrame extends IFrame<Keychain> {
19
30
  );
20
31
  }
21
32
 
33
+ if (version) {
34
+ _url.searchParams.set("v", encodeURIComponent(version));
35
+ }
36
+
37
+ if (slot) {
38
+ _url.searchParams.set("ps", encodeURIComponent(slot));
39
+ }
40
+
41
+ if (namespace) {
42
+ _url.searchParams.set("ns", encodeURIComponent(namespace));
43
+ }
44
+
45
+ if (tokens?.erc20) {
46
+ _url.searchParams.set(
47
+ "erc20",
48
+ encodeURIComponent(tokens.erc20.toString()),
49
+ );
50
+ }
51
+
22
52
  super({
23
53
  ...iframeOptions,
24
54
  id: "controller-keychain",
@@ -37,7 +37,7 @@ export default class SessionAccount extends WalletAccount {
37
37
  sessionKeyGuid: string;
38
38
  },
39
39
  ) {
40
- super({ nodeUrl: rpcUrl }, provider);
40
+ super({ nodeUrl: rpcUrl }, provider, address);
41
41
 
42
42
  this.address = address;
43
43
  this.controller = CartridgeSessionAccount.newAsRegistered(
package/src/provider.ts CHANGED
@@ -1,18 +1,18 @@
1
- import { WalletAccount } from "starknet";
2
1
  import {
3
2
  AddInvokeTransactionParameters,
4
3
  AddStarknetChainParameters,
5
- Errors,
6
4
  Permission,
7
5
  RequestAccountsParameters,
8
6
  RequestFn,
9
7
  StarknetWindowObject,
10
8
  SwitchStarknetChainParameters,
11
9
  TypedData,
10
+ UNEXPECTED_ERROR,
12
11
  WalletEventHandlers,
13
12
  WalletEventListener,
14
13
  WalletEvents,
15
14
  } from "@starknet-io/types-js";
15
+ import { WalletAccount } from "starknet";
16
16
  import manifest from "../package.json";
17
17
 
18
18
  import { icon } from "./icon";
@@ -93,7 +93,7 @@ export default abstract class BaseProvider implements StarknetWindowObject {
93
93
  code: 63,
94
94
  message: "An unexpected error occurred",
95
95
  data: "wallet_watchAsset not implemented",
96
- } as Errors.UNEXPECTED_ERROR;
96
+ } as UNEXPECTED_ERROR;
97
97
 
98
98
  case "wallet_addStarknetChain": {
99
99
  let params = call.params as AddStarknetChainParameters;
@@ -111,7 +111,7 @@ export default abstract class BaseProvider implements StarknetWindowObject {
111
111
  code: 63,
112
112
  message: "An unexpected error occurred",
113
113
  data: "Account not initialized",
114
- } as Errors.UNEXPECTED_ERROR;
114
+ } as UNEXPECTED_ERROR;
115
115
  }
116
116
 
117
117
  return await this.account.getChainId();
@@ -121,7 +121,7 @@ export default abstract class BaseProvider implements StarknetWindowObject {
121
121
  code: 63,
122
122
  message: "An unexpected error occurred",
123
123
  data: "wallet_deploymentData not implemented",
124
- } as Errors.UNEXPECTED_ERROR;
124
+ } as UNEXPECTED_ERROR;
125
125
 
126
126
  case "wallet_addInvokeTransaction":
127
127
  if (!this.account) {
@@ -129,7 +129,7 @@ export default abstract class BaseProvider implements StarknetWindowObject {
129
129
  code: 63,
130
130
  message: "An unexpected error occurred",
131
131
  data: "Account not initialized",
132
- } as Errors.UNEXPECTED_ERROR;
132
+ } as UNEXPECTED_ERROR;
133
133
  }
134
134
 
135
135
  let params = call.params as AddInvokeTransactionParameters;
@@ -146,7 +146,7 @@ export default abstract class BaseProvider implements StarknetWindowObject {
146
146
  code: 63,
147
147
  message: "An unexpected error occurred",
148
148
  data: "wallet_addDeclareTransaction not implemented",
149
- } as Errors.UNEXPECTED_ERROR;
149
+ } as UNEXPECTED_ERROR;
150
150
 
151
151
  case "wallet_signTypedData": {
152
152
  if (!this.account) {
@@ -154,7 +154,7 @@ export default abstract class BaseProvider implements StarknetWindowObject {
154
154
  code: 63,
155
155
  message: "An unexpected error occurred",
156
156
  data: "Account not initialized",
157
- } as Errors.UNEXPECTED_ERROR;
157
+ } as UNEXPECTED_ERROR;
158
158
  }
159
159
 
160
160
  return await this.account.signMessage(call.params as TypedData);
@@ -169,7 +169,7 @@ export default abstract class BaseProvider implements StarknetWindowObject {
169
169
  code: 63,
170
170
  message: "An unexpected error occurred",
171
171
  data: `Unknown RPC call type: ${call.type}`,
172
- } as Errors.UNEXPECTED_ERROR;
172
+ } as UNEXPECTED_ERROR;
173
173
  }
174
174
  };
175
175
 
@@ -37,9 +37,8 @@ export default class SessionAccount extends WalletAccount {
37
37
  sessionKeyGuid: string;
38
38
  },
39
39
  ) {
40
- super({ nodeUrl: rpcUrl }, provider);
40
+ super({ nodeUrl: rpcUrl }, provider, address);
41
41
 
42
- this.address = address;
43
42
  this.controller = CartridgeSessionAccount.newAsRegistered(
44
43
  rpcUrl,
45
44
  privateKey,