@cartridge/controller 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.
Files changed (40) hide show
  1. package/.turbo/turbo-build$colon$deps.log +41 -21
  2. package/.turbo/turbo-build.log +40 -20
  3. package/HEADLESS_MODE.md +113 -0
  4. package/dist/controller.d.ts +9 -2
  5. package/dist/errors.d.ts +10 -0
  6. package/dist/iframe/security.d.ts +10 -0
  7. package/dist/index-BdTFKueB.js +1072 -0
  8. package/dist/index-BdTFKueB.js.map +1 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.js +2273 -2524
  11. package/dist/index.js.map +1 -1
  12. package/dist/node/index.cjs +30 -5
  13. package/dist/node/index.cjs.map +1 -1
  14. package/dist/node/index.d.cts +11 -1
  15. package/dist/node/index.d.ts +11 -1
  16. package/dist/node/index.js +29 -7
  17. package/dist/node/index.js.map +1 -1
  18. package/dist/session/provider.d.ts +8 -2
  19. package/dist/session.js +141 -139
  20. package/dist/session.js.map +1 -1
  21. package/dist/stats.html +1 -1
  22. package/dist/types.d.ts +20 -1
  23. package/dist/utils.d.ts +5 -3
  24. package/package.json +4 -3
  25. package/src/__tests__/asWalletStandard.test.ts +87 -0
  26. package/src/__tests__/headlessConnectApproval.test.ts +97 -0
  27. package/src/__tests__/iframeSecurity.test.ts +84 -0
  28. package/src/__tests__/parseChainId.test.ts +1 -1
  29. package/src/__tests__/toWasmPolicies.test.ts +89 -40
  30. package/src/controller.ts +165 -13
  31. package/src/errors.ts +30 -0
  32. package/src/iframe/base.ts +14 -3
  33. package/src/iframe/keychain.ts +8 -5
  34. package/src/iframe/security.ts +48 -0
  35. package/src/index.ts +1 -0
  36. package/src/session/provider.ts +77 -48
  37. package/src/types.ts +30 -1
  38. package/src/utils.ts +21 -7
  39. package/dist/provider-DSqqvDee.js +0 -369
  40. package/dist/provider-DSqqvDee.js.map +0 -1
@@ -1,18 +1,38 @@
1
1
 
2
- > @cartridge/controller@0.13.4 build:deps /home/runner/work/controller/controller/packages/controller
2
+ > @cartridge/controller@0.13.6 build:deps /home/runner/work/controller/controller/packages/controller
3
3
  > pnpm build
4
4
 
5
5
 
6
- > @cartridge/controller@0.13.4 build /home/runner/work/controller/controller/packages/controller
6
+ > @cartridge/controller@0.13.6 build /home/runner/work/controller/controller/packages/controller
7
7
  > pnpm build:browser && pnpm build:node
8
8
 
9
9
 
10
- > @cartridge/controller@0.13.4 build:browser /home/runner/work/controller/controller/packages/controller
10
+ > @cartridge/controller@0.13.6 build:browser /home/runner/work/controller/controller/packages/controller
11
11
  > vite build
12
12
 
13
13
  vite v6.3.4 building for production...
14
14
  transforming...
15
- ✓ 246 modules transformed.
15
+ ../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/Address.js (6:21): A comment
16
+
17
+ "/*#__PURE__*/"
18
+
19
+ in "../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/Address.js" contains an annotation that Rollup cannot interpret due to the position of the comment. The comment will be removed to avoid issues.
20
+ ../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/Base64.js (6:27): A comment
21
+
22
+ "/*#__PURE__*/"
23
+
24
+ in "../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/Base64.js" contains an annotation that Rollup cannot interpret due to the position of the comment. The comment will be removed to avoid issues.
25
+ ../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/Json.js (1:21): A comment
26
+
27
+ "/*#__PURE__*/"
28
+
29
+ in "../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/Json.js" contains an annotation that Rollup cannot interpret due to the position of the comment. The comment will be removed to avoid issues.
30
+ ../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/internal/cursor.js (2:21): A comment
31
+
32
+ "/*#__PURE__*/"
33
+
34
+ in "../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/internal/cursor.js" contains an annotation that Rollup cannot interpret due to the position of the comment. The comment will be removed to avoid issues.
35
+ ✓ 389 modules transformed.
16
36
  rendering chunks...
17
37
  [plugin vite:reporter]
18
38
  (!) /home/runner/work/controller/controller/packages/controller/src/toast/index.ts is dynamically imported by /home/runner/work/controller/controller/packages/controller/src/account.ts but also statically imported by /home/runner/work/controller/controller/packages/controller/src/index.ts, dynamic import will not move module into another chunk.
@@ -20,14 +40,14 @@ rendering chunks...
20
40
 
21
41
  [vite:dts] Start generate declaration files...
22
42
  computing gzip size...
23
- dist/session.js  10.03 kB │ gzip: 3.01 kB │ map: 23.85 kB
24
- dist/provider-DSqqvDee.js  15.05 kB │ gzip: 6.17 kB │ map: 39.52 kB
25
- dist/index.js 196.19 kB │ gzip: 51.71 kB │ map: 547.91 kB
26
- [vite:dts] Declaration files built in 3525ms.
43
+ dist/session.js  10.53 kB │ gzip: 3.24 kB │ map: 25.46 kB
44
+ dist/index-BdTFKueB.js  38.34 kB │ gzip: 12.80 kB │ map: 81.00 kB
45
+ dist/index.js 186.49 kB │ gzip: 49.14 kB │ map: 569.43 kB
46
+ [vite:dts] Declaration files built in 3707ms.
27
47
 
28
- ✓ built in 5.12s
48
+ ✓ built in 5.77s
29
49
 
30
- > @cartridge/controller@0.13.4 build:node /home/runner/work/controller/controller/packages/controller
50
+ > @cartridge/controller@0.13.6 build:node /home/runner/work/controller/controller/packages/controller
31
51
  > tsup --config tsup.node.config.ts
32
52
 
33
53
  CLI Building entry: src/node/index.ts
@@ -38,16 +58,16 @@ computing gzip size...
38
58
  CLI Cleaning output folder
39
59
  ESM Build start
40
60
  CJS Build start
41
- "constants", "getChecksumAddress" and "shortString" are imported from external module "starknet" but never used in "dist/node/index.js".
42
- "constants", "getChecksumAddress" and "shortString" are imported from external module "starknet" but never used in "dist/node/index.cjs".
61
+ "constants" and "shortString" are imported from external module "starknet" but never used in "dist/node/index.js".
62
+ "constants" and "shortString" are imported from external module "starknet" but never used in "dist/node/index.cjs".
43
63
  Entry module "dist/node/index.cjs" is using named and default exports together. Consumers of your bundle will have to use `chunk.default` to access the default export, which may not be what you want. Use `output.exports: "named"` to disable this warning.
44
- ESM dist/node/index.js 22.43 KB
45
- ESM dist/node/index.js.map 54.20 KB
46
- ESM ⚡️ Build success in 324ms
47
- CJS dist/node/index.cjs 23.22 KB
48
- CJS dist/node/index.cjs.map 54.43 KB
49
- CJS ⚡️ Build success in 325ms
64
+ ESM dist/node/index.js 23.50 KB
65
+ ESM dist/node/index.js.map 56.57 KB
66
+ ESM ⚡️ Build success in 359ms
67
+ CJS dist/node/index.cjs 24.40 KB
68
+ CJS dist/node/index.cjs.map 56.82 KB
69
+ CJS ⚡️ Build success in 357ms
50
70
  DTS Build start
51
- DTS ⚡️ Build success in 2937ms
52
- DTS dist/node/index.d.ts 5.98 KB
53
- DTS dist/node/index.d.cts 5.98 KB
71
+ DTS ⚡️ Build success in 3125ms
72
+ DTS dist/node/index.d.ts 6.42 KB
73
+ DTS dist/node/index.d.cts 6.42 KB
@@ -1,14 +1,34 @@
1
1
 
2
- > @cartridge/controller@0.13.4 build /home/runner/work/controller/controller/packages/controller
2
+ > @cartridge/controller@0.13.6 build /home/runner/work/controller/controller/packages/controller
3
3
  > pnpm build:browser && pnpm build:node
4
4
 
5
5
 
6
- > @cartridge/controller@0.13.4 build:browser /home/runner/work/controller/controller/packages/controller
6
+ > @cartridge/controller@0.13.6 build:browser /home/runner/work/controller/controller/packages/controller
7
7
  > vite build
8
8
 
9
9
  vite v6.3.4 building for production...
10
10
  transforming...
11
- ✓ 246 modules transformed.
11
+ ../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/Address.js (6:21): A comment
12
+
13
+ "/*#__PURE__*/"
14
+
15
+ in "../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/Address.js" contains an annotation that Rollup cannot interpret due to the position of the comment. The comment will be removed to avoid issues.
16
+ ../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/Base64.js (6:27): A comment
17
+
18
+ "/*#__PURE__*/"
19
+
20
+ in "../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/Base64.js" contains an annotation that Rollup cannot interpret due to the position of the comment. The comment will be removed to avoid issues.
21
+ ../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/Json.js (1:21): A comment
22
+
23
+ "/*#__PURE__*/"
24
+
25
+ in "../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/Json.js" contains an annotation that Rollup cannot interpret due to the position of the comment. The comment will be removed to avoid issues.
26
+ ../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/internal/cursor.js (2:21): A comment
27
+
28
+ "/*#__PURE__*/"
29
+
30
+ in "../../node_modules/.pnpm/ox@0.4.4_typescript@5.8.3_zod@3.24.4/node_modules/ox/_esm/core/internal/cursor.js" contains an annotation that Rollup cannot interpret due to the position of the comment. The comment will be removed to avoid issues.
31
+ ✓ 389 modules transformed.
12
32
  rendering chunks...
13
33
  [plugin vite:reporter]
14
34
  (!) /home/runner/work/controller/controller/packages/controller/src/toast/index.ts is dynamically imported by /home/runner/work/controller/controller/packages/controller/src/account.ts but also statically imported by /home/runner/work/controller/controller/packages/controller/src/index.ts, dynamic import will not move module into another chunk.
@@ -16,14 +36,14 @@ rendering chunks...
16
36
 
17
37
  [vite:dts] Start generate declaration files...
18
38
  computing gzip size...
19
- dist/session.js  10.03 kB │ gzip: 3.01 kB │ map: 23.85 kB
20
- dist/provider-DSqqvDee.js  15.05 kB │ gzip: 6.17 kB │ map: 39.52 kB
21
- dist/index.js 196.19 kB │ gzip: 51.71 kB │ map: 547.91 kB
22
- [vite:dts] Declaration files built in 3639ms.
39
+ dist/session.js  10.53 kB │ gzip: 3.24 kB │ map: 25.46 kB
40
+ dist/index-BdTFKueB.js  38.34 kB │ gzip: 12.80 kB │ map: 81.00 kB
41
+ dist/index.js 186.49 kB │ gzip: 49.14 kB │ map: 569.43 kB
42
+ [vite:dts] Declaration files built in 3504ms.
23
43
 
24
- ✓ built in 5.20s
44
+ ✓ built in 5.59s
25
45
 
26
- > @cartridge/controller@0.13.4 build:node /home/runner/work/controller/controller/packages/controller
46
+ > @cartridge/controller@0.13.6 build:node /home/runner/work/controller/controller/packages/controller
27
47
  > tsup --config tsup.node.config.ts
28
48
 
29
49
  CLI Building entry: src/node/index.ts
@@ -34,16 +54,16 @@ computing gzip size...
34
54
  CLI Cleaning output folder
35
55
  ESM Build start
36
56
  CJS Build start
37
- "constants", "getChecksumAddress" and "shortString" are imported from external module "starknet" but never used in "dist/node/index.cjs".
57
+ "constants" and "shortString" are imported from external module "starknet" but never used in "dist/node/index.js".
58
+ "constants" and "shortString" are imported from external module "starknet" but never used in "dist/node/index.cjs".
38
59
  Entry module "dist/node/index.cjs" is using named and default exports together. Consumers of your bundle will have to use `chunk.default` to access the default export, which may not be what you want. Use `output.exports: "named"` to disable this warning.
39
- "constants", "getChecksumAddress" and "shortString" are imported from external module "starknet" but never used in "dist/node/index.js".
40
- CJS dist/node/index.cjs 23.22 KB
41
- CJS dist/node/index.cjs.map 54.43 KB
42
- CJS ⚡️ Build success in 249ms
43
- ESM dist/node/index.js 22.43 KB
44
- ESM dist/node/index.js.map 54.20 KB
45
- ESM ⚡️ Build success in 250ms
60
+ ESM dist/node/index.js 23.50 KB
61
+ ESM dist/node/index.js.map 56.57 KB
62
+ ESM ⚡️ Build success in 323ms
63
+ CJS dist/node/index.cjs 24.40 KB
64
+ CJS dist/node/index.cjs.map 56.82 KB
65
+ CJS ⚡️ Build success in 324ms
46
66
  DTS Build start
47
- DTS ⚡️ Build success in 3079ms
48
- DTS dist/node/index.d.ts 5.98 KB
49
- DTS dist/node/index.d.cts 5.98 KB
67
+ DTS ⚡️ Build success in 3326ms
68
+ DTS dist/node/index.d.ts 6.42 KB
69
+ DTS dist/node/index.d.cts 6.42 KB
@@ -0,0 +1,113 @@
1
+ # Headless Mode Guide
2
+
3
+ ## Overview
4
+
5
+ Headless mode enables programmatic authentication with the Cartridge Controller SDK without displaying any UI. You trigger headless mode by passing a `username` and `signer` to `connect(...)`.
6
+
7
+ ```
8
+ Controller SDK → Keychain iframe (hidden) → Backend API
9
+ ```
10
+
11
+ **Key Points**
12
+ - The keychain iframe still exists, but the modal is not opened.
13
+ - The SDK passes the connect request to keychain over Penpal.
14
+ - Keychain executes the same authentication logic as the UI flow.
15
+ - No duplicated auth logic in the SDK.
16
+
17
+ ## Usage
18
+
19
+ ### Basic (Passkey / WebAuthn)
20
+
21
+ ```ts
22
+ import Controller from "@cartridge/controller";
23
+
24
+ const controller = new Controller({
25
+ defaultChainId: "SN_SEPOLIA",
26
+ });
27
+
28
+ await controller.connect({
29
+ username: "alice",
30
+ signer: "webauthn",
31
+ });
32
+ ```
33
+
34
+ ### Password
35
+
36
+ ```ts
37
+ await controller.connect({
38
+ username: "alice",
39
+ signer: "password",
40
+ password: "correct horse battery staple",
41
+ });
42
+ ```
43
+
44
+ ### OAuth / EVM / WalletConnect
45
+
46
+ ```ts
47
+ // Google / Discord
48
+ await controller.connect({ username: "alice", signer: "google" });
49
+ await controller.connect({ username: "alice", signer: "discord" });
50
+
51
+ // EVM wallets
52
+ await controller.connect({ username: "alice", signer: "metamask" });
53
+ await controller.connect({ username: "alice", signer: "rabby" });
54
+ await controller.connect({ username: "alice", signer: "phantom-evm" });
55
+
56
+ // WalletConnect
57
+ await controller.connect({ username: "alice", signer: "walletconnect" });
58
+ ```
59
+
60
+ ## Supported Auth Options
61
+
62
+ Headless mode supports all **implemented** auth options:
63
+ - `webauthn`
64
+ - `password`
65
+ - `google`
66
+ - `discord`
67
+ - `walletconnect`
68
+ - `metamask`
69
+ - `rabby`
70
+ - `phantom-evm`
71
+
72
+ ## Handling Session Approval
73
+
74
+ If policies are unverified or include approvals, Keychain will prompt for
75
+ session approval **after** authentication. In that case, `connect` will open
76
+ the approval UI and resolve once the session is approved.
77
+
78
+ ```ts
79
+ const account = await controller.connect({
80
+ username: "alice",
81
+ signer: "webauthn",
82
+ });
83
+
84
+ console.log("Session approved:", account.address);
85
+ ```
86
+ If you want to react to connection state changes, subscribe to the standard
87
+ wallet events (for example `accountsChanged`) or just await `connect(...)` and
88
+ update your app state afterwards.
89
+
90
+ ## Error Handling
91
+
92
+ The SDK provides specific error classes for headless mode:
93
+
94
+ ```ts
95
+ import {
96
+ HeadlessAuthenticationError,
97
+ } from "@cartridge/controller";
98
+
99
+ try {
100
+ await controller.connect({ username: "alice", signer: "webauthn" });
101
+ } catch (error) {
102
+ if (error instanceof HeadlessAuthenticationError) {
103
+ // Auth failed (invalid credentials, signer mismatch, etc.)
104
+ }
105
+ }
106
+ ```
107
+
108
+ ## Notes
109
+
110
+ - Headless mode uses the **existing signers** on the controller for the given username.
111
+ - For passkeys, the account must already have a WebAuthn signer registered.
112
+ - If policies are unverified or include approvals, Keychain will request
113
+ explicit approval after authentication.
@@ -1,8 +1,9 @@
1
1
  import { Policy } from '@cartridge/presets';
2
+ import { WalletWithStarknetFeatures } from '@starknet-io/get-starknet-wallet-standard/features';
2
3
  import { AddStarknetChainParameters } from '@starknet-io/types-js';
3
4
  import { WalletAccount } from 'starknet';
4
5
  import { default as BaseProvider } from './provider';
5
- import { AuthOptions, ControllerOptions, ProfileContextTypeVariant, OpenOptions, StarterpackOptions } from './types';
6
+ import { AuthOptions, ConnectOptions, ControllerOptions, ProfileContextTypeVariant, OpenOptions, StarterpackOptions } from './types';
6
7
  export default class ControllerProvider extends BaseProvider {
7
8
  private keychain?;
8
9
  private options;
@@ -15,7 +16,7 @@ export default class ControllerProvider extends BaseProvider {
15
16
  constructor(options?: ControllerOptions);
16
17
  logout(): Promise<void>;
17
18
  probe(): Promise<WalletAccount | undefined>;
18
- connect(signupOptions?: AuthOptions): Promise<WalletAccount | undefined>;
19
+ connect(options?: AuthOptions | ConnectOptions): Promise<WalletAccount | undefined>;
19
20
  switchStarknetChain(chainId: string): Promise<boolean>;
20
21
  addStarknetChain(_chain: AddStarknetChainParameters): Promise<boolean>;
21
22
  disconnect(): Promise<void>;
@@ -23,6 +24,7 @@ export default class ControllerProvider extends BaseProvider {
23
24
  openProfileTo(to: string): Promise<void>;
24
25
  openProfileAt(at: string): Promise<void>;
25
26
  openSettings(): void;
27
+ close(): Promise<void>;
26
28
  revoke(origin: string, _policy: Policy[]): Promise<void> | null;
27
29
  rpcUrl(): string;
28
30
  username(): Promise<string> | undefined;
@@ -33,6 +35,11 @@ export default class ControllerProvider extends BaseProvider {
33
35
  transactionHash: string;
34
36
  } | undefined>;
35
37
  delegateAccount(): Promise<string | null>;
38
+ /**
39
+ * Returns a wallet standard interface for the controller.
40
+ * This allows using the controller with libraries that expect the wallet standard interface.
41
+ */
42
+ asWalletStandard(): WalletWithStarknetFeatures;
36
43
  /**
37
44
  * Opens the keychain in standalone mode (first-party context) for authentication.
38
45
  * This establishes first-party storage, enabling seamless iframe access across all games.
package/dist/errors.d.ts CHANGED
@@ -1,3 +1,13 @@
1
1
  export declare class NotReadyToConnect extends Error {
2
2
  constructor();
3
3
  }
4
+ export declare class HeadlessAuthenticationError extends Error {
5
+ cause?: Error | undefined;
6
+ constructor(message: string, cause?: Error | undefined);
7
+ }
8
+ export declare class InvalidCredentialsError extends HeadlessAuthenticationError {
9
+ constructor(credentialType: string);
10
+ }
11
+ export declare class HeadlessModeNotSupportedError extends Error {
12
+ constructor(operation: string);
13
+ }
@@ -0,0 +1,10 @@
1
+ export declare function isLocalhostHostname(hostname: string): boolean;
2
+ /**
3
+ * Restrict iframe targets to HTTPS in production, while still allowing local HTTP dev.
4
+ */
5
+ export declare function validateKeychainIframeUrl(url: URL): void;
6
+ /**
7
+ * Build a conservative allow list for iframe feature policy.
8
+ * Local network access is only needed for localhost development.
9
+ */
10
+ export declare function buildIframeAllowList(url: URL): string;