@cartridge/controller 0.13.7 → 0.13.9

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/session.js CHANGED
@@ -1,31 +1,31 @@
1
- import { WalletAccount as y, stark as u, ec as p, encode as l } from "starknet";
2
- import { signerToGuid as h, subscribeCreateSession as f } from "@cartridge/controller-wasm";
1
+ import { WalletAccount as f, encode as l, stark as p, ec as m } from "starknet";
2
+ import { signerToGuid as h, subscribeCreateSession as w } from "@cartridge/controller-wasm";
3
3
  export * from "@cartridge/controller-wasm";
4
- import { n as m, B as w, f as g, K as v, A as I, w as K, g as U, e as x } from "./index-CYAUAqql.js";
5
- import { c as H, E as J, F as $, H as z, b as F, I as L, a as T, N as B, R as D } from "./index-CYAUAqql.js";
6
- import { CartridgeSessionAccount as O } from "@cartridge/controller-wasm/session";
7
- class N extends y {
4
+ import { n as S, B as v, f as _, K as I, A as K, w as U, g as x, x as u, e as P } from "./index-CJNujYxo.js";
5
+ import { c as J, E as $, F as z, H as T, b as L, I as B, a as D, N as F, R as M } from "./index-CJNujYxo.js";
6
+ import { CartridgeSessionAccount as A } from "@cartridge/controller-wasm/session";
7
+ class N extends f {
8
8
  controller;
9
9
  constructor(e, {
10
- rpcUrl: t,
11
- privateKey: s,
12
- address: i,
10
+ rpcUrl: s,
11
+ privateKey: i,
12
+ address: t,
13
13
  ownerGuid: r,
14
14
  chainId: a,
15
15
  expiresAt: o,
16
16
  policies: n,
17
17
  guardianKeyGuid: c,
18
18
  metadataHash: d,
19
- sessionKeyGuid: _
19
+ sessionKeyGuid: y
20
20
  }) {
21
21
  super({
22
- provider: { nodeUrl: t },
22
+ provider: { nodeUrl: s },
23
23
  walletProvider: e,
24
- address: i
25
- }), this.controller = O.newAsRegistered(
26
- t,
24
+ address: t
25
+ }), this.controller = A.newAsRegistered(
27
26
  s,
28
27
  i,
28
+ t,
29
29
  r,
30
30
  a,
31
31
  {
@@ -33,7 +33,7 @@ class N extends y {
33
33
  policies: n,
34
34
  guardianKeyGuid: c ?? "0x0",
35
35
  metadataHash: d ?? "0x0",
36
- sessionKeyGuid: _
36
+ sessionKeyGuid: y
37
37
  }
38
38
  );
39
39
  }
@@ -52,14 +52,14 @@ class N extends y {
52
52
  async execute(e) {
53
53
  try {
54
54
  return await this.controller.executeFromOutside(
55
- m(e)
55
+ S(e)
56
56
  );
57
57
  } catch {
58
- return this.controller.execute(m(e));
58
+ return this.controller.execute(S(e));
59
59
  }
60
60
  }
61
61
  }
62
- class k extends w {
62
+ class b extends v {
63
63
  id = "controller_session";
64
64
  name = "Controller Session";
65
65
  _chainId;
@@ -69,18 +69,18 @@ class k extends w {
69
69
  _disconnectRedirectUrl;
70
70
  _policies;
71
71
  _preset;
72
- _ready;
73
72
  _keychainUrl;
74
73
  _apiUrl;
75
74
  _publicKey;
76
75
  _sessionKeyGuid;
77
76
  _signupOptions;
77
+ _readyPromise;
78
78
  reopenBrowser = !0;
79
79
  constructor({
80
80
  rpc: e,
81
- chainId: t,
82
- policies: s,
83
- preset: i,
81
+ chainId: s,
82
+ policies: i,
83
+ preset: t,
84
84
  shouldOverridePresetPolicies: r,
85
85
  redirectUrl: a,
86
86
  disconnectRedirectUrl: o,
@@ -88,51 +88,53 @@ class k extends w {
88
88
  apiUrl: c,
89
89
  signupOptions: d
90
90
  }) {
91
- if (super(), !s && !i)
91
+ if (super(), !i && !t)
92
92
  throw new Error("Either `policies` or `preset` must be provided");
93
- (!i || r) && s ? this._policies = g(s) : (this._preset = i, s && console.warn(
93
+ (!t || r) && i ? this._policies = _(i) : (this._preset = t, i && console.warn(
94
94
  "[Controller] Both `preset` and `policies` provided to SessionProvider. Policies are ignored when preset is set. Use `shouldOverridePresetPolicies: true` to override."
95
- ), this._policies = { verified: !1 }), this._rpcUrl = e, this._chainId = t, this._redirectUrl = a, this._disconnectRedirectUrl = o, this._keychainUrl = n || v, this._apiUrl = c ?? I, this._signupOptions = d, this._ready = this._init(), typeof window < "u" && (window.starknet_controller_session = this);
95
+ ), this._policies = { verified: !1 }), this._rpcUrl = e, this._chainId = s, this._redirectUrl = a, this._disconnectRedirectUrl = o, this._keychainUrl = n || I, this._apiUrl = c ?? K, this._signupOptions = d, this._setSigningKeys(), this._readyPromise = this._resolvePreset(), typeof window < "u" && (window.starknet_controller_session = this);
96
96
  }
97
- async _init() {
98
- if (this._preset) {
99
- const t = await K(this._preset);
100
- if (!t)
101
- throw new Error(`Failed to load preset: ${this._preset}`);
102
- const s = U(t, this._chainId);
103
- if (!s)
104
- throw new Error(
105
- `No policies found for chain ${this._chainId} in preset ${this._preset}`
106
- );
107
- this._policies = g(s);
108
- }
109
- if (this.tryRetrieveFromQueryOrStorage()) {
110
- const t = localStorage.getItem("sessionSigner");
111
- if (!t) throw new Error("failed to get sessionSigner");
112
- const s = JSON.parse(t);
97
+ _setSigningKeys() {
98
+ const e = localStorage.getItem("sessionSigner");
99
+ if (e) {
100
+ const s = JSON.parse(e);
113
101
  this._publicKey = s.pubKey, this._sessionKeyGuid = h({
114
102
  starknet: { privateKey: l.addHexPrefix(s.privKey) }
115
103
  });
116
104
  } else {
117
- const t = u.randomAddress();
118
- this._publicKey = p.starkCurve.getStarkKey(t), localStorage.setItem(
105
+ const s = p.randomAddress();
106
+ this._publicKey = m.starkCurve.getStarkKey(s), localStorage.setItem(
119
107
  "sessionSigner",
120
108
  JSON.stringify({
121
- privKey: t,
109
+ privKey: s,
122
110
  pubKey: this._publicKey
123
111
  })
124
112
  ), this._sessionKeyGuid = h({
125
- starknet: { privateKey: l.addHexPrefix(t) }
113
+ starknet: { privateKey: l.addHexPrefix(s) }
126
114
  });
127
115
  }
128
116
  }
129
- validatePoliciesSubset(e, t) {
117
+ // Resolve preset policies asynchronously.
118
+ // Public methods await this before proceeding.
119
+ async _resolvePreset() {
120
+ if (!this._preset) return;
121
+ const e = await U(this._preset);
122
+ if (!e)
123
+ throw new Error(`Failed to load preset: ${this._preset}`);
124
+ const s = x(e, this._chainId);
125
+ if (!s)
126
+ throw new Error(
127
+ `No policies found for chain ${this._chainId} in preset ${this._preset}`
128
+ );
129
+ this._policies = _(s);
130
+ }
131
+ validatePoliciesSubset(e, s) {
130
132
  if (e.contracts) {
131
- if (!t.contracts) return !1;
132
- for (const [s, i] of Object.entries(e.contracts)) {
133
- const r = t.contracts[s];
133
+ if (!s.contracts) return !1;
134
+ for (const [i, t] of Object.entries(e.contracts)) {
135
+ const r = s.contracts[i];
134
136
  if (!r) return !1;
135
- for (const a of i.methods) {
137
+ for (const a of t.methods) {
136
138
  const o = r.methods.find(
137
139
  (n) => n.entrypoint === a.entrypoint
138
140
  );
@@ -141,19 +143,19 @@ class k extends w {
141
143
  }
142
144
  }
143
145
  if (e.messages) {
144
- if (!t.messages) return !1;
145
- for (const s of e.messages) {
146
- const i = t.messages.find(
147
- (r) => JSON.stringify(r.domain) === JSON.stringify(s.domain) && JSON.stringify(r.types) === JSON.stringify(s.types)
146
+ if (!s.messages) return !1;
147
+ for (const i of e.messages) {
148
+ const t = s.messages.find(
149
+ (r) => JSON.stringify(r.domain) === JSON.stringify(i.domain) && JSON.stringify(r.types) === JSON.stringify(i.types)
148
150
  );
149
- if (!i || !i.authorized) return !1;
151
+ if (!t || !t.authorized) return !1;
150
152
  }
151
153
  }
152
154
  return !0;
153
155
  }
154
156
  padBase64(e) {
155
- const t = e.length % 4;
156
- return t === 0 ? e : e + "=".repeat(4 - t);
157
+ const s = e.length % 4;
158
+ return s === 0 ? e : e + "=".repeat(4 - s);
157
159
  }
158
160
  normalizeSession(e) {
159
161
  if (!(e.username === void 0 || e.address === void 0 || e.ownerGuid === void 0 || e.expiresAt === void 0))
@@ -170,51 +172,51 @@ class k extends w {
170
172
  }
171
173
  ingestSessionFromRedirect(e) {
172
174
  try {
173
- const t = atob(this.padBase64(e)), s = JSON.parse(t), i = this.normalizeSession(s);
174
- return i ? (localStorage.setItem("session", JSON.stringify(i)), i) : void 0;
175
- } catch (t) {
176
- console.error("Failed to ingest session redirect", t);
175
+ const s = atob(this.padBase64(e)), i = JSON.parse(s), t = this.normalizeSession(i);
176
+ return t ? (localStorage.setItem("session", JSON.stringify(t)), t) : void 0;
177
+ } catch (s) {
178
+ console.error("Failed to ingest session redirect", s);
177
179
  return;
178
180
  }
179
181
  }
180
182
  async username() {
181
- return await this._ready, this._username;
183
+ return await this._readyPromise, this.account || this.tryRetrieveSessionAccount(), this._username;
182
184
  }
183
185
  async probe() {
184
- return await this._ready, this.account;
186
+ return await this._readyPromise, this.account || this.tryRetrieveSessionAccount(), this.account;
185
187
  }
186
188
  async connect() {
187
- if (await this._ready, this.account)
189
+ if (await this._readyPromise, this.account || this.tryRetrieveSessionAccount(), this.account)
188
190
  return this.account;
189
191
  localStorage.setItem("sessionPolicies", JSON.stringify(this._policies)), localStorage.setItem("lastUsedConnector", this.id);
190
192
  try {
191
193
  if (this.reopenBrowser) {
192
- const i = u.randomAddress();
193
- this._publicKey = p.starkCurve.getStarkKey(i), localStorage.setItem(
194
+ const t = p.randomAddress();
195
+ this._publicKey = m.starkCurve.getStarkKey(t), localStorage.setItem(
194
196
  "sessionSigner",
195
197
  JSON.stringify({
196
- privKey: i,
198
+ privKey: t,
197
199
  pubKey: this._publicKey
198
200
  })
199
201
  ), this._sessionKeyGuid = h({
200
- starknet: { privateKey: l.addHexPrefix(i) }
202
+ starknet: { privateKey: l.addHexPrefix(t) }
201
203
  });
202
204
  let r = `${this._keychainUrl}/session?public_key=${this._publicKey}&redirect_uri=${this._redirectUrl}&redirect_query_name=startapp&rpc_url=${this._rpcUrl}`;
203
205
  this._preset ? r += `&preset=${encodeURIComponent(this._preset)}` : r += `&policies=${encodeURIComponent(JSON.stringify(this._policies))}`, this._signupOptions && (r += `&signers=${encodeURIComponent(JSON.stringify(this._signupOptions))}`), window.open(r, "_blank");
204
206
  }
205
- const e = await f(
207
+ const e = await w(
206
208
  this._sessionKeyGuid,
207
209
  this._apiUrl
208
- ), t = e.authorization[1], s = {
210
+ ), s = e.authorization[1], i = {
209
211
  username: e.controller.accountID,
210
212
  address: e.controller.address,
211
- ownerGuid: t,
213
+ ownerGuid: s,
212
214
  expiresAt: e.expiresAt,
213
215
  guardianKeyGuid: "0x0",
214
216
  metadataHash: "0x0",
215
217
  sessionKeyGuid: this._sessionKeyGuid
216
218
  };
217
- return localStorage.setItem("session", JSON.stringify(s)), this.tryRetrieveFromQueryOrStorage(), this.account;
219
+ return localStorage.setItem("session", JSON.stringify(i)), this.tryRetrieveSessionAccount(), this.account;
218
220
  } catch (e) {
219
221
  throw console.log(e), e;
220
222
  }
@@ -232,37 +234,38 @@ class k extends w {
232
234
  "redirect_url",
233
235
  this._disconnectRedirectUrl
234
236
  );
235
- const t = window.open(e);
236
- if (t === null) return Promise.resolve();
237
- const { resolve: s, promise: i } = Promise.withResolvers();
237
+ const s = window.open(e);
238
+ if (s === null) return Promise.resolve();
239
+ const { resolve: i, promise: t } = Promise.withResolvers();
238
240
  function r() {
239
- t?.closed && (s(), clearInterval(a));
241
+ s?.closed && (i(), clearInterval(a));
240
242
  }
241
243
  const a = setInterval(r, 500);
242
- return i;
244
+ return t;
243
245
  }
244
- tryRetrieveFromQueryOrStorage() {
246
+ // Try to retrieve the session account from localStorage or URL query params
247
+ tryRetrieveSessionAccount() {
245
248
  if (this.account)
246
249
  return this.account;
247
- const e = localStorage.getItem("sessionSigner"), t = e ? JSON.parse(e) : null;
248
- let s = null;
249
- const i = localStorage.getItem("session");
250
- if (i) {
251
- const o = JSON.parse(i), n = this.normalizeSession(o);
252
- n ? (s = n, localStorage.setItem("session", JSON.stringify(s))) : this.clearStoredSession();
250
+ let e = null;
251
+ const s = localStorage.getItem("session");
252
+ if (s) {
253
+ const o = JSON.parse(s), n = this.normalizeSession(o);
254
+ n ? (e = n, localStorage.setItem("session", JSON.stringify(e))) : this.clearStoredSession();
253
255
  }
254
- if (window.location.search.includes("startapp")) {
255
- const o = new URLSearchParams(window.location.search), n = o.get("startapp");
256
+ if (window.location.search.includes(u)) {
257
+ const o = new URLSearchParams(window.location.search), n = o.get(u);
256
258
  if (n) {
257
259
  const c = this.ingestSessionFromRedirect(n);
258
- c && Number(c.expiresAt) !== Number(s?.expiresAt) && (s = c), o.delete("startapp");
260
+ c && Number(c.expiresAt) !== Number(e?.expiresAt) && (e = c), o.delete(u);
259
261
  const d = window.location.pathname + (o.toString() ? `?${o.toString()}` : "") + window.location.hash;
260
262
  window.history.replaceState({}, document.title, d);
261
263
  }
262
264
  }
263
- if (!s || !t)
265
+ const i = localStorage.getItem("sessionSigner"), t = i ? JSON.parse(i) : null;
266
+ if (!e || !t)
264
267
  return;
265
- const r = parseInt(s.expiresAt) * 1e3;
268
+ const r = parseInt(e.expiresAt) * 1e3;
266
269
  if (Date.now() >= r) {
267
270
  this.clearStoredSession();
268
271
  return;
@@ -280,17 +283,17 @@ class k extends w {
280
283
  return;
281
284
  }
282
285
  }
283
- return this._username = s.username, this.account = new N(this, {
286
+ return this._username = e.username, this.account = new N(this, {
284
287
  rpcUrl: this._rpcUrl,
285
288
  privateKey: t.privKey,
286
- address: s.address,
287
- ownerGuid: s.ownerGuid,
289
+ address: e.address,
290
+ ownerGuid: e.ownerGuid,
288
291
  chainId: this._chainId,
289
- expiresAt: parseInt(s.expiresAt),
290
- policies: x(this._policies),
291
- guardianKeyGuid: s.guardianKeyGuid,
292
- metadataHash: s.metadataHash,
293
- sessionKeyGuid: s.sessionKeyGuid
292
+ expiresAt: parseInt(e.expiresAt),
293
+ policies: P(this._policies),
294
+ guardianKeyGuid: e.guardianKeyGuid,
295
+ metadataHash: e.metadataHash,
296
+ sessionKeyGuid: e.sessionKeyGuid
294
297
  }), this.account;
295
298
  }
296
299
  clearStoredSession() {
@@ -298,15 +301,15 @@ class k extends w {
298
301
  }
299
302
  }
300
303
  export {
301
- H as ALL_AUTH_OPTIONS,
302
- J as EMBEDDED_WALLETS,
303
- $ as FeeSource,
304
- z as HeadlessAuthenticationError,
305
- F as HeadlessModeNotSupportedError,
306
- L as IMPLEMENTED_AUTH_OPTIONS,
307
- T as InvalidCredentialsError,
308
- B as NotReadyToConnect,
309
- D as ResponseCodes,
310
- k as default
304
+ J as ALL_AUTH_OPTIONS,
305
+ $ as EMBEDDED_WALLETS,
306
+ z as FeeSource,
307
+ T as HeadlessAuthenticationError,
308
+ L as HeadlessModeNotSupportedError,
309
+ B as IMPLEMENTED_AUTH_OPTIONS,
310
+ D as InvalidCredentialsError,
311
+ F as NotReadyToConnect,
312
+ M as ResponseCodes,
313
+ b as default
311
314
  };
312
315
  //# sourceMappingURL=session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sources":["../src/session/account.ts","../src/session/provider.ts"],"sourcesContent":["import { Policy } from \"@cartridge/controller-wasm\";\nimport { CartridgeSessionAccount } from \"@cartridge/controller-wasm/session\";\nimport { Call, InvokeFunctionResponse, WalletAccount } from \"starknet\";\n\nimport { normalizeCalls } from \"../utils\";\nimport BaseProvider from \"../provider\";\n\nexport * from \"../errors\";\nexport * from \"../types\";\n\nexport default class SessionAccount extends WalletAccount {\n public controller: CartridgeSessionAccount;\n\n constructor(\n provider: BaseProvider,\n {\n rpcUrl,\n privateKey,\n address,\n ownerGuid,\n chainId,\n expiresAt,\n policies,\n guardianKeyGuid,\n metadataHash,\n sessionKeyGuid,\n }: {\n rpcUrl: string;\n privateKey: string;\n address: string;\n ownerGuid: string;\n chainId: string;\n expiresAt: number;\n policies: Policy[];\n guardianKeyGuid: string;\n metadataHash: string;\n sessionKeyGuid: string;\n },\n ) {\n super({\n provider: { nodeUrl: rpcUrl },\n walletProvider: provider,\n address,\n });\n\n this.controller = CartridgeSessionAccount.newAsRegistered(\n rpcUrl,\n privateKey,\n address,\n ownerGuid,\n chainId,\n {\n expiresAt,\n policies,\n guardianKeyGuid: guardianKeyGuid ?? \"0x0\",\n metadataHash: metadataHash ?? \"0x0\",\n sessionKeyGuid: sessionKeyGuid,\n },\n );\n }\n\n /**\n * Invoke execute function in account contract\n *\n * @param calls the invocation object or an array of them, containing:\n * - contractAddress - the address of the contract\n * - entrypoint - the entrypoint of the contract\n * - calldata - (defaults to []) the calldata\n * - signature - (defaults to []) the signature\n * @param abis (optional) the abi of the contract for better displaying\n *\n * @returns response from addTransaction\n */\n async execute(calls: Call | Call[]): Promise<InvokeFunctionResponse> {\n try {\n const res = await this.controller.executeFromOutside(\n normalizeCalls(calls),\n );\n return res;\n } catch (e) {\n return this.controller.execute(normalizeCalls(calls));\n }\n }\n}\n","import { ec, stark, WalletAccount } from \"starknet\";\n\nimport {\n signerToGuid,\n subscribeCreateSession,\n} from \"@cartridge/controller-wasm\";\nimport { loadConfig, SessionPolicies } from \"@cartridge/presets\";\nimport { AddStarknetChainParameters } from \"@starknet-io/types-js\";\nimport { encode } from \"starknet\";\nimport { API_URL, KEYCHAIN_URL } from \"../constants\";\nimport { parsePolicies, ParsedSessionPolicies } from \"../policies\";\nimport BaseProvider from \"../provider\";\nimport { AuthOptions } from \"../types\";\nimport { getPresetSessionPolicies, toWasmPolicies } from \"../utils\";\nimport SessionAccount from \"./account\";\n\ninterface SessionRegistration {\n username: string;\n address: string;\n ownerGuid: string;\n transactionHash?: string;\n expiresAt: string;\n guardianKeyGuid: string;\n metadataHash: string;\n sessionKeyGuid: string;\n allowedPoliciesRoot?: string;\n}\n\nexport type SessionOptions = {\n rpc: string;\n chainId: string;\n policies?: SessionPolicies;\n preset?: string;\n shouldOverridePresetPolicies?: boolean;\n redirectUrl: string;\n disconnectRedirectUrl?: string;\n keychainUrl?: string;\n apiUrl?: string;\n signupOptions?: AuthOptions;\n};\n\nexport default class SessionProvider extends BaseProvider {\n public id = \"controller_session\";\n public name = \"Controller Session\";\n\n protected _chainId: string;\n protected _rpcUrl: string;\n protected _username?: string;\n protected _redirectUrl: string;\n protected _disconnectRedirectUrl?: string;\n protected _policies: ParsedSessionPolicies;\n protected _preset?: string;\n private _ready: Promise<void>;\n protected _keychainUrl: string;\n protected _apiUrl: string;\n protected _publicKey!: string;\n protected _sessionKeyGuid!: string;\n protected _signupOptions?: AuthOptions;\n public reopenBrowser: boolean = true;\n\n constructor({\n rpc,\n chainId,\n policies,\n preset,\n shouldOverridePresetPolicies,\n redirectUrl,\n disconnectRedirectUrl,\n keychainUrl,\n apiUrl,\n signupOptions,\n }: SessionOptions) {\n super();\n\n if (!policies && !preset) {\n throw new Error(\"Either `policies` or `preset` must be provided\");\n }\n\n // Policy precedence logic (matching ControllerProvider):\n // 1. If shouldOverridePresetPolicies is true and policies are provided, use policies\n // 2. Otherwise, if preset is defined, resolve policies from preset\n // 3. Otherwise, use provided policies\n if ((!preset || shouldOverridePresetPolicies) && policies) {\n this._policies = parsePolicies(policies);\n } else {\n this._preset = preset;\n if (policies) {\n console.warn(\n \"[Controller] Both `preset` and `policies` provided to SessionProvider. \" +\n \"Policies are ignored when preset is set. \" +\n \"Use `shouldOverridePresetPolicies: true` to override.\",\n );\n }\n this._policies = { verified: false };\n }\n\n this._rpcUrl = rpc;\n this._chainId = chainId;\n this._redirectUrl = redirectUrl;\n this._disconnectRedirectUrl = disconnectRedirectUrl;\n this._keychainUrl = keychainUrl || KEYCHAIN_URL;\n this._apiUrl = apiUrl ?? API_URL;\n this._signupOptions = signupOptions;\n\n // Eagerly start async init: resolve preset policies (if any),\n // then try to restore an existing session from storage.\n // All public async methods await this before proceeding.\n this._ready = this._init();\n\n if (typeof window !== \"undefined\") {\n (window as any).starknet_controller_session = this;\n }\n }\n\n private async _init(): Promise<void> {\n if (this._preset) {\n const config = await loadConfig(this._preset);\n if (!config) {\n throw new Error(`Failed to load preset: ${this._preset}`);\n }\n\n const sessionPolicies = getPresetSessionPolicies(config, this._chainId);\n if (!sessionPolicies) {\n throw new Error(\n `No policies found for chain ${this._chainId} in preset ${this._preset}`,\n );\n }\n\n this._policies = parsePolicies(sessionPolicies);\n }\n\n const account = this.tryRetrieveFromQueryOrStorage();\n if (!account) {\n const pk = stark.randomAddress();\n this._publicKey = ec.starkCurve.getStarkKey(pk);\n\n localStorage.setItem(\n \"sessionSigner\",\n JSON.stringify({\n privKey: pk,\n pubKey: this._publicKey,\n }),\n );\n this._sessionKeyGuid = signerToGuid({\n starknet: { privateKey: encode.addHexPrefix(pk) },\n });\n } else {\n const pk = localStorage.getItem(\"sessionSigner\");\n if (!pk) throw new Error(\"failed to get sessionSigner\");\n\n const jsonPk: {\n privKey: string;\n pubKey: string;\n } = JSON.parse(pk);\n\n this._publicKey = jsonPk.pubKey;\n this._sessionKeyGuid = signerToGuid({\n starknet: { privateKey: encode.addHexPrefix(jsonPk.privKey) },\n });\n }\n }\n\n private validatePoliciesSubset(\n newPolicies: ParsedSessionPolicies,\n existingPolicies: ParsedSessionPolicies,\n ): boolean {\n if (newPolicies.contracts) {\n if (!existingPolicies.contracts) return false;\n\n for (const [address, contract] of Object.entries(newPolicies.contracts)) {\n const existingContract = existingPolicies.contracts[address];\n if (!existingContract) return false;\n\n for (const method of contract.methods) {\n const existingMethod = existingContract.methods.find(\n (m) => m.entrypoint === method.entrypoint,\n );\n if (!existingMethod || !existingMethod.authorized) return false;\n }\n }\n }\n\n if (newPolicies.messages) {\n if (!existingPolicies.messages) return false;\n\n for (const message of newPolicies.messages) {\n const existingMessage = existingPolicies.messages.find(\n (m) =>\n JSON.stringify(m.domain) === JSON.stringify(message.domain) &&\n JSON.stringify(m.types) === JSON.stringify(message.types),\n );\n if (!existingMessage || !existingMessage.authorized) return false;\n }\n }\n\n return true;\n }\n\n private padBase64(value: string): string {\n const padding = value.length % 4;\n if (padding === 0) {\n return value;\n }\n return value + \"=\".repeat(4 - padding);\n }\n\n private normalizeSession(\n session: Partial<SessionRegistration>,\n ): SessionRegistration | undefined {\n if (\n session.username === undefined ||\n session.address === undefined ||\n session.ownerGuid === undefined ||\n session.expiresAt === undefined\n ) {\n return undefined;\n }\n\n return {\n username: session.username,\n address: session.address,\n ownerGuid: session.ownerGuid,\n transactionHash: session.transactionHash,\n expiresAt: session.expiresAt,\n guardianKeyGuid: session.guardianKeyGuid ?? \"0x0\",\n metadataHash: session.metadataHash ?? \"0x0\",\n sessionKeyGuid: session.sessionKeyGuid ?? this._sessionKeyGuid,\n };\n }\n\n public ingestSessionFromRedirect(\n encodedSession: string,\n ): SessionRegistration | undefined {\n try {\n const decoded = atob(this.padBase64(encodedSession));\n const parsed = JSON.parse(decoded) as Partial<SessionRegistration>;\n const normalized = this.normalizeSession(parsed);\n if (!normalized) {\n return undefined;\n }\n localStorage.setItem(\"session\", JSON.stringify(normalized));\n return normalized;\n } catch (e) {\n console.error(\"Failed to ingest session redirect\", e);\n return undefined;\n }\n }\n\n async username() {\n await this._ready;\n return this._username;\n }\n\n async probe(): Promise<WalletAccount | undefined> {\n await this._ready;\n return this.account;\n }\n\n async connect(): Promise<WalletAccount | undefined> {\n await this._ready;\n\n if (this.account) {\n return this.account;\n }\n\n localStorage.setItem(\"sessionPolicies\", JSON.stringify(this._policies));\n localStorage.setItem(\"lastUsedConnector\", this.id);\n\n try {\n if (this.reopenBrowser) {\n const pk = stark.randomAddress();\n this._publicKey = ec.starkCurve.getStarkKey(pk);\n\n localStorage.setItem(\n \"sessionSigner\",\n JSON.stringify({\n privKey: pk,\n pubKey: this._publicKey,\n }),\n );\n this._sessionKeyGuid = signerToGuid({\n starknet: { privateKey: encode.addHexPrefix(pk) },\n });\n let url =\n `${this._keychainUrl}` +\n `/session?public_key=${this._publicKey}` +\n `&redirect_uri=${this._redirectUrl}` +\n `&redirect_query_name=startapp` +\n `&rpc_url=${this._rpcUrl}`;\n\n if (this._preset) {\n url += `&preset=${encodeURIComponent(this._preset)}`;\n } else {\n url += `&policies=${encodeURIComponent(JSON.stringify(this._policies))}`;\n }\n\n if (this._signupOptions) {\n url += `&signers=${encodeURIComponent(JSON.stringify(this._signupOptions))}`;\n }\n\n window.open(url, \"_blank\");\n }\n\n const sessionResult = await subscribeCreateSession(\n this._sessionKeyGuid,\n this._apiUrl,\n );\n\n // auth is: [shortstring!('authorization-by-registered'), owner_guid]\n const ownerGuid = sessionResult.authorization[1];\n const session: SessionRegistration = {\n username: sessionResult.controller.accountID,\n address: sessionResult.controller.address,\n ownerGuid,\n expiresAt: sessionResult.expiresAt,\n guardianKeyGuid: \"0x0\",\n metadataHash: \"0x0\",\n sessionKeyGuid: this._sessionKeyGuid,\n };\n localStorage.setItem(\"session\", JSON.stringify(session));\n\n this.tryRetrieveFromQueryOrStorage();\n\n return this.account;\n } catch (e) {\n console.log(e);\n throw e;\n }\n }\n\n switchStarknetChain(_chainId: string): Promise<boolean> {\n throw new Error(\"switchStarknetChain not implemented\");\n }\n\n addStarknetChain(_chain: AddStarknetChainParameters): Promise<boolean> {\n throw new Error(\"addStarknetChain not implemented\");\n }\n\n disconnect(): Promise<void> {\n localStorage.removeItem(\"sessionSigner\");\n localStorage.removeItem(\"session\");\n localStorage.removeItem(\"sessionPolicies\");\n localStorage.removeItem(\"lastUsedConnector\");\n this.account = undefined;\n this.emitAccountsChanged([]);\n this._username = undefined;\n const disconnectUrl = new URL(`${this._keychainUrl}`);\n disconnectUrl.pathname = \"disconnect\";\n\n this._disconnectRedirectUrl &&\n disconnectUrl.searchParams.append(\n \"redirect_url\",\n this._disconnectRedirectUrl,\n );\n\n const openedWindow = window.open(disconnectUrl);\n if (openedWindow === null) return Promise.resolve();\n\n const { resolve, promise } = Promise.withResolvers<void>();\n function onWindowClose() {\n if (openedWindow?.closed) {\n resolve();\n clearInterval(checkInterval);\n }\n }\n const checkInterval = setInterval(onWindowClose, 500);\n return promise;\n }\n\n tryRetrieveFromQueryOrStorage() {\n if (this.account) {\n return this.account;\n }\n\n const signerString = localStorage.getItem(\"sessionSigner\");\n const signer = signerString ? JSON.parse(signerString) : null;\n let sessionRegistration: SessionRegistration | null = null;\n\n const sessionString = localStorage.getItem(\"session\");\n if (sessionString) {\n const parsed = JSON.parse(sessionString) as Partial<SessionRegistration>;\n const normalized = this.normalizeSession(parsed);\n if (normalized) {\n sessionRegistration = normalized;\n localStorage.setItem(\"session\", JSON.stringify(sessionRegistration));\n } else {\n this.clearStoredSession();\n }\n }\n\n if (window.location.search.includes(\"startapp\")) {\n const params = new URLSearchParams(window.location.search);\n const session = params.get(\"startapp\");\n if (session) {\n const normalizedSession = this.ingestSessionFromRedirect(session);\n if (\n normalizedSession &&\n Number(normalizedSession.expiresAt) !==\n Number(sessionRegistration?.expiresAt)\n ) {\n sessionRegistration = normalizedSession;\n }\n\n // Remove the session query parameter\n params.delete(\"startapp\");\n const newUrl =\n window.location.pathname +\n (params.toString() ? `?${params.toString()}` : \"\") +\n window.location.hash;\n window.history.replaceState({}, document.title, newUrl);\n }\n }\n\n if (!sessionRegistration || !signer) {\n return;\n }\n\n // Check expiration\n const expirationTime = parseInt(sessionRegistration.expiresAt) * 1000;\n if (Date.now() >= expirationTime) {\n this.clearStoredSession();\n return;\n }\n\n // Check stored policies\n const storedPoliciesStr = localStorage.getItem(\"sessionPolicies\");\n if (storedPoliciesStr) {\n const storedPolicies = JSON.parse(\n storedPoliciesStr,\n ) as ParsedSessionPolicies;\n\n const isValid = this.validatePoliciesSubset(\n this._policies,\n storedPolicies,\n );\n\n if (!isValid) {\n this.clearStoredSession();\n return;\n }\n }\n\n this._username = sessionRegistration.username;\n this.account = new SessionAccount(this, {\n rpcUrl: this._rpcUrl,\n privateKey: signer.privKey,\n address: sessionRegistration.address,\n ownerGuid: sessionRegistration.ownerGuid,\n chainId: this._chainId,\n expiresAt: parseInt(sessionRegistration.expiresAt),\n policies: toWasmPolicies(this._policies),\n guardianKeyGuid: sessionRegistration.guardianKeyGuid,\n metadataHash: sessionRegistration.metadataHash,\n sessionKeyGuid: sessionRegistration.sessionKeyGuid,\n });\n\n return this.account;\n }\n\n private clearStoredSession(): void {\n localStorage.removeItem(\"sessionSigner\");\n localStorage.removeItem(\"session\");\n localStorage.removeItem(\"sessionPolicies\");\n localStorage.removeItem(\"lastUsedConnector\");\n }\n}\n"],"names":["SessionAccount","WalletAccount","provider","rpcUrl","privateKey","address","ownerGuid","chainId","expiresAt","policies","guardianKeyGuid","metadataHash","sessionKeyGuid","CartridgeSessionAccount","calls","normalizeCalls","SessionProvider","BaseProvider","rpc","preset","shouldOverridePresetPolicies","redirectUrl","disconnectRedirectUrl","keychainUrl","apiUrl","signupOptions","parsePolicies","KEYCHAIN_URL","API_URL","config","loadConfig","sessionPolicies","getPresetSessionPolicies","pk","jsonPk","signerToGuid","encode","stark","ec","newPolicies","existingPolicies","contract","existingContract","method","existingMethod","m","message","existingMessage","value","padding","session","encodedSession","decoded","parsed","normalized","e","url","sessionResult","subscribeCreateSession","_chainId","_chain","disconnectUrl","openedWindow","resolve","promise","onWindowClose","checkInterval","signerString","signer","sessionRegistration","sessionString","params","normalizedSession","newUrl","expirationTime","storedPoliciesStr","storedPolicies","toWasmPolicies"],"mappings":"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"}
1
+ {"version":3,"file":"session.js","sources":["../src/session/account.ts","../src/session/provider.ts"],"sourcesContent":["import { Policy } from \"@cartridge/controller-wasm\";\nimport { CartridgeSessionAccount } from \"@cartridge/controller-wasm/session\";\nimport { Call, InvokeFunctionResponse, WalletAccount } from \"starknet\";\n\nimport { normalizeCalls } from \"../utils\";\nimport BaseProvider from \"../provider\";\n\nexport * from \"../errors\";\nexport * from \"../types\";\n\nexport default class SessionAccount extends WalletAccount {\n public controller: CartridgeSessionAccount;\n\n constructor(\n provider: BaseProvider,\n {\n rpcUrl,\n privateKey,\n address,\n ownerGuid,\n chainId,\n expiresAt,\n policies,\n guardianKeyGuid,\n metadataHash,\n sessionKeyGuid,\n }: {\n rpcUrl: string;\n privateKey: string;\n address: string;\n ownerGuid: string;\n chainId: string;\n expiresAt: number;\n policies: Policy[];\n guardianKeyGuid: string;\n metadataHash: string;\n sessionKeyGuid: string;\n },\n ) {\n super({\n provider: { nodeUrl: rpcUrl },\n walletProvider: provider,\n address,\n });\n\n this.controller = CartridgeSessionAccount.newAsRegistered(\n rpcUrl,\n privateKey,\n address,\n ownerGuid,\n chainId,\n {\n expiresAt,\n policies,\n guardianKeyGuid: guardianKeyGuid ?? \"0x0\",\n metadataHash: metadataHash ?? \"0x0\",\n sessionKeyGuid: sessionKeyGuid,\n },\n );\n }\n\n /**\n * Invoke execute function in account contract\n *\n * @param calls the invocation object or an array of them, containing:\n * - contractAddress - the address of the contract\n * - entrypoint - the entrypoint of the contract\n * - calldata - (defaults to []) the calldata\n * - signature - (defaults to []) the signature\n * @param abis (optional) the abi of the contract for better displaying\n *\n * @returns response from addTransaction\n */\n async execute(calls: Call | Call[]): Promise<InvokeFunctionResponse> {\n try {\n const res = await this.controller.executeFromOutside(\n normalizeCalls(calls),\n );\n return res;\n } catch (e) {\n return this.controller.execute(normalizeCalls(calls));\n }\n }\n}\n","import { ec, stark, WalletAccount } from \"starknet\";\n\nimport {\n signerToGuid,\n subscribeCreateSession,\n} from \"@cartridge/controller-wasm\";\nimport { loadConfig, SessionPolicies } from \"@cartridge/presets\";\nimport { AddStarknetChainParameters } from \"@starknet-io/types-js\";\nimport { encode } from \"starknet\";\nimport { API_URL, KEYCHAIN_URL, REDIRECT_QUERY_NAME } from \"../constants\";\nimport { parsePolicies, ParsedSessionPolicies } from \"../policies\";\nimport BaseProvider from \"../provider\";\nimport { AuthOptions } from \"../types\";\nimport { getPresetSessionPolicies, toWasmPolicies } from \"../utils\";\nimport SessionAccount from \"./account\";\n\ninterface SessionRegistration {\n username: string;\n address: string;\n ownerGuid: string;\n transactionHash?: string;\n expiresAt: string;\n guardianKeyGuid: string;\n metadataHash: string;\n sessionKeyGuid: string;\n allowedPoliciesRoot?: string;\n}\n\nexport type SessionOptions = {\n rpc: string;\n chainId: string;\n policies?: SessionPolicies;\n preset?: string;\n shouldOverridePresetPolicies?: boolean;\n redirectUrl: string;\n disconnectRedirectUrl?: string;\n keychainUrl?: string;\n apiUrl?: string;\n signupOptions?: AuthOptions;\n};\n\nexport default class SessionProvider extends BaseProvider {\n public id = \"controller_session\";\n public name = \"Controller Session\";\n\n protected _chainId: string;\n protected _rpcUrl: string;\n protected _username?: string;\n protected _redirectUrl: string;\n protected _disconnectRedirectUrl?: string;\n protected _policies: ParsedSessionPolicies;\n protected _preset?: string;\n protected _keychainUrl: string;\n protected _apiUrl: string;\n protected _publicKey!: string;\n protected _sessionKeyGuid!: string;\n protected _signupOptions?: AuthOptions;\n private _readyPromise: Promise<void>;\n public reopenBrowser: boolean = true;\n\n constructor({\n rpc,\n chainId,\n policies,\n preset,\n shouldOverridePresetPolicies,\n redirectUrl,\n disconnectRedirectUrl,\n keychainUrl,\n apiUrl,\n signupOptions,\n }: SessionOptions) {\n super();\n\n if (!policies && !preset) {\n throw new Error(\"Either `policies` or `preset` must be provided\");\n }\n\n // Policy precedence logic (matching ControllerProvider):\n // 1. If shouldOverridePresetPolicies is true and policies are provided, use policies\n // 2. Otherwise, if preset is defined, resolve policies from preset\n // 3. Otherwise, use provided policies\n if ((!preset || shouldOverridePresetPolicies) && policies) {\n this._policies = parsePolicies(policies);\n } else {\n this._preset = preset;\n if (policies) {\n console.warn(\n \"[Controller] Both `preset` and `policies` provided to SessionProvider. \" +\n \"Policies are ignored when preset is set. \" +\n \"Use `shouldOverridePresetPolicies: true` to override.\",\n );\n }\n this._policies = { verified: false };\n }\n\n this._rpcUrl = rpc;\n this._chainId = chainId;\n this._redirectUrl = redirectUrl;\n this._disconnectRedirectUrl = disconnectRedirectUrl;\n this._keychainUrl = keychainUrl || KEYCHAIN_URL;\n this._apiUrl = apiUrl ?? API_URL;\n this._signupOptions = signupOptions;\n\n this._setSigningKeys();\n this._readyPromise = this._resolvePreset();\n\n if (typeof window !== \"undefined\") {\n (window as any).starknet_controller_session = this;\n }\n }\n\n private _setSigningKeys(): void {\n const signerString = localStorage.getItem(\"sessionSigner\");\n if (signerString) {\n const signer = JSON.parse(signerString);\n this._publicKey = signer.pubKey;\n this._sessionKeyGuid = signerToGuid({\n starknet: { privateKey: encode.addHexPrefix(signer.privKey) },\n });\n } else {\n const pk = stark.randomAddress();\n this._publicKey = ec.starkCurve.getStarkKey(pk);\n\n localStorage.setItem(\n \"sessionSigner\",\n JSON.stringify({\n privKey: pk,\n pubKey: this._publicKey,\n }),\n );\n this._sessionKeyGuid = signerToGuid({\n starknet: { privateKey: encode.addHexPrefix(pk) },\n });\n }\n }\n\n // Resolve preset policies asynchronously.\n // Public methods await this before proceeding.\n private async _resolvePreset(): Promise<void> {\n if (!this._preset) return;\n\n const config = await loadConfig(this._preset);\n if (!config) {\n throw new Error(`Failed to load preset: ${this._preset}`);\n }\n\n const sessionPolicies = getPresetSessionPolicies(config, this._chainId);\n if (!sessionPolicies) {\n throw new Error(\n `No policies found for chain ${this._chainId} in preset ${this._preset}`,\n );\n }\n\n this._policies = parsePolicies(sessionPolicies);\n }\n\n private validatePoliciesSubset(\n newPolicies: ParsedSessionPolicies,\n existingPolicies: ParsedSessionPolicies,\n ): boolean {\n if (newPolicies.contracts) {\n if (!existingPolicies.contracts) return false;\n\n for (const [address, contract] of Object.entries(newPolicies.contracts)) {\n const existingContract = existingPolicies.contracts[address];\n if (!existingContract) return false;\n\n for (const method of contract.methods) {\n const existingMethod = existingContract.methods.find(\n (m) => m.entrypoint === method.entrypoint,\n );\n if (!existingMethod || !existingMethod.authorized) return false;\n }\n }\n }\n\n if (newPolicies.messages) {\n if (!existingPolicies.messages) return false;\n\n for (const message of newPolicies.messages) {\n const existingMessage = existingPolicies.messages.find(\n (m) =>\n JSON.stringify(m.domain) === JSON.stringify(message.domain) &&\n JSON.stringify(m.types) === JSON.stringify(message.types),\n );\n if (!existingMessage || !existingMessage.authorized) return false;\n }\n }\n\n return true;\n }\n\n private padBase64(value: string): string {\n const padding = value.length % 4;\n if (padding === 0) {\n return value;\n }\n return value + \"=\".repeat(4 - padding);\n }\n\n private normalizeSession(\n session: Partial<SessionRegistration>,\n ): SessionRegistration | undefined {\n if (\n session.username === undefined ||\n session.address === undefined ||\n session.ownerGuid === undefined ||\n session.expiresAt === undefined\n ) {\n return undefined;\n }\n\n return {\n username: session.username,\n address: session.address,\n ownerGuid: session.ownerGuid,\n transactionHash: session.transactionHash,\n expiresAt: session.expiresAt,\n guardianKeyGuid: session.guardianKeyGuid ?? \"0x0\",\n metadataHash: session.metadataHash ?? \"0x0\",\n sessionKeyGuid: session.sessionKeyGuid ?? this._sessionKeyGuid,\n };\n }\n\n public ingestSessionFromRedirect(\n encodedSession: string,\n ): SessionRegistration | undefined {\n try {\n const decoded = atob(this.padBase64(encodedSession));\n const parsed = JSON.parse(decoded) as Partial<SessionRegistration>;\n const normalized = this.normalizeSession(parsed);\n if (!normalized) {\n return undefined;\n }\n localStorage.setItem(\"session\", JSON.stringify(normalized));\n return normalized;\n } catch (e) {\n console.error(\"Failed to ingest session redirect\", e);\n return undefined;\n }\n }\n\n async username() {\n await this._readyPromise;\n\n if (!this.account) {\n this.tryRetrieveSessionAccount();\n }\n\n return this._username;\n }\n\n async probe(): Promise<WalletAccount | undefined> {\n await this._readyPromise;\n\n if (!this.account) {\n this.tryRetrieveSessionAccount();\n }\n\n return this.account;\n }\n\n async connect(): Promise<WalletAccount | undefined> {\n await this._readyPromise;\n\n if (!this.account) {\n this.tryRetrieveSessionAccount();\n }\n\n if (this.account) {\n return this.account;\n }\n\n localStorage.setItem(\"sessionPolicies\", JSON.stringify(this._policies));\n localStorage.setItem(\"lastUsedConnector\", this.id);\n\n try {\n if (this.reopenBrowser) {\n const pk = stark.randomAddress();\n this._publicKey = ec.starkCurve.getStarkKey(pk);\n\n localStorage.setItem(\n \"sessionSigner\",\n JSON.stringify({\n privKey: pk,\n pubKey: this._publicKey,\n }),\n );\n this._sessionKeyGuid = signerToGuid({\n starknet: { privateKey: encode.addHexPrefix(pk) },\n });\n let url =\n `${this._keychainUrl}` +\n `/session?public_key=${this._publicKey}` +\n `&redirect_uri=${this._redirectUrl}` +\n `&redirect_query_name=startapp` +\n `&rpc_url=${this._rpcUrl}`;\n\n if (this._preset) {\n url += `&preset=${encodeURIComponent(this._preset)}`;\n } else {\n url += `&policies=${encodeURIComponent(JSON.stringify(this._policies))}`;\n }\n\n if (this._signupOptions) {\n url += `&signers=${encodeURIComponent(JSON.stringify(this._signupOptions))}`;\n }\n\n window.open(url, \"_blank\");\n }\n\n const sessionResult = await subscribeCreateSession(\n this._sessionKeyGuid,\n this._apiUrl,\n );\n\n // auth is: [shortstring!('authorization-by-registered'), owner_guid]\n const ownerGuid = sessionResult.authorization[1];\n const session: SessionRegistration = {\n username: sessionResult.controller.accountID,\n address: sessionResult.controller.address,\n ownerGuid,\n expiresAt: sessionResult.expiresAt,\n guardianKeyGuid: \"0x0\",\n metadataHash: \"0x0\",\n sessionKeyGuid: this._sessionKeyGuid,\n };\n localStorage.setItem(\"session\", JSON.stringify(session));\n\n this.tryRetrieveSessionAccount();\n\n return this.account;\n } catch (e) {\n console.log(e);\n throw e;\n }\n }\n\n switchStarknetChain(_chainId: string): Promise<boolean> {\n throw new Error(\"switchStarknetChain not implemented\");\n }\n\n addStarknetChain(_chain: AddStarknetChainParameters): Promise<boolean> {\n throw new Error(\"addStarknetChain not implemented\");\n }\n\n disconnect(): Promise<void> {\n localStorage.removeItem(\"sessionSigner\");\n localStorage.removeItem(\"session\");\n localStorage.removeItem(\"sessionPolicies\");\n localStorage.removeItem(\"lastUsedConnector\");\n this.account = undefined;\n this.emitAccountsChanged([]);\n this._username = undefined;\n const disconnectUrl = new URL(`${this._keychainUrl}`);\n disconnectUrl.pathname = \"disconnect\";\n\n this._disconnectRedirectUrl &&\n disconnectUrl.searchParams.append(\n \"redirect_url\",\n this._disconnectRedirectUrl,\n );\n\n const openedWindow = window.open(disconnectUrl);\n if (openedWindow === null) return Promise.resolve();\n\n const { resolve, promise } = Promise.withResolvers<void>();\n function onWindowClose() {\n if (openedWindow?.closed) {\n resolve();\n clearInterval(checkInterval);\n }\n }\n const checkInterval = setInterval(onWindowClose, 500);\n return promise;\n }\n\n // Try to retrieve the session account from localStorage or URL query params\n private tryRetrieveSessionAccount() {\n if (this.account) {\n return this.account;\n }\n\n let sessionRegistration: SessionRegistration | null = null;\n\n // Load session from localStorage (saved by ingestSessionFromRedirect or connect)\n const sessionString = localStorage.getItem(\"session\");\n if (sessionString) {\n const parsed = JSON.parse(sessionString) as Partial<SessionRegistration>;\n const normalized = this.normalizeSession(parsed);\n if (normalized) {\n sessionRegistration = normalized;\n localStorage.setItem(\"session\", JSON.stringify(sessionRegistration));\n } else {\n this.clearStoredSession();\n }\n }\n\n if (window.location.search.includes(REDIRECT_QUERY_NAME)) {\n const params = new URLSearchParams(window.location.search);\n const session = params.get(REDIRECT_QUERY_NAME);\n if (session) {\n const normalizedSession = this.ingestSessionFromRedirect(session);\n if (\n normalizedSession &&\n Number(normalizedSession.expiresAt) !==\n Number(sessionRegistration?.expiresAt)\n ) {\n sessionRegistration = normalizedSession;\n }\n\n // Remove the session query parameter\n params.delete(REDIRECT_QUERY_NAME);\n const newUrl =\n window.location.pathname +\n (params.toString() ? `?${params.toString()}` : \"\") +\n window.location.hash;\n window.history.replaceState({}, document.title, newUrl);\n }\n }\n\n const signerString = localStorage.getItem(\"sessionSigner\");\n const signer = signerString ? JSON.parse(signerString) : null;\n\n if (!sessionRegistration || !signer) {\n return;\n }\n\n // Check expiration\n const expirationTime = parseInt(sessionRegistration.expiresAt) * 1000;\n if (Date.now() >= expirationTime) {\n this.clearStoredSession();\n return;\n }\n\n // Check stored policies\n const storedPoliciesStr = localStorage.getItem(\"sessionPolicies\");\n if (storedPoliciesStr) {\n const storedPolicies = JSON.parse(\n storedPoliciesStr,\n ) as ParsedSessionPolicies;\n\n const isValid = this.validatePoliciesSubset(\n this._policies,\n storedPolicies,\n );\n\n if (!isValid) {\n this.clearStoredSession();\n return;\n }\n }\n\n this._username = sessionRegistration.username;\n this.account = new SessionAccount(this, {\n rpcUrl: this._rpcUrl,\n privateKey: signer.privKey,\n address: sessionRegistration.address,\n ownerGuid: sessionRegistration.ownerGuid,\n chainId: this._chainId,\n expiresAt: parseInt(sessionRegistration.expiresAt),\n policies: toWasmPolicies(this._policies),\n guardianKeyGuid: sessionRegistration.guardianKeyGuid,\n metadataHash: sessionRegistration.metadataHash,\n sessionKeyGuid: sessionRegistration.sessionKeyGuid,\n });\n\n return this.account;\n }\n\n private clearStoredSession(): void {\n localStorage.removeItem(\"sessionSigner\");\n localStorage.removeItem(\"session\");\n localStorage.removeItem(\"sessionPolicies\");\n localStorage.removeItem(\"lastUsedConnector\");\n }\n}\n"],"names":["SessionAccount","WalletAccount","provider","rpcUrl","privateKey","address","ownerGuid","chainId","expiresAt","policies","guardianKeyGuid","metadataHash","sessionKeyGuid","CartridgeSessionAccount","calls","normalizeCalls","SessionProvider","BaseProvider","rpc","preset","shouldOverridePresetPolicies","redirectUrl","disconnectRedirectUrl","keychainUrl","apiUrl","signupOptions","parsePolicies","KEYCHAIN_URL","API_URL","signerString","signer","signerToGuid","encode","pk","stark","ec","config","loadConfig","sessionPolicies","getPresetSessionPolicies","newPolicies","existingPolicies","contract","existingContract","method","existingMethod","m","message","existingMessage","value","padding","session","encodedSession","decoded","parsed","normalized","e","url","sessionResult","subscribeCreateSession","_chainId","_chain","disconnectUrl","openedWindow","resolve","promise","onWindowClose","checkInterval","sessionRegistration","sessionString","REDIRECT_QUERY_NAME","params","normalizedSession","newUrl","expirationTime","storedPoliciesStr","storedPolicies","toWasmPolicies"],"mappings":"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"}