@cartridge/connector 0.13.4 → 0.13.6

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @cartridge/connector@0.13.4 build:deps /home/runner/work/controller/controller/packages/connector
2
+ > @cartridge/connector@0.13.6 build:deps /home/runner/work/controller/controller/packages/connector
3
3
  > tsup --dts-resolve
4
4
 
5
5
  CLI Building entry: src/controller.ts, src/index.ts, src/session.ts
@@ -9,15 +9,15 @@
9
9
  CLI Target: esnext
10
10
  CLI Cleaning output folder
11
11
  ESM Build start
12
- ESM dist/controller.js 1.97 KB
13
- ESM dist/index.js 2.75 KB
14
- ESM dist/session.js 848.00 B
15
- ESM dist/controller.js.map 3.54 KB
16
- ESM dist/index.js.map 5.01 KB
17
- ESM dist/session.js.map 1.51 KB
18
- ESM ⚡️ Build success in 65ms
12
+ ESM dist/index.js 2.83 KB
13
+ ESM dist/session.js 916.00 B
14
+ ESM dist/controller.js 1.98 KB
15
+ ESM dist/index.js.map 5.84 KB
16
+ ESM dist/session.js.map 1.73 KB
17
+ ESM dist/controller.js.map 4.15 KB
18
+ ESM ⚡️ Build success in 44ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 6146ms
21
- DTS dist/index.d.ts 354.00 B
22
- DTS dist/controller.d.ts 1013.00 B
20
+ DTS ⚡️ Build success in 6912ms
21
+ DTS dist/index.d.ts 290.00 B
22
+ DTS dist/controller.d.ts 947.00 B
23
23
  DTS dist/session.d.ts 476.00 B
@@ -1,7 +1,6 @@
1
- import * as node_modules__starknet_react_core_dist_index_KYmfBIOq from 'node_modules/@starknet-react/core/dist/index-KYmfBIOq';
2
- import ControllerProvider, { ControllerOptions, AuthOptions } from '@cartridge/controller';
1
+ import * as _starknet_io_get_starknet_wallet_standard_features from '@starknet-io/get-starknet-wallet-standard/features';
2
+ import ControllerProvider, { ControllerOptions, ConnectOptions } from '@cartridge/controller';
3
3
  import { InjectedConnector, Connector } from '@starknet-react/core';
4
- import { WalletWithStarknetFeatures } from '@starknet-io/get-starknet-wallet-standard/features';
5
4
 
6
5
  declare class ControllerConnector extends InjectedConnector {
7
6
  controller: ControllerProvider;
@@ -12,10 +11,12 @@ declare class ControllerConnector extends InjectedConnector {
12
11
  delegateAccount(): Promise<string | null>;
13
12
  connect(args?: {
14
13
  chainIdHint?: bigint;
15
- signupOptions?: AuthOptions;
16
- }): Promise<node_modules__starknet_react_core_dist_index_KYmfBIOq.c>;
14
+ } & ConnectOptions): Promise<{
15
+ account: string;
16
+ chainId?: bigint;
17
+ }>;
17
18
  static fromConnectors(connectors: Connector[]): ControllerConnector;
18
- asWalletStandard(): WalletWithStarknetFeatures;
19
+ asWalletStandard(): _starknet_io_get_starknet_wallet_standard_features.WalletWithStarknetFeatures;
19
20
  }
20
21
 
21
22
  export { ControllerConnector as default };
@@ -1,7 +1,6 @@
1
1
  // src/controller.ts
2
2
  import ControllerProvider from "@cartridge/controller";
3
3
  import { InjectedConnector } from "@starknet-react/core";
4
- import { StarknetInjectedWallet } from "@starknet-io/get-starknet-wallet-standard";
5
4
  var ControllerConnector = class extends InjectedConnector {
6
5
  controller;
7
6
  constructor(options = {}) {
@@ -18,7 +17,11 @@ var ControllerConnector = class extends InjectedConnector {
18
17
  this.controller = controller;
19
18
  }
20
19
  async disconnect() {
21
- this.controller.disconnect();
20
+ await this.controller.disconnect();
21
+ try {
22
+ await super.disconnect();
23
+ } catch {
24
+ }
22
25
  }
23
26
  username() {
24
27
  return this.controller.username();
@@ -30,11 +33,17 @@ var ControllerConnector = class extends InjectedConnector {
30
33
  return await this.controller.delegateAccount();
31
34
  }
32
35
  async connect(args) {
33
- const account = await this.controller.connect(args?.signupOptions);
36
+ const { chainIdHint, ...connectOptions } = args ?? {};
37
+ const controllerArgs = args && Object.keys(connectOptions).length > 0 ? connectOptions : void 0;
38
+ const account = await this.controller.connect(controllerArgs);
34
39
  if (!account) {
35
40
  throw new Error("Failed to connect controller");
36
41
  }
37
- return super.connect({ chainIdHint: args?.chainIdHint });
42
+ if (typeof window !== "undefined") {
43
+ window.starknet_controller = this.controller;
44
+ }
45
+ const data = await super.connect({ chainIdHint });
46
+ return { ...data, account: account.address };
38
47
  }
39
48
  static fromConnectors(connectors) {
40
49
  const connector = connectors.find((c) => c.id === "controller");
@@ -44,12 +53,7 @@ var ControllerConnector = class extends InjectedConnector {
44
53
  return connector;
45
54
  }
46
55
  asWalletStandard() {
47
- if (typeof window !== "undefined") {
48
- console.warn(
49
- `Casting Controller to WalletWithStarknetFeatures is an experimental feature and may contain bugs. Please report any issues at https://github.com/cartridge-gg/controller/issues`
50
- );
51
- }
52
- return new StarknetInjectedWallet(this.controller);
56
+ return this.controller.asWalletStandard();
53
57
  }
54
58
  };
55
59
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/controller.ts"],"sourcesContent":["import ControllerProvider, {\n AuthOptions,\n ControllerOptions,\n} from \"@cartridge/controller\";\nimport { Connector, InjectedConnector } from \"@starknet-react/core\";\n\nimport { StarknetInjectedWallet } from \"@starknet-io/get-starknet-wallet-standard\";\nimport type { WalletWithStarknetFeatures } from \"@starknet-io/get-starknet-wallet-standard/features\";\n\nexport default class ControllerConnector extends InjectedConnector {\n public controller: ControllerProvider;\n\n constructor(options: ControllerOptions = {}) {\n let controller: ControllerProvider;\n\n if (typeof window !== \"undefined\" && (window as any).starknet_controller) {\n console.warn(\n \"ControllerConnector was instantiated multiple times. \" +\n \"Reusing existing controller to prevent errors. \" +\n \"To fix, create the connector at the module level instead of inside a React component.\",\n );\n controller = (window as any).starknet_controller;\n } else {\n controller = new ControllerProvider(options);\n }\n\n super({ options: { id: controller.id, name: controller.name } });\n this.controller = controller;\n }\n\n async disconnect() {\n this.controller.disconnect();\n }\n\n username() {\n return this.controller.username();\n }\n\n isReady(): boolean {\n return this.controller.isReady();\n }\n\n async delegateAccount() {\n return await this.controller.delegateAccount();\n }\n\n async connect(args?: { chainIdHint?: bigint; signupOptions?: AuthOptions }) {\n const account = await this.controller.connect(args?.signupOptions);\n if (!account) {\n throw new Error(\"Failed to connect controller\");\n }\n return super.connect({ chainIdHint: args?.chainIdHint });\n }\n\n static fromConnectors(connectors: Connector[]): ControllerConnector {\n const connector = connectors.find((c) => c.id === \"controller\");\n if (!connector) {\n throw new Error(\"Controller connector not found\");\n }\n return connector as ControllerConnector;\n }\n\n asWalletStandard(): WalletWithStarknetFeatures {\n if (typeof window !== \"undefined\") {\n console.warn(\n `Casting Controller to WalletWithStarknetFeatures is an experimental feature and may contain bugs. ` +\n `Please report any issues at https://github.com/cartridge-gg/controller/issues`,\n );\n }\n\n return new StarknetInjectedWallet(this.controller);\n }\n}\n"],"mappings":";AAAA,OAAO,wBAGA;AACP,SAAoB,yBAAyB;AAE7C,SAAS,8BAA8B;AAGvC,IAAqB,sBAArB,cAAiD,kBAAkB;AAAA,EAC1D;AAAA,EAEP,YAAY,UAA6B,CAAC,GAAG;AAC3C,QAAI;AAEJ,QAAI,OAAO,WAAW,eAAgB,OAAe,qBAAqB;AACxE,cAAQ;AAAA,QACN;AAAA,MAGF;AACA,mBAAc,OAAe;AAAA,IAC/B,OAAO;AACL,mBAAa,IAAI,mBAAmB,OAAO;AAAA,IAC7C;AAEA,UAAM,EAAE,SAAS,EAAE,IAAI,WAAW,IAAI,MAAM,WAAW,KAAK,EAAE,CAAC;AAC/D,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,aAAa;AACjB,SAAK,WAAW,WAAW;AAAA,EAC7B;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,WAAW,SAAS;AAAA,EAClC;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK,WAAW,QAAQ;AAAA,EACjC;AAAA,EAEA,MAAM,kBAAkB;AACtB,WAAO,MAAM,KAAK,WAAW,gBAAgB;AAAA,EAC/C;AAAA,EAEA,MAAM,QAAQ,MAA8D;AAC1E,UAAM,UAAU,MAAM,KAAK,WAAW,QAAQ,MAAM,aAAa;AACjE,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,WAAO,MAAM,QAAQ,EAAE,aAAa,MAAM,YAAY,CAAC;AAAA,EACzD;AAAA,EAEA,OAAO,eAAe,YAA8C;AAClE,UAAM,YAAY,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY;AAC9D,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,mBAA+C;AAC7C,QAAI,OAAO,WAAW,aAAa;AACjC,cAAQ;AAAA,QACN;AAAA,MAEF;AAAA,IACF;AAEA,WAAO,IAAI,uBAAuB,KAAK,UAAU;AAAA,EACnD;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/controller.ts"],"sourcesContent":["import ControllerProvider, {\n ConnectOptions,\n ControllerOptions,\n} from \"@cartridge/controller\";\nimport { Connector, InjectedConnector } from \"@starknet-react/core\";\n\nexport default class ControllerConnector extends InjectedConnector {\n public controller: ControllerProvider;\n\n constructor(options: ControllerOptions = {}) {\n let controller: ControllerProvider;\n\n if (typeof window !== \"undefined\" && (window as any).starknet_controller) {\n console.warn(\n \"ControllerConnector was instantiated multiple times. \" +\n \"Reusing existing controller to prevent errors. \" +\n \"To fix, create the connector at the module level instead of inside a React component.\",\n );\n controller = (window as any).starknet_controller;\n } else {\n controller = new ControllerProvider(options);\n }\n\n super({ options: { id: controller.id, name: controller.name } });\n this.controller = controller;\n }\n\n async disconnect() {\n await this.controller.disconnect();\n try {\n await super.disconnect();\n } catch {\n // Best-effort: starknet-react may call disconnect even when the injected wallet isn't present.\n }\n }\n\n username() {\n return this.controller.username();\n }\n\n isReady(): boolean {\n return this.controller.isReady();\n }\n\n async delegateAccount() {\n return await this.controller.delegateAccount();\n }\n\n async connect(args?: { chainIdHint?: bigint } & ConnectOptions) {\n const { chainIdHint, ...connectOptions } = args ?? {};\n const controllerArgs =\n args && Object.keys(connectOptions).length > 0\n ? (connectOptions as ConnectOptions)\n : undefined;\n\n const account = await this.controller.connect(controllerArgs);\n if (!account) {\n throw new Error(\"Failed to connect controller\");\n }\n\n // Ensure the injected wallet instance used by starknet-react (window.starknet_controller)\n // always points at the same ControllerProvider instance this connector wraps.\n if (typeof window !== \"undefined\") {\n (window as any).starknet_controller = this.controller;\n }\n\n const data = await super.connect({ chainIdHint });\n\n // `@starknet-react/core` updates its state from the `account` returned here.\n // Use the authoritative address from `controller.connect()` to avoid edge cases\n // where the injected wallet request returns an empty/undefined account.\n return { ...data, account: account.address };\n }\n\n static fromConnectors(connectors: Connector[]): ControllerConnector {\n const connector = connectors.find((c) => c.id === \"controller\");\n if (!connector) {\n throw new Error(\"Controller connector not found\");\n }\n return connector as ControllerConnector;\n }\n\n asWalletStandard() {\n return this.controller.asWalletStandard();\n }\n}\n"],"mappings":";AAAA,OAAO,wBAGA;AACP,SAAoB,yBAAyB;AAE7C,IAAqB,sBAArB,cAAiD,kBAAkB;AAAA,EAC1D;AAAA,EAEP,YAAY,UAA6B,CAAC,GAAG;AAC3C,QAAI;AAEJ,QAAI,OAAO,WAAW,eAAgB,OAAe,qBAAqB;AACxE,cAAQ;AAAA,QACN;AAAA,MAGF;AACA,mBAAc,OAAe;AAAA,IAC/B,OAAO;AACL,mBAAa,IAAI,mBAAmB,OAAO;AAAA,IAC7C;AAEA,UAAM,EAAE,SAAS,EAAE,IAAI,WAAW,IAAI,MAAM,WAAW,KAAK,EAAE,CAAC;AAC/D,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,aAAa;AACjB,UAAM,KAAK,WAAW,WAAW;AACjC,QAAI;AACF,YAAM,MAAM,WAAW;AAAA,IACzB,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,WAAW,SAAS;AAAA,EAClC;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK,WAAW,QAAQ;AAAA,EACjC;AAAA,EAEA,MAAM,kBAAkB;AACtB,WAAO,MAAM,KAAK,WAAW,gBAAgB;AAAA,EAC/C;AAAA,EAEA,MAAM,QAAQ,MAAkD;AAC9D,UAAM,EAAE,aAAa,GAAG,eAAe,IAAI,QAAQ,CAAC;AACpD,UAAM,iBACJ,QAAQ,OAAO,KAAK,cAAc,EAAE,SAAS,IACxC,iBACD;AAEN,UAAM,UAAU,MAAM,KAAK,WAAW,QAAQ,cAAc;AAC5D,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AAIA,QAAI,OAAO,WAAW,aAAa;AACjC,MAAC,OAAe,sBAAsB,KAAK;AAAA,IAC7C;AAEA,UAAM,OAAO,MAAM,MAAM,QAAQ,EAAE,YAAY,CAAC;AAKhD,WAAO,EAAE,GAAG,MAAM,SAAS,QAAQ,QAAQ;AAAA,EAC7C;AAAA,EAEA,OAAO,eAAe,YAA8C;AAClE,UAAM,YAAY,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY;AAC9D,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,mBAAmB;AACjB,WAAO,KAAK,WAAW,iBAAiB;AAAA,EAC1C;AACF;","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  export { default as ControllerConnector } from './controller.js';
2
2
  export { default as SessionConnector } from './session.js';
3
- import 'node_modules/@starknet-react/core/dist/index-KYmfBIOq';
3
+ import '@starknet-io/get-starknet-wallet-standard/features';
4
4
  import '@cartridge/controller';
5
5
  import '@starknet-react/core';
6
- import '@starknet-io/get-starknet-wallet-standard/features';
7
6
  import '@cartridge/controller/session';
package/dist/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  // src/controller.ts
2
2
  import ControllerProvider from "@cartridge/controller";
3
3
  import { InjectedConnector } from "@starknet-react/core";
4
- import { StarknetInjectedWallet } from "@starknet-io/get-starknet-wallet-standard";
5
4
  var ControllerConnector = class extends InjectedConnector {
6
5
  controller;
7
6
  constructor(options = {}) {
@@ -18,7 +17,11 @@ var ControllerConnector = class extends InjectedConnector {
18
17
  this.controller = controller;
19
18
  }
20
19
  async disconnect() {
21
- this.controller.disconnect();
20
+ await this.controller.disconnect();
21
+ try {
22
+ await super.disconnect();
23
+ } catch {
24
+ }
22
25
  }
23
26
  username() {
24
27
  return this.controller.username();
@@ -30,11 +33,17 @@ var ControllerConnector = class extends InjectedConnector {
30
33
  return await this.controller.delegateAccount();
31
34
  }
32
35
  async connect(args) {
33
- const account = await this.controller.connect(args?.signupOptions);
36
+ const { chainIdHint, ...connectOptions } = args ?? {};
37
+ const controllerArgs = args && Object.keys(connectOptions).length > 0 ? connectOptions : void 0;
38
+ const account = await this.controller.connect(controllerArgs);
34
39
  if (!account) {
35
40
  throw new Error("Failed to connect controller");
36
41
  }
37
- return super.connect({ chainIdHint: args?.chainIdHint });
42
+ if (typeof window !== "undefined") {
43
+ window.starknet_controller = this.controller;
44
+ }
45
+ const data = await super.connect({ chainIdHint });
46
+ return { ...data, account: account.address };
38
47
  }
39
48
  static fromConnectors(connectors) {
40
49
  const connector = connectors.find((c) => c.id === "controller");
@@ -44,12 +53,7 @@ var ControllerConnector = class extends InjectedConnector {
44
53
  return connector;
45
54
  }
46
55
  asWalletStandard() {
47
- if (typeof window !== "undefined") {
48
- console.warn(
49
- `Casting Controller to WalletWithStarknetFeatures is an experimental feature and may contain bugs. Please report any issues at https://github.com/cartridge-gg/controller/issues`
50
- );
51
- }
52
- return new StarknetInjectedWallet(this.controller);
56
+ return this.controller.asWalletStandard();
53
57
  }
54
58
  };
55
59
 
@@ -69,7 +73,11 @@ var SessionConnector = class extends InjectedConnector2 {
69
73
  this.controller = controller;
70
74
  }
71
75
  async disconnect() {
72
- this.controller.disconnect();
76
+ await this.controller.disconnect();
77
+ try {
78
+ await super.disconnect();
79
+ } catch {
80
+ }
73
81
  }
74
82
  static fromConnectors(connectors) {
75
83
  const connector = connectors.find((c) => c.id === "controller_session");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/controller.ts","../src/session.ts"],"sourcesContent":["import ControllerProvider, {\n AuthOptions,\n ControllerOptions,\n} from \"@cartridge/controller\";\nimport { Connector, InjectedConnector } from \"@starknet-react/core\";\n\nimport { StarknetInjectedWallet } from \"@starknet-io/get-starknet-wallet-standard\";\nimport type { WalletWithStarknetFeatures } from \"@starknet-io/get-starknet-wallet-standard/features\";\n\nexport default class ControllerConnector extends InjectedConnector {\n public controller: ControllerProvider;\n\n constructor(options: ControllerOptions = {}) {\n let controller: ControllerProvider;\n\n if (typeof window !== \"undefined\" && (window as any).starknet_controller) {\n console.warn(\n \"ControllerConnector was instantiated multiple times. \" +\n \"Reusing existing controller to prevent errors. \" +\n \"To fix, create the connector at the module level instead of inside a React component.\",\n );\n controller = (window as any).starknet_controller;\n } else {\n controller = new ControllerProvider(options);\n }\n\n super({ options: { id: controller.id, name: controller.name } });\n this.controller = controller;\n }\n\n async disconnect() {\n this.controller.disconnect();\n }\n\n username() {\n return this.controller.username();\n }\n\n isReady(): boolean {\n return this.controller.isReady();\n }\n\n async delegateAccount() {\n return await this.controller.delegateAccount();\n }\n\n async connect(args?: { chainIdHint?: bigint; signupOptions?: AuthOptions }) {\n const account = await this.controller.connect(args?.signupOptions);\n if (!account) {\n throw new Error(\"Failed to connect controller\");\n }\n return super.connect({ chainIdHint: args?.chainIdHint });\n }\n\n static fromConnectors(connectors: Connector[]): ControllerConnector {\n const connector = connectors.find((c) => c.id === \"controller\");\n if (!connector) {\n throw new Error(\"Controller connector not found\");\n }\n return connector as ControllerConnector;\n }\n\n asWalletStandard(): WalletWithStarknetFeatures {\n if (typeof window !== \"undefined\") {\n console.warn(\n `Casting Controller to WalletWithStarknetFeatures is an experimental feature and may contain bugs. ` +\n `Please report any issues at https://github.com/cartridge-gg/controller/issues`,\n );\n }\n\n return new StarknetInjectedWallet(this.controller);\n }\n}\n","import SessionProvider, { SessionOptions } from \"@cartridge/controller/session\";\nimport { Connector, InjectedConnector } from \"@starknet-react/core\";\n\nexport default class SessionConnector extends InjectedConnector {\n public controller: SessionProvider;\n\n constructor(options: SessionOptions) {\n const controller = new SessionProvider(options);\n\n super({\n options: {\n id: controller.id,\n name: controller.name,\n },\n });\n\n this.controller = controller;\n }\n\n async disconnect() {\n this.controller.disconnect();\n }\n\n static fromConnectors(connectors: Connector[]): SessionConnector {\n const connector = connectors.find((c) => c.id === \"controller_session\");\n if (!connector) {\n throw new Error(\"Session connector not found\");\n }\n return connector as SessionConnector;\n }\n\n username() {\n return this.controller.username();\n }\n}\n"],"mappings":";AAAA,OAAO,wBAGA;AACP,SAAoB,yBAAyB;AAE7C,SAAS,8BAA8B;AAGvC,IAAqB,sBAArB,cAAiD,kBAAkB;AAAA,EAC1D;AAAA,EAEP,YAAY,UAA6B,CAAC,GAAG;AAC3C,QAAI;AAEJ,QAAI,OAAO,WAAW,eAAgB,OAAe,qBAAqB;AACxE,cAAQ;AAAA,QACN;AAAA,MAGF;AACA,mBAAc,OAAe;AAAA,IAC/B,OAAO;AACL,mBAAa,IAAI,mBAAmB,OAAO;AAAA,IAC7C;AAEA,UAAM,EAAE,SAAS,EAAE,IAAI,WAAW,IAAI,MAAM,WAAW,KAAK,EAAE,CAAC;AAC/D,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,aAAa;AACjB,SAAK,WAAW,WAAW;AAAA,EAC7B;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,WAAW,SAAS;AAAA,EAClC;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK,WAAW,QAAQ;AAAA,EACjC;AAAA,EAEA,MAAM,kBAAkB;AACtB,WAAO,MAAM,KAAK,WAAW,gBAAgB;AAAA,EAC/C;AAAA,EAEA,MAAM,QAAQ,MAA8D;AAC1E,UAAM,UAAU,MAAM,KAAK,WAAW,QAAQ,MAAM,aAAa;AACjE,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,WAAO,MAAM,QAAQ,EAAE,aAAa,MAAM,YAAY,CAAC;AAAA,EACzD;AAAA,EAEA,OAAO,eAAe,YAA8C;AAClE,UAAM,YAAY,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY;AAC9D,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,mBAA+C;AAC7C,QAAI,OAAO,WAAW,aAAa;AACjC,cAAQ;AAAA,QACN;AAAA,MAEF;AAAA,IACF;AAEA,WAAO,IAAI,uBAAuB,KAAK,UAAU;AAAA,EACnD;AACF;;;ACxEA,OAAO,qBAAyC;AAChD,SAAoB,qBAAAA,0BAAyB;AAE7C,IAAqB,mBAArB,cAA8CA,mBAAkB;AAAA,EACvD;AAAA,EAEP,YAAY,SAAyB;AACnC,UAAM,aAAa,IAAI,gBAAgB,OAAO;AAE9C,UAAM;AAAA,MACJ,SAAS;AAAA,QACP,IAAI,WAAW;AAAA,QACf,MAAM,WAAW;AAAA,MACnB;AAAA,IACF,CAAC;AAED,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,aAAa;AACjB,SAAK,WAAW,WAAW;AAAA,EAC7B;AAAA,EAEA,OAAO,eAAe,YAA2C;AAC/D,UAAM,YAAY,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,oBAAoB;AACtE,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,WAAW,SAAS;AAAA,EAClC;AACF;","names":["InjectedConnector"]}
1
+ {"version":3,"sources":["../src/controller.ts","../src/session.ts"],"sourcesContent":["import ControllerProvider, {\n ConnectOptions,\n ControllerOptions,\n} from \"@cartridge/controller\";\nimport { Connector, InjectedConnector } from \"@starknet-react/core\";\n\nexport default class ControllerConnector extends InjectedConnector {\n public controller: ControllerProvider;\n\n constructor(options: ControllerOptions = {}) {\n let controller: ControllerProvider;\n\n if (typeof window !== \"undefined\" && (window as any).starknet_controller) {\n console.warn(\n \"ControllerConnector was instantiated multiple times. \" +\n \"Reusing existing controller to prevent errors. \" +\n \"To fix, create the connector at the module level instead of inside a React component.\",\n );\n controller = (window as any).starknet_controller;\n } else {\n controller = new ControllerProvider(options);\n }\n\n super({ options: { id: controller.id, name: controller.name } });\n this.controller = controller;\n }\n\n async disconnect() {\n await this.controller.disconnect();\n try {\n await super.disconnect();\n } catch {\n // Best-effort: starknet-react may call disconnect even when the injected wallet isn't present.\n }\n }\n\n username() {\n return this.controller.username();\n }\n\n isReady(): boolean {\n return this.controller.isReady();\n }\n\n async delegateAccount() {\n return await this.controller.delegateAccount();\n }\n\n async connect(args?: { chainIdHint?: bigint } & ConnectOptions) {\n const { chainIdHint, ...connectOptions } = args ?? {};\n const controllerArgs =\n args && Object.keys(connectOptions).length > 0\n ? (connectOptions as ConnectOptions)\n : undefined;\n\n const account = await this.controller.connect(controllerArgs);\n if (!account) {\n throw new Error(\"Failed to connect controller\");\n }\n\n // Ensure the injected wallet instance used by starknet-react (window.starknet_controller)\n // always points at the same ControllerProvider instance this connector wraps.\n if (typeof window !== \"undefined\") {\n (window as any).starknet_controller = this.controller;\n }\n\n const data = await super.connect({ chainIdHint });\n\n // `@starknet-react/core` updates its state from the `account` returned here.\n // Use the authoritative address from `controller.connect()` to avoid edge cases\n // where the injected wallet request returns an empty/undefined account.\n return { ...data, account: account.address };\n }\n\n static fromConnectors(connectors: Connector[]): ControllerConnector {\n const connector = connectors.find((c) => c.id === \"controller\");\n if (!connector) {\n throw new Error(\"Controller connector not found\");\n }\n return connector as ControllerConnector;\n }\n\n asWalletStandard() {\n return this.controller.asWalletStandard();\n }\n}\n","import SessionProvider, { SessionOptions } from \"@cartridge/controller/session\";\nimport { Connector, InjectedConnector } from \"@starknet-react/core\";\n\nexport default class SessionConnector extends InjectedConnector {\n public controller: SessionProvider;\n\n constructor(options: SessionOptions) {\n const controller = new SessionProvider(options);\n\n super({\n options: {\n id: controller.id,\n name: controller.name,\n },\n });\n\n this.controller = controller;\n }\n\n async disconnect() {\n await this.controller.disconnect();\n try {\n await super.disconnect();\n } catch {\n // Best-effort: disconnect should not throw if the injected wallet isn't available.\n }\n }\n\n static fromConnectors(connectors: Connector[]): SessionConnector {\n const connector = connectors.find((c) => c.id === \"controller_session\");\n if (!connector) {\n throw new Error(\"Session connector not found\");\n }\n return connector as SessionConnector;\n }\n\n username() {\n return this.controller.username();\n }\n}\n"],"mappings":";AAAA,OAAO,wBAGA;AACP,SAAoB,yBAAyB;AAE7C,IAAqB,sBAArB,cAAiD,kBAAkB;AAAA,EAC1D;AAAA,EAEP,YAAY,UAA6B,CAAC,GAAG;AAC3C,QAAI;AAEJ,QAAI,OAAO,WAAW,eAAgB,OAAe,qBAAqB;AACxE,cAAQ;AAAA,QACN;AAAA,MAGF;AACA,mBAAc,OAAe;AAAA,IAC/B,OAAO;AACL,mBAAa,IAAI,mBAAmB,OAAO;AAAA,IAC7C;AAEA,UAAM,EAAE,SAAS,EAAE,IAAI,WAAW,IAAI,MAAM,WAAW,KAAK,EAAE,CAAC;AAC/D,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,aAAa;AACjB,UAAM,KAAK,WAAW,WAAW;AACjC,QAAI;AACF,YAAM,MAAM,WAAW;AAAA,IACzB,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,WAAW,SAAS;AAAA,EAClC;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK,WAAW,QAAQ;AAAA,EACjC;AAAA,EAEA,MAAM,kBAAkB;AACtB,WAAO,MAAM,KAAK,WAAW,gBAAgB;AAAA,EAC/C;AAAA,EAEA,MAAM,QAAQ,MAAkD;AAC9D,UAAM,EAAE,aAAa,GAAG,eAAe,IAAI,QAAQ,CAAC;AACpD,UAAM,iBACJ,QAAQ,OAAO,KAAK,cAAc,EAAE,SAAS,IACxC,iBACD;AAEN,UAAM,UAAU,MAAM,KAAK,WAAW,QAAQ,cAAc;AAC5D,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AAIA,QAAI,OAAO,WAAW,aAAa;AACjC,MAAC,OAAe,sBAAsB,KAAK;AAAA,IAC7C;AAEA,UAAM,OAAO,MAAM,MAAM,QAAQ,EAAE,YAAY,CAAC;AAKhD,WAAO,EAAE,GAAG,MAAM,SAAS,QAAQ,QAAQ;AAAA,EAC7C;AAAA,EAEA,OAAO,eAAe,YAA8C;AAClE,UAAM,YAAY,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY;AAC9D,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,mBAAmB;AACjB,WAAO,KAAK,WAAW,iBAAiB;AAAA,EAC1C;AACF;;;ACrFA,OAAO,qBAAyC;AAChD,SAAoB,qBAAAA,0BAAyB;AAE7C,IAAqB,mBAArB,cAA8CA,mBAAkB;AAAA,EACvD;AAAA,EAEP,YAAY,SAAyB;AACnC,UAAM,aAAa,IAAI,gBAAgB,OAAO;AAE9C,UAAM;AAAA,MACJ,SAAS;AAAA,QACP,IAAI,WAAW;AAAA,QACf,MAAM,WAAW;AAAA,MACnB;AAAA,IACF,CAAC;AAED,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,aAAa;AACjB,UAAM,KAAK,WAAW,WAAW;AACjC,QAAI;AACF,YAAM,MAAM,WAAW;AAAA,IACzB,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,OAAO,eAAe,YAA2C;AAC/D,UAAM,YAAY,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,oBAAoB;AACtE,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,WAAW,SAAS;AAAA,EAClC;AACF;","names":["InjectedConnector"]}
package/dist/session.js CHANGED
@@ -14,7 +14,11 @@ var SessionConnector = class extends InjectedConnector {
14
14
  this.controller = controller;
15
15
  }
16
16
  async disconnect() {
17
- this.controller.disconnect();
17
+ await this.controller.disconnect();
18
+ try {
19
+ await super.disconnect();
20
+ } catch {
21
+ }
18
22
  }
19
23
  static fromConnectors(connectors) {
20
24
  const connector = connectors.find((c) => c.id === "controller_session");
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/session.ts"],"sourcesContent":["import SessionProvider, { SessionOptions } from \"@cartridge/controller/session\";\nimport { Connector, InjectedConnector } from \"@starknet-react/core\";\n\nexport default class SessionConnector extends InjectedConnector {\n public controller: SessionProvider;\n\n constructor(options: SessionOptions) {\n const controller = new SessionProvider(options);\n\n super({\n options: {\n id: controller.id,\n name: controller.name,\n },\n });\n\n this.controller = controller;\n }\n\n async disconnect() {\n this.controller.disconnect();\n }\n\n static fromConnectors(connectors: Connector[]): SessionConnector {\n const connector = connectors.find((c) => c.id === \"controller_session\");\n if (!connector) {\n throw new Error(\"Session connector not found\");\n }\n return connector as SessionConnector;\n }\n\n username() {\n return this.controller.username();\n }\n}\n"],"mappings":";AAAA,OAAO,qBAAyC;AAChD,SAAoB,yBAAyB;AAE7C,IAAqB,mBAArB,cAA8C,kBAAkB;AAAA,EACvD;AAAA,EAEP,YAAY,SAAyB;AACnC,UAAM,aAAa,IAAI,gBAAgB,OAAO;AAE9C,UAAM;AAAA,MACJ,SAAS;AAAA,QACP,IAAI,WAAW;AAAA,QACf,MAAM,WAAW;AAAA,MACnB;AAAA,IACF,CAAC;AAED,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,aAAa;AACjB,SAAK,WAAW,WAAW;AAAA,EAC7B;AAAA,EAEA,OAAO,eAAe,YAA2C;AAC/D,UAAM,YAAY,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,oBAAoB;AACtE,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,WAAW,SAAS;AAAA,EAClC;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/session.ts"],"sourcesContent":["import SessionProvider, { SessionOptions } from \"@cartridge/controller/session\";\nimport { Connector, InjectedConnector } from \"@starknet-react/core\";\n\nexport default class SessionConnector extends InjectedConnector {\n public controller: SessionProvider;\n\n constructor(options: SessionOptions) {\n const controller = new SessionProvider(options);\n\n super({\n options: {\n id: controller.id,\n name: controller.name,\n },\n });\n\n this.controller = controller;\n }\n\n async disconnect() {\n await this.controller.disconnect();\n try {\n await super.disconnect();\n } catch {\n // Best-effort: disconnect should not throw if the injected wallet isn't available.\n }\n }\n\n static fromConnectors(connectors: Connector[]): SessionConnector {\n const connector = connectors.find((c) => c.id === \"controller_session\");\n if (!connector) {\n throw new Error(\"Session connector not found\");\n }\n return connector as SessionConnector;\n }\n\n username() {\n return this.controller.username();\n }\n}\n"],"mappings":";AAAA,OAAO,qBAAyC;AAChD,SAAoB,yBAAyB;AAE7C,IAAqB,mBAArB,cAA8C,kBAAkB;AAAA,EACvD;AAAA,EAEP,YAAY,SAAyB;AACnC,UAAM,aAAa,IAAI,gBAAgB,OAAO;AAE9C,UAAM;AAAA,MACJ,SAAS;AAAA,QACP,IAAI,WAAW;AAAA,QACf,MAAM,WAAW;AAAA,MACnB;AAAA,IACF,CAAC;AAED,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,aAAa;AACjB,UAAM,KAAK,WAAW,WAAW;AACjC,QAAI;AACF,YAAM,MAAM,WAAW;AAAA,IACzB,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,OAAO,eAAe,YAA2C;AAC/D,UAAM,YAAY,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,oBAAoB;AACtE,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,WAAW,SAAS;AAAA,EAClC;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cartridge/connector",
3
- "version": "0.13.4",
3
+ "version": "0.13.6",
4
4
  "description": "Cartridge Controller Connector",
5
5
  "repository": {
6
6
  "type": "git",
@@ -44,17 +44,20 @@
44
44
  "@starknet-react/core": "^5.0.1"
45
45
  },
46
46
  "dependencies": {
47
- "@starknet-io/get-starknet-wallet-standard": "5.0.0-beta.0",
48
- "@cartridge/controller": "0.13.4"
47
+ "@cartridge/controller": "0.13.6"
49
48
  },
50
49
  "devDependencies": {
50
+ "@vitest/coverage-v8": "2.1.8",
51
51
  "prettier": "^3.4.2",
52
52
  "tsup": "^8.0.1",
53
53
  "typescript": "^5.7.3",
54
- "@cartridge/tsconfig": "0.13.4"
54
+ "vitest": "2.1.8",
55
+ "@cartridge/tsconfig": "0.13.6"
55
56
  },
56
57
  "scripts": {
57
58
  "build:deps": "tsup --dts-resolve",
59
+ "test": "vitest",
60
+ "test:ci": "vitest run",
58
61
  "format": "prettier --write \"src/**/*.ts\"",
59
62
  "format:check": "prettier --check \"src/**/*.ts\""
60
63
  }
@@ -0,0 +1,90 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
+
3
+ // Mock starknet-react's InjectedConnector so we can control what super.connect returns.
4
+ vi.mock("@starknet-react/core", () => {
5
+ type InjectedConnectorOptions = { id: string; name?: string };
6
+
7
+ class InjectedConnector {
8
+ private readonly _options: InjectedConnectorOptions;
9
+
10
+ constructor({ options }: { options: InjectedConnectorOptions }) {
11
+ this._options = options;
12
+ }
13
+
14
+ get id(): string {
15
+ return this._options.id;
16
+ }
17
+
18
+ get name(): string {
19
+ return this._options.name ?? this._options.id;
20
+ }
21
+
22
+ // Simulate an edge case where the injected request resolves but returns an
23
+ // empty/undefined account. Our connector should still return the address
24
+ // from controller.connect().
25
+ async connect(): Promise<{ account?: string; chainId?: bigint }> {
26
+ return { account: undefined, chainId: 1n };
27
+ }
28
+
29
+ async disconnect(): Promise<void> {}
30
+ }
31
+
32
+ // The real module exports both, but ControllerConnector only needs InjectedConnector.
33
+ class Connector {}
34
+
35
+ return { Connector, InjectedConnector };
36
+ });
37
+
38
+ // Mock controller SDK so ControllerConnector doesn't need a real iframe/keychain.
39
+ vi.mock("@cartridge/controller", () => {
40
+ class ControllerProvider {
41
+ id = "controller";
42
+ name = "Controller";
43
+ account?: { address: string };
44
+
45
+ constructor() {
46
+ if (typeof window !== "undefined") {
47
+ (window as any).starknet_controller = this;
48
+ }
49
+ }
50
+
51
+ async connect(): Promise<{ address: string } | undefined> {
52
+ this.account = { address: "0xabc" };
53
+ return this.account;
54
+ }
55
+
56
+ disconnect() {}
57
+ username() {}
58
+ isReady() {
59
+ return true;
60
+ }
61
+ delegateAccount() {}
62
+ asWalletStandard() {}
63
+ }
64
+
65
+ return {
66
+ __esModule: true,
67
+ default: ControllerProvider,
68
+ };
69
+ });
70
+
71
+ import ControllerConnector from "../controller";
72
+
73
+ describe("ControllerConnector", () => {
74
+ beforeEach(() => {
75
+ (globalThis as any).window = {};
76
+ });
77
+
78
+ afterEach(() => {
79
+ delete (globalThis as any).window;
80
+ });
81
+
82
+ it("returns the address from controller.connect() even if injected connect has no account", async () => {
83
+ const connector = new ControllerConnector();
84
+
85
+ const result = await connector.connect();
86
+
87
+ expect(result.account).toBe("0xabc");
88
+ expect((window as any).starknet_controller).toBe(connector.controller);
89
+ });
90
+ });
package/src/controller.ts CHANGED
@@ -1,12 +1,9 @@
1
1
  import ControllerProvider, {
2
- AuthOptions,
2
+ ConnectOptions,
3
3
  ControllerOptions,
4
4
  } from "@cartridge/controller";
5
5
  import { Connector, InjectedConnector } from "@starknet-react/core";
6
6
 
7
- import { StarknetInjectedWallet } from "@starknet-io/get-starknet-wallet-standard";
8
- import type { WalletWithStarknetFeatures } from "@starknet-io/get-starknet-wallet-standard/features";
9
-
10
7
  export default class ControllerConnector extends InjectedConnector {
11
8
  public controller: ControllerProvider;
12
9
 
@@ -29,7 +26,12 @@ export default class ControllerConnector extends InjectedConnector {
29
26
  }
30
27
 
31
28
  async disconnect() {
32
- this.controller.disconnect();
29
+ await this.controller.disconnect();
30
+ try {
31
+ await super.disconnect();
32
+ } catch {
33
+ // Best-effort: starknet-react may call disconnect even when the injected wallet isn't present.
34
+ }
33
35
  }
34
36
 
35
37
  username() {
@@ -44,12 +46,30 @@ export default class ControllerConnector extends InjectedConnector {
44
46
  return await this.controller.delegateAccount();
45
47
  }
46
48
 
47
- async connect(args?: { chainIdHint?: bigint; signupOptions?: AuthOptions }) {
48
- const account = await this.controller.connect(args?.signupOptions);
49
+ async connect(args?: { chainIdHint?: bigint } & ConnectOptions) {
50
+ const { chainIdHint, ...connectOptions } = args ?? {};
51
+ const controllerArgs =
52
+ args && Object.keys(connectOptions).length > 0
53
+ ? (connectOptions as ConnectOptions)
54
+ : undefined;
55
+
56
+ const account = await this.controller.connect(controllerArgs);
49
57
  if (!account) {
50
58
  throw new Error("Failed to connect controller");
51
59
  }
52
- return super.connect({ chainIdHint: args?.chainIdHint });
60
+
61
+ // Ensure the injected wallet instance used by starknet-react (window.starknet_controller)
62
+ // always points at the same ControllerProvider instance this connector wraps.
63
+ if (typeof window !== "undefined") {
64
+ (window as any).starknet_controller = this.controller;
65
+ }
66
+
67
+ const data = await super.connect({ chainIdHint });
68
+
69
+ // `@starknet-react/core` updates its state from the `account` returned here.
70
+ // Use the authoritative address from `controller.connect()` to avoid edge cases
71
+ // where the injected wallet request returns an empty/undefined account.
72
+ return { ...data, account: account.address };
53
73
  }
54
74
 
55
75
  static fromConnectors(connectors: Connector[]): ControllerConnector {
@@ -60,14 +80,7 @@ export default class ControllerConnector extends InjectedConnector {
60
80
  return connector as ControllerConnector;
61
81
  }
62
82
 
63
- asWalletStandard(): WalletWithStarknetFeatures {
64
- if (typeof window !== "undefined") {
65
- console.warn(
66
- `Casting Controller to WalletWithStarknetFeatures is an experimental feature and may contain bugs. ` +
67
- `Please report any issues at https://github.com/cartridge-gg/controller/issues`,
68
- );
69
- }
70
-
71
- return new StarknetInjectedWallet(this.controller);
83
+ asWalletStandard() {
84
+ return this.controller.asWalletStandard();
72
85
  }
73
86
  }
package/src/session.ts CHANGED
@@ -18,7 +18,12 @@ export default class SessionConnector extends InjectedConnector {
18
18
  }
19
19
 
20
20
  async disconnect() {
21
- this.controller.disconnect();
21
+ await this.controller.disconnect();
22
+ try {
23
+ await super.disconnect();
24
+ } catch {
25
+ // Best-effort: disconnect should not throw if the injected wallet isn't available.
26
+ }
22
27
  }
23
28
 
24
29
  static fromConnectors(connectors: Connector[]): SessionConnector {
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: "node",
6
+ include: ["src/**/*.test.ts"],
7
+ },
8
+ });
9
+