@cartridge/controller 0.5.0-alpha.4 → 0.5.0-alpha.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 (71) hide show
  1. package/.turbo/turbo-build$colon$deps.log +116 -4
  2. package/dist/account.d.ts +9 -6
  3. package/dist/account.js +84 -74
  4. package/dist/account.js.map +1 -1
  5. package/dist/constants.d.ts +4 -2
  6. package/dist/constants.js +7 -2
  7. package/dist/constants.js.map +1 -1
  8. package/dist/controller.d.ts +12 -5
  9. package/dist/controller.js +739 -182
  10. package/dist/controller.js.map +1 -1
  11. package/dist/errors.d.ts +3 -1
  12. package/dist/errors.js +10 -6
  13. package/dist/errors.js.map +1 -1
  14. package/dist/icon.d.ts +3 -1
  15. package/dist/icon.js +5 -1
  16. package/dist/icon.js.map +1 -1
  17. package/dist/iframe/base.d.ts +5 -23
  18. package/dist/iframe/base.js +272 -98
  19. package/dist/iframe/base.js.map +1 -1
  20. package/dist/iframe/index.d.ts +5 -3
  21. package/dist/iframe/index.js +331 -3
  22. package/dist/iframe/index.js.map +1 -1
  23. package/dist/iframe/keychain.d.ts +5 -7
  24. package/dist/iframe/keychain.js +294 -13
  25. package/dist/iframe/keychain.js.map +1 -1
  26. package/dist/iframe/profile.d.ts +5 -11
  27. package/dist/iframe/profile.js +308 -16
  28. package/dist/iframe/profile.js.map +1 -1
  29. package/dist/index.d.ts +9 -4
  30. package/dist/index.js +767 -4
  31. package/dist/index.js.map +1 -1
  32. package/dist/presets.d.ts +9 -2
  33. package/dist/presets.js +159 -146
  34. package/dist/presets.js.map +1 -1
  35. package/dist/provider.d.ts +9 -4
  36. package/dist/provider.js +138 -124
  37. package/dist/provider.js.map +1 -1
  38. package/dist/session/account.d.ts +14 -8
  39. package/dist/session/account.js +235 -27
  40. package/dist/session/account.js.map +1 -1
  41. package/dist/session/backend.d.ts +4 -2
  42. package/dist/session/backend.js +38 -37
  43. package/dist/session/backend.js.map +1 -1
  44. package/dist/session/index.d.ts +9 -5
  45. package/dist/session/index.js +467 -5
  46. package/dist/session/index.js.map +1 -1
  47. package/dist/session/provider.d.ts +12 -8
  48. package/dist/session/provider.js +281 -81
  49. package/dist/session/provider.js.map +1 -1
  50. package/dist/telegram/backend.d.ts +5 -2
  51. package/dist/telegram/backend.js +38 -37
  52. package/dist/telegram/backend.js.map +1 -1
  53. package/dist/telegram/provider.d.ts +7 -4
  54. package/dist/telegram/provider.js +283 -70
  55. package/dist/telegram/provider.js.map +1 -1
  56. package/dist/types-DIeWpu0p.d.ts +196 -0
  57. package/dist/types.d.ts +5 -159
  58. package/dist/types.js +12 -8
  59. package/dist/types.js.map +1 -1
  60. package/dist/utils.d.ts +7 -3
  61. package/dist/utils.js +12 -8
  62. package/dist/utils.js.map +1 -1
  63. package/package.json +17 -14
  64. package/src/controller.ts +13 -25
  65. package/src/iframe/base.ts +3 -0
  66. package/src/iframe/profile.ts +17 -9
  67. package/src/presets.ts +10 -1
  68. package/src/session/provider.ts +1 -2
  69. package/src/types.ts +3 -7
  70. package/tsconfig.json +4 -1
  71. package/tsconfig.tsbuildinfo +0 -1
package/dist/index.js CHANGED
@@ -1,5 +1,768 @@
1
- export { default } from "./controller";
2
- export * from "./errors";
3
- export * from "./types";
4
- export { defaultPresets } from "./presets";
1
+ // src/account.ts
2
+ import {
3
+ WalletAccount
4
+ } from "starknet";
5
+
6
+ // src/types.ts
7
+ var ResponseCodes = /* @__PURE__ */ ((ResponseCodes2) => {
8
+ ResponseCodes2["SUCCESS"] = "SUCCESS";
9
+ ResponseCodes2["NOT_CONNECTED"] = "NOT_CONNECTED";
10
+ ResponseCodes2["ERROR"] = "ERROR";
11
+ ResponseCodes2["CANCELED"] = "CANCELED";
12
+ ResponseCodes2["USER_INTERACTION_REQUIRED"] = "USER_INTERACTION_REQUIRED";
13
+ return ResponseCodes2;
14
+ })(ResponseCodes || {});
15
+
16
+ // src/account.ts
17
+ var ControllerAccount = class extends WalletAccount {
18
+ constructor(provider, address, keychain, options, modal) {
19
+ super({ nodeUrl: provider.rpc.toString() }, provider);
20
+ this.address = address;
21
+ this.keychain = keychain;
22
+ this.options = options;
23
+ this.modal = modal;
24
+ }
25
+ /**
26
+ * Invoke execute function in account contract
27
+ *
28
+ * @param calls the invocation object or an array of them, containing:
29
+ * - contractAddress - the address of the contract
30
+ * - entrypoint - the entrypoint of the contract
31
+ * - calldata - (defaults to []) the calldata
32
+ * - signature - (defaults to []) the signature
33
+ * @param abis (optional) the abi of the contract for better displaying
34
+ *
35
+ * @returns response from addTransaction
36
+ */
37
+ async execute(calls) {
38
+ calls = Array.isArray(calls) ? calls : [calls];
39
+ return new Promise(async (resolve, reject) => {
40
+ const sessionExecute = await this.keychain.execute(
41
+ calls,
42
+ void 0,
43
+ void 0,
44
+ false
45
+ );
46
+ if (sessionExecute.code === "SUCCESS" /* SUCCESS */) {
47
+ resolve(sessionExecute);
48
+ return;
49
+ }
50
+ if (this.options?.propagateSessionErrors) {
51
+ reject(sessionExecute.error);
52
+ return;
53
+ }
54
+ this.modal.open();
55
+ const manualExecute = await this.keychain.execute(
56
+ calls,
57
+ void 0,
58
+ void 0,
59
+ true,
60
+ sessionExecute.error
61
+ );
62
+ if (manualExecute.code === "SUCCESS" /* SUCCESS */) {
63
+ resolve(manualExecute);
64
+ this.modal.close();
65
+ return;
66
+ }
67
+ reject(manualExecute.error);
68
+ return;
69
+ });
70
+ }
71
+ /**
72
+ * Sign an JSON object for off-chain usage with the starknet private key and return the signature
73
+ * This adds a message prefix so it cant be interchanged with transactions
74
+ *
75
+ * @param json - JSON object to be signed
76
+ * @returns the signature of the JSON object
77
+ * @throws {Error} if the JSON object is not a valid JSON
78
+ */
79
+ async signMessage(typedData) {
80
+ try {
81
+ this.modal.open();
82
+ const res = await this.keychain.signMessage(typedData, "");
83
+ this.modal.close();
84
+ if ("code" in res) {
85
+ throw res;
86
+ }
87
+ return res;
88
+ } catch (e) {
89
+ console.error(e);
90
+ throw e;
91
+ }
92
+ }
93
+ };
94
+ var account_default = ControllerAccount;
95
+
96
+ // src/iframe/base.ts
97
+ import { connectToChild } from "@cartridge/penpal";
98
+
99
+ // src/presets.ts
100
+ var defaultPresets = {
101
+ cartridge: {
102
+ id: "cartridge",
103
+ name: "Cartridge",
104
+ icon: "/whitelabel/cartridge/icon.svg",
105
+ cover: {
106
+ light: "/whitelabel/cartridge/cover-light.png",
107
+ dark: "/whitelabel/cartridge/cover-dark.png"
108
+ }
109
+ },
110
+ "force-prime": {
111
+ id: "force-prime",
112
+ name: "Force Prime",
113
+ icon: "/whitelabel/force-prime/icon.png",
114
+ cover: "/whitelabel/force-prime/cover.png",
115
+ colors: {
116
+ primary: "#E1CC89"
117
+ }
118
+ },
119
+ paved: {
120
+ id: "paved",
121
+ name: "Paved",
122
+ icon: "/whitelabel/paved/icon.svg",
123
+ cover: "/whitelabel/paved/cover.png",
124
+ colors: {
125
+ primary: "#B0CAF8"
126
+ }
127
+ },
128
+ eternum: {
129
+ id: "eternum",
130
+ name: "Eternum",
131
+ icon: "/whitelabel/eternum/icon.gif",
132
+ cover: "/whitelabel/eternum/cover.png",
133
+ colors: {
134
+ primary: "#CE9822"
135
+ }
136
+ },
137
+ pistols: {
138
+ id: "pistols",
139
+ name: "Pistols at Ten Blocks",
140
+ icon: "/whitelabel/pistols/icon.png",
141
+ cover: "/whitelabel/pistols/cover.png",
142
+ colors: {
143
+ primary: "#EF9758"
144
+ }
145
+ },
146
+ pixelaw: {
147
+ id: "pixelaw",
148
+ name: "Pixelaw",
149
+ icon: "/whitelabel/pixelaw/icon.svg",
150
+ cover: "/whitelabel/pixelaw/cover.png",
151
+ colors: {
152
+ primary: "#7C00B1",
153
+ primaryForeground: "white"
154
+ }
155
+ },
156
+ "dope-wars": {
157
+ id: "dope-wars",
158
+ name: "Dope Wars",
159
+ icon: "/whitelabel/dope-wars/icon.png",
160
+ cover: "/whitelabel/dope-wars/cover.png",
161
+ colors: {
162
+ primary: "#11ED83"
163
+ }
164
+ },
165
+ zkastle: {
166
+ id: "zkastle",
167
+ name: "zKastle",
168
+ icon: "/whitelabel/zkastle/icon.svg",
169
+ cover: "/whitelabel/zkastle/cover.png",
170
+ colors: {
171
+ primary: "#E50D2C"
172
+ }
173
+ },
174
+ "loot-survivor": {
175
+ id: "loot-survivor",
176
+ name: "Loot Survivor",
177
+ icon: "/whitelabel/loot-survivor/icon.png",
178
+ cover: "/whitelabel/loot-survivor/cover.png",
179
+ colors: {
180
+ primary: "#33FF33"
181
+ }
182
+ },
183
+ "tale-weaver": {
184
+ id: "tale-weaver",
185
+ name: "Tale Weaver",
186
+ icon: "/whitelabel/tale-weaver/icon.png",
187
+ cover: "/whitelabel/tale-weaver/cover.png",
188
+ colors: {
189
+ primary: "#fce377"
190
+ }
191
+ },
192
+ "realm-of-ra": {
193
+ id: "realm-of-ra",
194
+ name: "Realm of Ra",
195
+ icon: "/whitelabel/realm-of-ra/icon.png",
196
+ cover: "/whitelabel/realm-of-ra/cover.png",
197
+ colors: {
198
+ primary: "#de9534"
199
+ }
200
+ },
201
+ "jokers-of-neon": {
202
+ id: "jokers-of-neon",
203
+ name: "Jokers of Neon",
204
+ icon: "/whitelabel/jokers-of-neon/icon.png",
205
+ cover: "/whitelabel/jokers-of-neon/cover.png",
206
+ colors: {
207
+ primary: "#A144B2"
208
+ }
209
+ },
210
+ flippyflop: {
211
+ id: "flippyflop",
212
+ name: "FlippyFlop",
213
+ icon: "/whitelabel/flippyflop/icon.png",
214
+ cover: "/whitelabel/flippyflop/cover.png",
215
+ colors: {
216
+ primary: "#F38332"
217
+ }
218
+ },
219
+ "savage-summit": {
220
+ id: "savage-summit",
221
+ name: "Savage Summit",
222
+ icon: "/whitelabel/savage-summit/icon.png",
223
+ cover: "/whitelabel/savage-summit/cover.png",
224
+ colors: {
225
+ primary: "#fbf7da"
226
+ }
227
+ },
228
+ "dark-shuffle": {
229
+ id: "dark-shuffle",
230
+ name: "Dark Shuffle",
231
+ icon: "/whitelabel/dark-shuffle/icon.svg",
232
+ cover: "/whitelabel/dark-shuffle/cover.png",
233
+ colors: {
234
+ primary: "#F59100"
235
+ }
236
+ },
237
+ "blob-arena": {
238
+ id: "blob-arena",
239
+ name: "Blob Arena",
240
+ icon: "/whitelabel/blob-arena/icon.png",
241
+ cover: "/whitelabel/blob-arena/cover.png",
242
+ colors: {
243
+ primary: "#980f06"
244
+ }
245
+ },
246
+ zkube: {
247
+ id: "zkube",
248
+ name: "zKube",
249
+ icon: "/whitelabel/zkube/icon.png",
250
+ cover: "/whitelabel/zkube/cover.png",
251
+ colors: {
252
+ primary: "#5bc3e6"
253
+ }
254
+ }
255
+ };
256
+
257
+ // src/iframe/base.ts
258
+ var IFrame = class {
259
+ constructor({
260
+ id,
261
+ url,
262
+ theme,
263
+ config,
264
+ colorMode,
265
+ onClose,
266
+ onConnect,
267
+ methods = {}
268
+ }) {
269
+ if (typeof document === "undefined") {
270
+ return;
271
+ }
272
+ url.searchParams.set(
273
+ "theme",
274
+ encodeURIComponent(
275
+ JSON.stringify(
276
+ config?.presets?.[theme ?? "cartridge"] ?? defaultPresets.cartridge
277
+ )
278
+ )
279
+ );
280
+ if (colorMode) {
281
+ url.searchParams.set("colorMode", colorMode);
282
+ }
283
+ this.url = url;
284
+ const iframe = document.createElement("iframe");
285
+ iframe.src = url.toString();
286
+ iframe.id = id;
287
+ iframe.style.border = "none";
288
+ iframe.sandbox.add("allow-forms");
289
+ iframe.sandbox.add("allow-popups");
290
+ iframe.sandbox.add("allow-scripts");
291
+ iframe.sandbox.add("allow-same-origin");
292
+ iframe.allow = "publickey-credentials-create *; publickey-credentials-get *; clipboard-write";
293
+ if (!!document.hasStorageAccess) {
294
+ iframe.sandbox.add("allow-storage-access-by-user-activation");
295
+ }
296
+ const container = document.createElement("div");
297
+ container.id = "controller";
298
+ container.style.position = "fixed";
299
+ container.style.height = "100%";
300
+ container.style.width = "100%";
301
+ container.style.top = "0";
302
+ container.style.left = "0";
303
+ container.style.zIndex = "10000";
304
+ container.style.backgroundColor = "rgba(0,0,0,0.6)";
305
+ container.style.display = "flex";
306
+ container.style.alignItems = "center";
307
+ container.style.justifyContent = "center";
308
+ container.style.visibility = "hidden";
309
+ container.style.opacity = "0";
310
+ container.style.transition = "opacity 0.2s ease";
311
+ container.appendChild(iframe);
312
+ this.iframe = iframe;
313
+ this.container = container;
314
+ connectToChild({
315
+ iframe: this.iframe,
316
+ methods: { close: () => this.close(), ...methods }
317
+ }).promise.then(onConnect);
318
+ this.resize();
319
+ window.addEventListener("resize", () => this.resize());
320
+ const observer = new MutationObserver(() => {
321
+ const existingController2 = document.getElementById("controller");
322
+ if (document.body) {
323
+ if (id === "controller-keychain" && !existingController2 || id === "controller-profile") {
324
+ document.body.appendChild(container);
325
+ observer.disconnect();
326
+ }
327
+ }
328
+ });
329
+ observer.observe(document.documentElement, {
330
+ childList: true,
331
+ subtree: true
332
+ });
333
+ const existingController = document.getElementById("controller");
334
+ if (document.body) {
335
+ if (id === "controller-keychain" && !existingController || id === "controller-profile") {
336
+ document.body.appendChild(container);
337
+ }
338
+ }
339
+ this.onClose = onClose;
340
+ }
341
+ open() {
342
+ if (!this.container) return;
343
+ document.body.style.overflow = "hidden";
344
+ this.container.style.visibility = "visible";
345
+ this.container.style.opacity = "1";
346
+ }
347
+ close() {
348
+ if (!this.container) return;
349
+ this.onClose?.();
350
+ document.body.style.overflow = "auto";
351
+ this.container.style.visibility = "hidden";
352
+ this.container.style.opacity = "0";
353
+ }
354
+ resize() {
355
+ if (!this.iframe) return;
356
+ this.iframe.style.userSelect = "none";
357
+ if (window.innerWidth < 768) {
358
+ this.iframe.style.height = "100%";
359
+ this.iframe.style.width = "100%";
360
+ this.iframe.style.borderRadius = "0";
361
+ return;
362
+ }
363
+ this.iframe.style.height = "600px";
364
+ this.iframe.style.width = "432px";
365
+ this.iframe.style.borderRadius = "8px";
366
+ }
367
+ };
368
+
369
+ // src/constants.ts
370
+ var KEYCHAIN_URL = "https://x.cartridge.gg";
371
+ var PROFILE_URL = "https://profile.cartridge.gg";
372
+
373
+ // src/iframe/keychain.ts
374
+ var KeychainIFrame = class extends IFrame {
375
+ constructor({ url, policies, ...iframeOptions }) {
376
+ const _url = new URL(url ?? KEYCHAIN_URL);
377
+ if (policies) {
378
+ _url.searchParams.set(
379
+ "policies",
380
+ encodeURIComponent(JSON.stringify(policies))
381
+ );
382
+ }
383
+ super({
384
+ ...iframeOptions,
385
+ id: "controller-keychain",
386
+ url: _url
387
+ });
388
+ }
389
+ };
390
+
391
+ // src/iframe/profile.ts
392
+ var ProfileIFrame = class extends IFrame {
393
+ constructor({
394
+ profileUrl,
395
+ rpcUrl,
396
+ namespace,
397
+ slot,
398
+ username,
399
+ tokens,
400
+ ...iframeOptions
401
+ }) {
402
+ const _profileUrl = profileUrl || PROFILE_URL;
403
+ const _url = new URL(
404
+ slot ? namespace ? `${_profileUrl}/account/${username}/slot/${slot}?ns=${encodeURIComponent(
405
+ namespace
406
+ )}` : `${_profileUrl}/account/${username}/slot/${slot}` : `${_profileUrl}/account/${username}`
407
+ );
408
+ _url.searchParams.set("rpcUrl", encodeURIComponent(rpcUrl));
409
+ if (tokens?.erc20) {
410
+ _url.searchParams.set(
411
+ "erc20",
412
+ encodeURIComponent(tokens.erc20.toString())
413
+ );
414
+ }
415
+ super({
416
+ ...iframeOptions,
417
+ id: "controller-profile",
418
+ url: _url
419
+ });
420
+ }
421
+ };
422
+
423
+ // src/errors.ts
424
+ var NotReadyToConnect = class _NotReadyToConnect extends Error {
425
+ constructor() {
426
+ super("Not ready to connect");
427
+ Object.setPrototypeOf(this, _NotReadyToConnect.prototype);
428
+ }
429
+ };
430
+
431
+ // src/provider.ts
432
+ import {
433
+ Permission
434
+ } from "@starknet-io/types-js";
435
+
436
+ // src/icon.ts
437
+ var icon = "data:image/png;base64,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";
438
+
439
+ // src/provider.ts
440
+ var BaseProvider = class {
441
+ constructor(options) {
442
+ this.id = "controller";
443
+ this.name = "Controller";
444
+ this.version = "0.4.0";
445
+ this.icon = icon;
446
+ this.subscriptions = [];
447
+ this.request = async (call) => {
448
+ switch (call.type) {
449
+ case "wallet_getPermissions":
450
+ await this.probe();
451
+ if (this.account) {
452
+ return [Permission.ACCOUNTS];
453
+ }
454
+ return [];
455
+ case "wallet_requestAccounts": {
456
+ if (this.account) {
457
+ return [this.account.address];
458
+ }
459
+ this.account = await this.probe();
460
+ if (!this.account) {
461
+ this.account = await this.connect();
462
+ }
463
+ if (this.account) {
464
+ return [this.account.address];
465
+ }
466
+ return [];
467
+ }
468
+ case "wallet_watchAsset":
469
+ throw {
470
+ code: 63,
471
+ message: "An unexpected error occurred",
472
+ data: "wallet_watchAsset not implemented"
473
+ };
474
+ case "wallet_addStarknetChain":
475
+ throw {
476
+ code: 63,
477
+ message: "An unexpected error occurred",
478
+ data: "wallet_addStarknetChain not implemented"
479
+ };
480
+ case "wallet_switchStarknetChain":
481
+ throw {
482
+ code: 63,
483
+ message: "An unexpected error occurred",
484
+ data: "wallet_switchStarknetChain not implemented"
485
+ };
486
+ case "wallet_requestChainId":
487
+ if (!this.account) {
488
+ throw {
489
+ code: 63,
490
+ message: "An unexpected error occurred",
491
+ data: "wallet_deploymentData not implemented"
492
+ };
493
+ }
494
+ return await this.account.getChainId();
495
+ case "wallet_deploymentData":
496
+ throw {
497
+ code: 63,
498
+ message: "An unexpected error occurred",
499
+ data: "wallet_deploymentData not implemented"
500
+ };
501
+ case "wallet_addInvokeTransaction":
502
+ if (!this.account) {
503
+ throw {
504
+ code: 63,
505
+ message: "An unexpected error occurred",
506
+ data: "wallet_deploymentData not implemented"
507
+ };
508
+ }
509
+ let params = call.params;
510
+ return await this.account.execute(
511
+ params.calls.map((call2) => ({
512
+ contractAddress: call2.contract_address,
513
+ entrypoint: call2.entry_point,
514
+ calldata: call2.calldata
515
+ }))
516
+ );
517
+ case "wallet_addDeclareTransaction":
518
+ throw {
519
+ code: 63,
520
+ message: "An unexpected error occurred",
521
+ data: "wallet_addDeclareTransaction not implemented"
522
+ };
523
+ case "wallet_signTypedData": {
524
+ if (!this.account) {
525
+ throw {
526
+ code: 63,
527
+ message: "An unexpected error occurred",
528
+ data: "Account not initialized"
529
+ };
530
+ }
531
+ return await this.account.signMessage(call.params);
532
+ }
533
+ case "wallet_supportedSpecs":
534
+ return [];
535
+ case "wallet_supportedWalletApi":
536
+ return [];
537
+ default:
538
+ throw {
539
+ code: 63,
540
+ message: "An unexpected error occurred",
541
+ data: `Unknown RPC call type: ${call.type}`
542
+ };
543
+ }
544
+ };
545
+ this.on = (event, handler) => {
546
+ if (event !== "accountsChanged" && event !== "networkChanged") {
547
+ throw new Error(`Unknown event: ${event}`);
548
+ }
549
+ this.subscriptions.push({ type: event, handler });
550
+ };
551
+ this.off = (event, handler) => {
552
+ if (event !== "accountsChanged" && event !== "networkChanged") {
553
+ throw new Error(`Unknown event: ${event}`);
554
+ }
555
+ const idx = this.subscriptions.findIndex(
556
+ (sub) => sub.type === event && sub.handler === handler
557
+ );
558
+ if (idx >= 0) {
559
+ this.subscriptions.splice(idx, 1);
560
+ }
561
+ };
562
+ const { rpc } = options;
563
+ this.rpc = new URL(rpc);
564
+ }
565
+ };
566
+
567
+ // src/controller.ts
568
+ var ControllerProvider = class extends BaseProvider {
569
+ constructor(options) {
570
+ const { rpc } = options;
571
+ super({ rpc });
572
+ this.iframes = {
573
+ keychain: new KeychainIFrame({
574
+ ...options,
575
+ onClose: this.keychain?.reset,
576
+ onConnect: (keychain) => {
577
+ this.keychain = keychain;
578
+ }
579
+ })
580
+ };
581
+ this.options = options;
582
+ if (typeof window !== "undefined") {
583
+ window.starknet_controller = this;
584
+ }
585
+ }
586
+ async probe() {
587
+ try {
588
+ await this.waitForKeychain();
589
+ if (!this.keychain) {
590
+ console.error(new NotReadyToConnect().message);
591
+ return;
592
+ }
593
+ const response = await this.keychain.probe(
594
+ this.rpc.toString()
595
+ );
596
+ this.account = new account_default(
597
+ this,
598
+ response.address,
599
+ this.keychain,
600
+ this.options,
601
+ this.iframes.keychain
602
+ );
603
+ } catch (e) {
604
+ console.error(e);
605
+ return;
606
+ }
607
+ if (this.options.profileUrl && !this.iframes.profile) {
608
+ const username = await this.keychain.username();
609
+ this.iframes.profile = new ProfileIFrame({
610
+ onConnect: (profile) => {
611
+ this.profile = profile;
612
+ },
613
+ methods: {
614
+ openPurchaseCredits: this.openPurchaseCredits.bind(this)
615
+ },
616
+ profileUrl: this.options.profileUrl,
617
+ rpcUrl: this.rpc.toString(),
618
+ username,
619
+ slot: this.options.slot,
620
+ namespace: this.options.namespace,
621
+ tokens: this.options.tokens
622
+ });
623
+ }
624
+ return this.account;
625
+ }
626
+ async connect() {
627
+ if (this.account) {
628
+ return this.account;
629
+ }
630
+ if (!this.keychain || !this.iframes.keychain) {
631
+ console.error(new NotReadyToConnect().message);
632
+ return;
633
+ }
634
+ if (!!document.hasStorageAccess) {
635
+ const ok = await document.hasStorageAccess();
636
+ if (!ok) {
637
+ await document.requestStorageAccess();
638
+ }
639
+ }
640
+ this.iframes.keychain.open();
641
+ try {
642
+ let response = await this.keychain.connect(
643
+ this.options.policies || [],
644
+ this.rpc.toString()
645
+ );
646
+ if (response.code !== "SUCCESS" /* SUCCESS */) {
647
+ throw new Error(response.message);
648
+ }
649
+ response = response;
650
+ this.account = new account_default(
651
+ this,
652
+ response.address,
653
+ this.keychain,
654
+ this.options,
655
+ this.iframes.keychain
656
+ );
657
+ return this.account;
658
+ } catch (e) {
659
+ console.log(e);
660
+ } finally {
661
+ this.iframes.keychain.close();
662
+ }
663
+ }
664
+ async disconnect() {
665
+ if (!this.keychain) {
666
+ console.error(new NotReadyToConnect().message);
667
+ return;
668
+ }
669
+ if (!!document.hasStorageAccess) {
670
+ const ok = await document.hasStorageAccess();
671
+ if (!ok) {
672
+ await document.requestStorageAccess();
673
+ }
674
+ }
675
+ this.account = void 0;
676
+ return this.keychain.disconnect();
677
+ }
678
+ async openProfile(tab = "inventory") {
679
+ if (!this.profile || !this.iframes.profile?.url) {
680
+ console.error("Profile is not ready");
681
+ return;
682
+ }
683
+ if (!this.account) {
684
+ console.error("Account is not ready");
685
+ return;
686
+ }
687
+ this.profile.navigate(`${this.iframes.profile.url?.pathname}/${tab}`);
688
+ this.iframes.profile.open();
689
+ }
690
+ async openSettings() {
691
+ if (!this.keychain || !this.iframes.keychain) {
692
+ console.error(new NotReadyToConnect().message);
693
+ return null;
694
+ }
695
+ this.iframes.keychain.open();
696
+ const res = await this.keychain.openSettings();
697
+ this.iframes.keychain.close();
698
+ if (res && res.code === "NOT_CONNECTED" /* NOT_CONNECTED */) {
699
+ return false;
700
+ }
701
+ return true;
702
+ }
703
+ revoke(origin, _policy) {
704
+ if (!this.keychain) {
705
+ console.error(new NotReadyToConnect().message);
706
+ return null;
707
+ }
708
+ return this.keychain.revoke(origin);
709
+ }
710
+ username() {
711
+ if (!this.keychain) {
712
+ console.error(new NotReadyToConnect().message);
713
+ return;
714
+ }
715
+ return this.keychain.username();
716
+ }
717
+ fetchControllers(contractAddresses) {
718
+ if (!this.keychain) {
719
+ throw new NotReadyToConnect().message;
720
+ }
721
+ return this.keychain.fetchControllers(contractAddresses);
722
+ }
723
+ openPurchaseCredits() {
724
+ if (!this.keychain || !this.iframes.keychain) {
725
+ console.error(new NotReadyToConnect().message);
726
+ return;
727
+ }
728
+ if (!this.iframes.profile) {
729
+ console.error("Profile is not ready");
730
+ return;
731
+ }
732
+ this.iframes.profile.close();
733
+ this.iframes.keychain.open();
734
+ this.keychain.openPurchaseCredits();
735
+ }
736
+ async delegateAccount() {
737
+ if (!this.keychain) {
738
+ console.error(new NotReadyToConnect().message);
739
+ return null;
740
+ }
741
+ return await this.keychain.delegateAccount();
742
+ }
743
+ waitForKeychain({
744
+ timeout = 5e3,
745
+ interval = 100
746
+ } = {}) {
747
+ return new Promise((resolve, reject) => {
748
+ const startTime = Date.now();
749
+ const id = setInterval(() => {
750
+ if (Date.now() - startTime > timeout) {
751
+ clearInterval(id);
752
+ reject(new Error("Timeout waiting for keychain"));
753
+ return;
754
+ }
755
+ if (!this.keychain) return;
756
+ clearInterval(id);
757
+ resolve();
758
+ }, interval);
759
+ });
760
+ }
761
+ };
762
+ export {
763
+ NotReadyToConnect,
764
+ ResponseCodes,
765
+ ControllerProvider as default,
766
+ defaultPresets
767
+ };
5
768
  //# sourceMappingURL=index.js.map