@domino-sdk/relay 1.60.0 → 1.62.0

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 (80) hide show
  1. package/CHANGELOG.md +175 -8
  2. package/README.md +3 -2
  3. package/dist/{schema-CwbRkmlr.d.ts → accounts-CCqCKCVx.d.ts} +3127 -1764
  4. package/dist/action-9Xl0StBg.d.ts +33 -0
  5. package/dist/{analytics-URV-mxjH.d.ts → analytics-BwAKLi7O.d.ts} +347 -3
  6. package/dist/{attempt-captures-W2dgzGqE.d.ts → attempt-captures-Cm-5G0PC.d.ts} +1 -1
  7. package/dist/authoring.d.ts +130 -42
  8. package/dist/authoring.js +105 -19
  9. package/dist/{automatic-outcomes-Cmou89IS.d.ts → automatic-outcomes-pAsOyIVp.d.ts} +5 -1
  10. package/dist/avatar.d.ts +1 -1
  11. package/dist/browser.d.ts +15 -11
  12. package/dist/browser.js +15 -11
  13. package/dist/{integrations-CmIkP1Gi.d.ts → capability-error-DFMwSuSf.d.ts} +160 -42
  14. package/dist/{pages-Bti7g5mX.d.ts → catalog--ZIlskAo.d.ts} +39 -561
  15. package/dist/{chunk-N3LJ6GFK.js → chunk-3KLC4AMA.js} +40 -11
  16. package/dist/{chunk-6ZG7WNYX.js → chunk-3PYYGFSB.js} +14 -2
  17. package/dist/{chunk-VWMIA2TT.js → chunk-5TEYFX6X.js} +2 -2
  18. package/dist/chunk-6WCIWXUV.js +31 -0
  19. package/dist/chunk-CICDIBOF.js +373 -0
  20. package/dist/{chunk-MHPKEVEW.js → chunk-CZFXGGEK.js} +5 -0
  21. package/dist/chunk-D26YNACF.js +320 -0
  22. package/dist/{chunk-KUPVQXUJ.js → chunk-E6IKQHTX.js} +2 -2
  23. package/dist/chunk-FWLQ5XCS.js +21 -0
  24. package/dist/{chunk-VVRQQRMQ.js → chunk-GKIFABGN.js} +150 -61
  25. package/dist/chunk-GTDW453U.js +522 -0
  26. package/dist/{chunk-Y2IGFLD2.js → chunk-HTZHBTIL.js} +69 -27
  27. package/dist/chunk-K2KS3JLY.js +188 -0
  28. package/dist/{chunk-GBSDAD3N.js → chunk-MK425RXJ.js} +3140 -3202
  29. package/dist/{chunk-YOAPPIWN.js → chunk-QYPMPWVX.js} +1 -1
  30. package/dist/chunk-UAKYDVT3.js +565 -0
  31. package/dist/{chunk-KWFY7L7X.js → chunk-UPQPUJOU.js} +36 -123
  32. package/dist/{chunk-2FHNY52R.js → chunk-UW5232GG.js} +65 -19
  33. package/dist/chunk-WSBYWVTZ.js +717 -0
  34. package/dist/{chunk-422J3QRW.js → chunk-XJFYAXET.js} +9 -8
  35. package/dist/{chunk-OTEUP2SG.js → chunk-XNKSSE32.js} +1 -1
  36. package/dist/{chunk-4OFH4BNX.js → chunk-Y322OTCH.js} +1 -1
  37. package/dist/{client-Cw1pB5sv.d.ts → client-B-hbHX30.d.ts} +109 -40
  38. package/dist/{deployments-DI-W7fBq.d.ts → deployments-M4OHn7G3.d.ts} +407 -18
  39. package/dist/identity-integration-3mX6b5iH.d.ts +1241 -0
  40. package/dist/index.d.ts +13 -11
  41. package/dist/index.js +14 -11
  42. package/dist/internal.d.ts +14 -12
  43. package/dist/internal.js +26 -14
  44. package/dist/{offers-CqXfMIxq.d.ts → offers-DhAtss4_.d.ts} +21 -4
  45. package/dist/pages-B8q8Y_dQ.d.ts +715 -0
  46. package/dist/{participant-activity-DHL8QYks.d.ts → participant-activity-D-Drp24G.d.ts} +16 -3
  47. package/dist/portal-proxy.d.ts +59 -2
  48. package/dist/portal-proxy.js +109 -23
  49. package/dist/react/index.d.ts +211 -27
  50. package/dist/react/index.js +286 -29
  51. package/dist/{action-DBzILFx9.d.ts → request-error-D_dUPLwo.d.ts} +1 -31
  52. package/dist/runtime/authoring.js +1 -1
  53. package/dist/runtime/chunks/Y4OAVXFR.js +1 -0
  54. package/dist/runtime/manifest.json +3 -3
  55. package/dist/runtime/schema.js +1 -1
  56. package/dist/schema.d.ts +154 -30
  57. package/dist/schema.js +128 -75
  58. package/dist/server/index.d.ts +14 -12
  59. package/dist/server/index.js +2189 -1631
  60. package/dist/sign-in-providers-BkjcDsFF.d.ts +39 -0
  61. package/dist/submission-input-DHGKhXfp.d.ts +342 -0
  62. package/dist/{telegram-browser-CTJh4Ro_.d.ts → telegram-browser-BCE7zdOb.d.ts} +49 -6
  63. package/dist/telegram.d.ts +64 -0
  64. package/dist/telegram.js +23 -0
  65. package/dist/testing.d.ts +112 -15
  66. package/dist/testing.js +321 -16
  67. package/dist/tracker-data-Hb1uQnk5.d.ts +1855 -0
  68. package/dist/{transport-B8Ss5lcz.d.ts → transport-DkhX2Cbs.d.ts} +5863 -2217
  69. package/dist/{wallet-DZWL7lJH.d.ts → wallet-DTO7SXj7.d.ts} +27 -7
  70. package/package.json +5 -1
  71. package/dist/accounts-DoabriBX.d.ts +0 -306
  72. package/dist/capability-error-DufwG3G0.d.ts +0 -159
  73. package/dist/chunk-MJEJQH5A.js +0 -962
  74. package/dist/chunk-N7YOS4ZU.js +0 -13
  75. package/dist/chunk-XQKUJL7H.js +0 -602
  76. package/dist/chunk-YNW2ZUUP.js +0 -247
  77. package/dist/groups-9Jm3peq3.d.ts +0 -2827
  78. package/dist/runtime/chunks/ADUMK6CR.js +0 -1
  79. package/dist/submission-input-D9EGH_yb.d.ts +0 -146
  80. package/dist/x-KFJD2x8y.d.ts +0 -331
@@ -7,22 +7,26 @@ import {
7
7
  discoverSignInWallets,
8
8
  discoverSolanaWallets,
9
9
  readSignInMethods,
10
- signInOptionsFrom,
10
+ signInOptionsFrom
11
+ } from "../chunk-UW5232GG.js";
12
+ import {
11
13
  telegramMiniAppInitData
12
- } from "../chunk-2FHNY52R.js";
13
- import "../chunk-VVRQQRMQ.js";
14
+ } from "../chunk-FWLQ5XCS.js";
15
+ import "../chunk-GKIFABGN.js";
14
16
  import {
15
17
  createRelayAction
16
- } from "../chunk-4OFH4BNX.js";
17
- import "../chunk-XQKUJL7H.js";
18
- import "../chunk-MJEJQH5A.js";
19
- import "../chunk-YNW2ZUUP.js";
18
+ } from "../chunk-Y322OTCH.js";
19
+ import "../chunk-6WCIWXUV.js";
20
+ import "../chunk-CICDIBOF.js";
21
+ import "../chunk-D26YNACF.js";
22
+ import "../chunk-GTDW453U.js";
23
+ import "../chunk-WSBYWVTZ.js";
20
24
  import "../chunk-KDR2VAJP.js";
21
- import "../chunk-6ZG7WNYX.js";
22
- import "../chunk-N7YOS4ZU.js";
25
+ import "../chunk-3PYYGFSB.js";
23
26
  import {
24
27
  sessionMember
25
- } from "../chunk-422J3QRW.js";
28
+ } from "../chunk-XJFYAXET.js";
29
+ import "../chunk-MK425RXJ.js";
26
30
  import {
27
31
  RelayError,
28
32
  RelayErrorCode,
@@ -30,7 +34,7 @@ import {
30
34
  clientError,
31
35
  isRelayError,
32
36
  isRequestError
33
- } from "../chunk-GBSDAD3N.js";
37
+ } from "../chunk-K2KS3JLY.js";
34
38
 
35
39
  // src/react/context.ts
36
40
  import { createContext, useContext } from "react";
@@ -52,12 +56,14 @@ var relayKeys = {
52
56
  experience: ["experience"],
53
57
  /** `useMe`. */
54
58
  me: ["me"],
55
- /** `useAccounts`. */
59
+ /** `useAccounts`, `useAccount`, `useTelegramAccount`, `useCreatorAccounts`. */
56
60
  accounts: ["accounts"],
57
61
  /** `useWallets`. */
58
62
  wallets: ["wallets"],
59
63
  /** `useMyProfile`, `useProfile`, `useProfileCompletions`, `useProfileReferral`. */
60
64
  profiles: ["profiles"],
65
+ /** `useConsent`. */
66
+ consent: ["consent"],
61
67
  /** `useLeaderboard`, `useLeaderboardPlacement`, `useLeaderboardHistory`. */
62
68
  leaderboards: ["leaderboards"],
63
69
  /** `useReferralSummary`. */
@@ -624,8 +630,11 @@ var ActivityFeed = class {
624
630
  };
625
631
 
626
632
  // src/react/role-delivery.ts
633
+ function grantsRole({ action }) {
634
+ return typeof action !== "string" || action === "grant-role";
635
+ }
627
636
  function sanitizeDeliveries(deliveries) {
628
- return deliveries.map(({ quest, status, revokedAt, reconciliation }) => ({
637
+ return deliveries.filter(grantsRole).map(({ quest, status, revokedAt, reconciliation }) => ({
629
638
  quest,
630
639
  status: reconciliation ? reconciliation.status === "granted" ? "delivered" : reconciliation.status : revokedAt ? "revoked" : status
631
640
  }));
@@ -1055,6 +1064,40 @@ var TEST_STATE_CHANGED_EVENT = "domino:test-state-changed";
1055
1064
  function isVisible() {
1056
1065
  return typeof document === "undefined" || document.visibilityState !== "hidden";
1057
1066
  }
1067
+ var WALLET_SIGN_IN_KEY = "domino:wallet-sign-in";
1068
+ function readWalletSignIn() {
1069
+ try {
1070
+ const value = JSON.parse(
1071
+ window.sessionStorage.getItem(WALLET_SIGN_IN_KEY) ?? "null"
1072
+ );
1073
+ return typeof value?.session === "string" && typeof value.address === "string" && typeof value.chain === "string" ? value : null;
1074
+ } catch {
1075
+ return null;
1076
+ }
1077
+ }
1078
+ function writeWalletSignIn(value) {
1079
+ try {
1080
+ if (value) {
1081
+ window.sessionStorage.setItem(WALLET_SIGN_IN_KEY, JSON.stringify(value));
1082
+ } else {
1083
+ window.sessionStorage.removeItem(WALLET_SIGN_IN_KEY);
1084
+ }
1085
+ } catch {
1086
+ }
1087
+ }
1088
+ function reportingSigner(signer, signed) {
1089
+ return {
1090
+ chain: signer.chain,
1091
+ network: signer.network,
1092
+ name: signer.name,
1093
+ address: () => signer.address(),
1094
+ ...signer.chainId ? { chainId: () => signer.chainId() } : {},
1095
+ sign: (message, address) => {
1096
+ signed(address);
1097
+ return signer.sign(message, address);
1098
+ }
1099
+ };
1100
+ }
1058
1101
  var ACTIVITY_MS = 5e3;
1059
1102
  var SNAPSHOT_MS = 3e4;
1060
1103
  var FOCUS_GAP_MS = 2e3;
@@ -1089,6 +1132,9 @@ var RelayStore = class {
1089
1132
  /** The first cache of this mount: a public read's `initialData` seeds only it. */
1090
1133
  #firstCache = null;
1091
1134
  #settled = null;
1135
+ /** The wallet the current session signed in with, while the store follows its accounts. */
1136
+ #wallet = null;
1137
+ #walletSigningOut = false;
1092
1138
  constructor(client, polling = {}) {
1093
1139
  this.client = client;
1094
1140
  this.#polling = {
@@ -1167,6 +1213,7 @@ var RelayStore = class {
1167
1213
  this.#observer?.dispose();
1168
1214
  this.#observer = null;
1169
1215
  this.#stopFeed();
1216
+ this.#stopWallet(false);
1170
1217
  this.#sessionRead?.abort();
1171
1218
  this.#sessionRead = null;
1172
1219
  this.#sessionVersion++;
@@ -1226,6 +1273,32 @@ var RelayStore = class {
1226
1273
  this.#setSession({ status: "ready", data: null, error: null });
1227
1274
  this.#emit();
1228
1275
  }
1276
+ /**
1277
+ * Signs in with a wallet through the client, then follows the wallet's accounts when the signer
1278
+ * can watch them: a switch to another account, or an empty list, signs out.
1279
+ */
1280
+ async signInWithWallet(signer) {
1281
+ if (!signer.watchAccounts) {
1282
+ await this.client.auth.wallet.signIn(signer);
1283
+ return;
1284
+ }
1285
+ let address;
1286
+ const session = await this.client.auth.wallet.signIn(
1287
+ reportingSigner(signer, (signed) => {
1288
+ address = signed;
1289
+ })
1290
+ );
1291
+ if (!this.#mounted || !address || typeof session?.id !== "string") {
1292
+ return;
1293
+ }
1294
+ writeWalletSignIn({
1295
+ session: session.id,
1296
+ chain: signer.chain,
1297
+ address,
1298
+ ...signer.name ? { name: signer.name } : {}
1299
+ });
1300
+ this.#watchWallet(signer, address, session.id);
1301
+ }
1229
1302
  /**
1230
1303
  * Reads the experience again. With a feed, it is read first: the events it finds read the
1231
1304
  * experience and whatever else they changed, so a change the participant just made shows its
@@ -1319,6 +1392,63 @@ var RelayStore = class {
1319
1392
  this.#feed = null;
1320
1393
  feed?.dispose();
1321
1394
  }
1395
+ /** Signs out when the wallet `session` signed in with reports another account, or none. */
1396
+ #watchWallet(signer, address, session) {
1397
+ this.#stopWallet(false);
1398
+ const signedIn = address.toLowerCase();
1399
+ const watch = { session, stop: () => {
1400
+ } };
1401
+ this.#wallet = watch;
1402
+ watch.stop = signer.watchAccounts((accounts) => {
1403
+ if (this.#wallet === watch && accounts[0]?.toLowerCase() !== signedIn) {
1404
+ void this.#walletSwitched();
1405
+ }
1406
+ });
1407
+ }
1408
+ async #walletSwitched() {
1409
+ if (this.#walletSigningOut) {
1410
+ return;
1411
+ }
1412
+ this.#walletSigningOut = true;
1413
+ try {
1414
+ await this.signOut();
1415
+ } catch {
1416
+ } finally {
1417
+ this.#walletSigningOut = false;
1418
+ }
1419
+ }
1420
+ #stopWallet(forget) {
1421
+ const watch = this.#wallet;
1422
+ this.#wallet = null;
1423
+ watch?.stop();
1424
+ if (forget) {
1425
+ writeWalletSignIn(null);
1426
+ }
1427
+ }
1428
+ /** Follows the wallet a session restored after a reload signed in with, if it is installed. */
1429
+ async #restoreWallet(record) {
1430
+ const wallets = await discoverEvmWallets();
1431
+ const wallet = record.name ? wallets.find((candidate) => candidate.name === record.name) : wallets.length === 1 ? wallets[0] : void 0;
1432
+ if (wallet?.signer.watchAccounts && this.#mounted && !this.#wallet && this.#scope?.session?.id === record.session) {
1433
+ this.#watchWallet(wallet.signer, record.address, record.session);
1434
+ }
1435
+ }
1436
+ /** Stops following a wallet once its session ended; resumes after a reload or remount. */
1437
+ #syncWallet(session) {
1438
+ const id = session?.id ?? null;
1439
+ if (this.#wallet && this.#wallet.session !== id) {
1440
+ this.#stopWallet(true);
1441
+ }
1442
+ if (this.#wallet || !id) {
1443
+ return;
1444
+ }
1445
+ const record = readWalletSignIn();
1446
+ if (record?.session === id && record.chain === "eip155") {
1447
+ void this.#restoreWallet(record);
1448
+ } else if (record) {
1449
+ writeWalletSignIn(null);
1450
+ }
1451
+ }
1322
1452
  /** Reads again, once each, the queries the events change. */
1323
1453
  #applyEvents(events) {
1324
1454
  const keys = /* @__PURE__ */ new Map();
@@ -1457,6 +1587,9 @@ var RelayStore = class {
1457
1587
  };
1458
1588
  this.#firstCache ??= this.#scope.cache;
1459
1589
  this.#syncFeed();
1590
+ if (next.status === "ready") {
1591
+ this.#syncWallet(session);
1592
+ }
1460
1593
  }
1461
1594
  #deriveExperience() {
1462
1595
  const session = this.#session;
@@ -1788,7 +1921,7 @@ function useBadgeCatalog() {
1788
1921
  const relay = useRelay();
1789
1922
  return useRelayQuery(
1790
1923
  [...relayKeys.badges, "catalog"],
1791
- (options) => relay.badges.list(options)
1924
+ async (options) => (await relay.badges.catalog(options)).items
1792
1925
  );
1793
1926
  }
1794
1927
  function useBadges() {
@@ -2444,7 +2577,8 @@ function useMe() {
2444
2577
  return useMemberQuery(relayKeys.me, (options) => relay.me.get(options));
2445
2578
  }
2446
2579
  function useSignIn() {
2447
- const relay = useRelay();
2580
+ const store = useStore();
2581
+ const relay = store.client;
2448
2582
  const [challenge, setChallengeState] = useState7(null);
2449
2583
  const latest = useRef6(null);
2450
2584
  const [busy, setBusy] = useState7(false);
@@ -2519,10 +2653,10 @@ function useSignIn() {
2519
2653
  );
2520
2654
  const withWallet = useCallback7(
2521
2655
  (signer) => run(async () => {
2522
- await relay.auth.wallet.signIn(signer);
2656
+ await store.signInWithWallet(signer);
2523
2657
  setChallenge(null);
2524
2658
  }, "Couldn't sign in with this wallet. Try again."),
2525
- [relay, run, setChallenge]
2659
+ [store, run, setChallenge]
2526
2660
  );
2527
2661
  const codeSent = challenge !== null;
2528
2662
  return useMemo7(
@@ -2539,14 +2673,26 @@ function useSignIn() {
2539
2673
  sendCode,
2540
2674
  verifyCode,
2541
2675
  startOver,
2676
+ /**
2677
+ * Leaves for the provider's consent screen: any of `providers().signInProviders`, Telegram
2678
+ * included.
2679
+ */
2542
2680
  withProvider,
2543
- /** Signs in, or signs up, with a wallet; the wallet asks the participant to sign a message. */
2681
+ /**
2682
+ * Signs in, or signs up, with a wallet; the wallet asks the participant to sign a message. A
2683
+ * wallet that can watch its accounts, such as an EVM browser wallet, is followed: switching
2684
+ * to another account in it, or locking it, signs out.
2685
+ */
2544
2686
  withWallet,
2545
- /** Leaves for Telegram Login, where the platform configured it. */
2687
+ /**
2688
+ * Leaves for Telegram Login, where the platform configured it.
2689
+ *
2690
+ * @deprecated Use `withProvider("telegram")`. Removed in 2.0.0.
2691
+ */
2546
2692
  withTelegram,
2547
2693
  /**
2548
2694
  * Signs in, or signs up, inside a Telegram Mini App the project enabled, with its launch data
2549
- * (`telegramMiniAppInitData()`).
2695
+ * (`telegramMiniAppInitData()` from `@domino-sdk/relay/telegram`).
2550
2696
  */
2551
2697
  withTelegramMiniApp
2552
2698
  }),
@@ -2610,7 +2756,7 @@ function useSignInOptions(input = {}) {
2610
2756
  if (!methods) {
2611
2757
  return null;
2612
2758
  }
2613
- if (!wallets && methods.providers.length === 0 && !methods.email && !methods.telegram?.login) {
2759
+ if (!wallets && methods.providers.length === 0 && !methods.signInProviders?.length && !methods.email && !methods.telegram?.login) {
2614
2760
  return null;
2615
2761
  }
2616
2762
  return signInOptionsFrom(methods, wallets ?? [], {
@@ -2618,6 +2764,7 @@ function useSignInOptions(input = {}) {
2618
2764
  walletsPending: !wallets,
2619
2765
  actions: {
2620
2766
  oauth: withProvider,
2767
+ provider: withProvider,
2621
2768
  sendCode,
2622
2769
  verifyCode,
2623
2770
  wallet: withWallet,
@@ -2638,6 +2785,7 @@ function useSignInOptions(input = {}) {
2638
2785
  return useMemo7(
2639
2786
  () => ({
2640
2787
  options: built?.options ?? null,
2788
+ signInProviders: built?.signInProviders ?? null,
2641
2789
  unavailable: built?.unavailable ?? NONE_UNAVAILABLE,
2642
2790
  telegram: built?.telegram ?? null,
2643
2791
  methodsError,
@@ -2653,7 +2801,7 @@ function useSignInOptions(input = {}) {
2653
2801
  }
2654
2802
 
2655
2803
  // src/react/accounts.ts
2656
- import { useMemo as useMemo8 } from "react";
2804
+ import { useCallback as useCallback8, useMemo as useMemo8 } from "react";
2657
2805
  function isConnected(accounts, provider) {
2658
2806
  return Boolean(
2659
2807
  accounts?.some(
@@ -2717,6 +2865,67 @@ function useAccounts() {
2717
2865
  ]
2718
2866
  );
2719
2867
  }
2868
+ function useAccount(provider) {
2869
+ const relay = useRelay();
2870
+ const invalidate = useInvalidate();
2871
+ const session = useScopeSession();
2872
+ const select = useCallback8(
2873
+ (accounts) => accounts.find((account2) => account2.provider === provider) ?? null,
2874
+ [provider]
2875
+ );
2876
+ const query = useMemberQuery(
2877
+ [...relayKeys.accounts, "sign-in"],
2878
+ (options) => relay.auth.signInAccounts(options),
2879
+ { refetchOnFocus: true, select }
2880
+ );
2881
+ const { isPending, actionError: actionError2, resetAction, run, retry, settle } = useAction();
2882
+ const actions = useMemo8(
2883
+ () => ({
2884
+ connect: () => run(async () => {
2885
+ const { url } = await relay.auth.start(
2886
+ { provider, mode: "connect" },
2887
+ { session }
2888
+ );
2889
+ window.location.assign(url);
2890
+ }),
2891
+ disconnect: () => run(async () => {
2892
+ await relay.auth.disconnect(provider, { session });
2893
+ void invalidate([
2894
+ relayKeys.accounts,
2895
+ relayKeys.experience,
2896
+ relayKeys.profiles
2897
+ ]);
2898
+ })
2899
+ }),
2900
+ [relay, invalidate, session, run, provider]
2901
+ );
2902
+ const account = query.data;
2903
+ return useMemo8(
2904
+ () => ({
2905
+ ...query,
2906
+ isPending,
2907
+ actionError: actionError2,
2908
+ resetAction,
2909
+ retry,
2910
+ settle,
2911
+ /** True when the account can be used to verify quests right now. */
2912
+ isConnected: Boolean(
2913
+ account?.configured && account.status === "connected"
2914
+ ),
2915
+ ...actions
2916
+ }),
2917
+ [
2918
+ query,
2919
+ isPending,
2920
+ actionError2,
2921
+ resetAction,
2922
+ retry,
2923
+ settle,
2924
+ account,
2925
+ actions
2926
+ ]
2927
+ );
2928
+ }
2720
2929
  function useTelegramAccount() {
2721
2930
  const relay = useRelay();
2722
2931
  const invalidate = useInvalidate();
@@ -2920,8 +3129,54 @@ function useProfileCompletions(profile, options = {}) {
2920
3129
  );
2921
3130
  }
2922
3131
 
3132
+ // src/react/consent.ts
3133
+ import { useMemo as useMemo10 } from "react";
3134
+ function useConsent() {
3135
+ const relay = useRelay();
3136
+ const store = useStore();
3137
+ const session = useScopeSession();
3138
+ const query = useMemberQuery(
3139
+ relayKeys.consent,
3140
+ (options) => relay.consent.get(options)
3141
+ );
3142
+ const { isPending, actionError: actionError2, resetAction, run, retry, settle } = useAction();
3143
+ const actions = useMemo10(() => {
3144
+ const change = (channel, granted, wording) => run(async (actionId) => {
3145
+ const cache = store.scope?.cache;
3146
+ await relay.consent.set(
3147
+ {
3148
+ actionId,
3149
+ channel,
3150
+ granted,
3151
+ ...wording === void 0 ? {} : { wording }
3152
+ },
3153
+ { session }
3154
+ );
3155
+ void cache?.invalidate([relayKeys.consent]);
3156
+ });
3157
+ return {
3158
+ /** Records the member's opt-in on `channel`, with the wording they saw. */
3159
+ grant: (channel, wording) => change(channel, true, wording),
3160
+ /** Records the member's opt-out on `channel`, with the wording they saw if there was any. */
3161
+ withdraw: (channel, wording) => change(channel, false, wording)
3162
+ };
3163
+ }, [relay, store, session, run]);
3164
+ return useMemo10(
3165
+ () => ({
3166
+ ...query,
3167
+ isPending,
3168
+ actionError: actionError2,
3169
+ resetAction,
3170
+ retry,
3171
+ settle,
3172
+ ...actions
3173
+ }),
3174
+ [query, isPending, actionError2, resetAction, retry, settle, actions]
3175
+ );
3176
+ }
3177
+
2923
3178
  // src/react/referrals.ts
2924
- import { useCallback as useCallback8, useEffect as useEffect7, useMemo as useMemo10, useRef as useRef7, useState as useState8 } from "react";
3179
+ import { useCallback as useCallback9, useEffect as useEffect7, useMemo as useMemo11, useRef as useRef7, useState as useState8 } from "react";
2925
3180
  var PENDING = "domino:pending-referral";
2926
3181
  var CODE = /^[a-zA-Z0-9_-]{1,100}$/;
2927
3182
  function captureReferralCode(param = "ref") {
@@ -2971,7 +3226,7 @@ function useInvitation(param = "ref") {
2971
3226
  action: createRelayAction()
2972
3227
  };
2973
3228
  }
2974
- const accept = useCallback8(
3229
+ const accept = useCallback9(
2975
3230
  async (code) => {
2976
3231
  const owner = pending.current;
2977
3232
  if (owner.action.busy) {
@@ -3016,7 +3271,7 @@ function useInvitation(param = "ref") {
3016
3271
  void accept(state.code);
3017
3272
  }
3018
3273
  }, [member, state, accept]);
3019
- return useMemo10(() => ({ invitation: state, accept }), [state, accept]);
3274
+ return useMemo11(() => ({ invitation: state, accept }), [state, accept]);
3020
3275
  }
3021
3276
  function useReferralSummary(options = {}) {
3022
3277
  const relay = useRelay();
@@ -3026,7 +3281,7 @@ function useReferralSummary(options = {}) {
3026
3281
  (request) => relay.referrals.summary(request),
3027
3282
  { intervalMs }
3028
3283
  );
3029
- return useMemo10(() => {
3284
+ return useMemo11(() => {
3030
3285
  let link = null;
3031
3286
  if (query.data && typeof window !== "undefined") {
3032
3287
  const url = new URL(path, window.location.origin);
@@ -3093,7 +3348,7 @@ function useQuestOutcomes(query = {}) {
3093
3348
  }
3094
3349
 
3095
3350
  // src/react/offers.ts
3096
- import { useCallback as useCallback9, useMemo as useMemo11 } from "react";
3351
+ import { useCallback as useCallback10, useMemo as useMemo12 } from "react";
3097
3352
  function useOffers() {
3098
3353
  const relay = useRelay();
3099
3354
  return useRelayQuery(
@@ -3108,11 +3363,11 @@ function useRedeemOffer() {
3108
3363
  { invalidates: [relayKeys.offers, relayKeys.balances] }
3109
3364
  );
3110
3365
  const { mutateAsync } = mutation;
3111
- const redeem = useCallback9(
3366
+ const redeem = useCallback10(
3112
3367
  (offer) => mutateAsync(offer).catch(() => null),
3113
3368
  [mutateAsync]
3114
3369
  );
3115
- return useMemo11(
3370
+ return useMemo12(
3116
3371
  () => ({ ...mutation, redeem, retry: replay, busy: mutation.isPending }),
3117
3372
  [mutation, redeem, replay]
3118
3373
  );
@@ -3152,11 +3407,13 @@ export {
3152
3407
  roleDeliveryLabel,
3153
3408
  roleDeliveryStatus,
3154
3409
  telegramMiniAppInitData,
3410
+ useAccount,
3155
3411
  useAccounts,
3156
3412
  useActivity,
3157
3413
  useBadgeCatalog,
3158
3414
  useBadges,
3159
3415
  useBalances,
3416
+ useConsent,
3160
3417
  useCreatorAccounts,
3161
3418
  useDeliveries,
3162
3419
  useEntitlements,
@@ -64,34 +64,4 @@ declare class RequestError extends Error {
64
64
  constructor(message: string, details: RequestErrorDetails);
65
65
  }
66
66
 
67
- /** SDK input convenience; the wire request always carries a key. */
68
- type OptionalActionId<T> = T extends {
69
- actionId: string;
70
- } ? Omit<T, "actionId"> & {
71
- actionId?: string;
72
- } : never;
73
- /** One logical write. Keep this object until its outcome is definite. */
74
- type RelayAction<T> = {
75
- /** The pending write's key, also available on its uncertain error as `operationId`. */
76
- readonly actionId: string | undefined;
77
- readonly busy: boolean;
78
- readonly error: RequestError | undefined;
79
- /**
80
- * Starts a write with a generated key. While an uncertain write is pending, replays its saved
81
- * callback instead of accepting a different write. Concurrent calls share one request.
82
- * Put refreshes and other follow-up work outside the callback.
83
- */
84
- run(task: (actionId: string) => Promise<T>): Promise<T>;
85
- /** Replays the exact pending callback and key, only when the error's recovery is `replay`. */
86
- retry(): Promise<T>;
87
- /** Acknowledge an authoritative, definite outcome after reconciliation. Refuses while busy. */
88
- settle(): boolean;
89
- };
90
- /**
91
- * Owns a mutation key across uncertain answers. A definite success or refusal ends the action;
92
- * the next `run` gets a new key. `reconcile` failures stay pending and cannot be replayed.
93
- * In-memory only: persist the key yourself if recovery must survive a reload or process restart.
94
- */
95
- declare function createRelayAction<T = unknown>(): RelayAction<T>;
96
-
97
- export { type OptionalActionId as O, type RelayAction as R, RequestError as a, type RequestErrorDetails as b, type RequestErrorKind as c, type RequestRecovery as d, createRelayAction as e, isRequestError as i };
67
+ export { RequestError as R, type RequestErrorDetails as a, type RequestErrorKind as b, type RequestRecovery as c, isRequestError as i };