@domino-sdk/relay 1.55.0 → 1.59.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 (65) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/dist/{accounts-DRPENuZe.d.ts → accounts-CVonEkdb.d.ts} +18 -7
  3. package/dist/{attempt-captures-CxxO7DeD.d.ts → attempt-captures-DBj-rxak.d.ts} +1 -1
  4. package/dist/authoring.d.ts +306 -72
  5. package/dist/authoring.js +264 -9
  6. package/dist/{automatic-outcomes-DxW_v5Wc.d.ts → automatic-outcomes-FS9okvBP.d.ts} +1 -1
  7. package/dist/avatar.d.ts +1 -2
  8. package/dist/browser.d.ts +8 -9
  9. package/dist/browser.js +10 -10
  10. package/dist/{capability-error-DSd8EMQC.d.ts → capability-error-DDJl0LY-.d.ts} +0 -6
  11. package/dist/{chunk-IZRITLVV.js → chunk-2LKGAL63.js} +2 -2
  12. package/dist/{chunk-GL43VQ5D.js → chunk-577DG2IT.js} +38 -8
  13. package/dist/{chunk-UY6KMLQG.js → chunk-6U5WWH3W.js} +141 -100
  14. package/dist/{chunk-YCOKTQ4E.js → chunk-AWWCEP7F.js} +1403 -882
  15. package/dist/{chunk-56DBFNR2.js → chunk-EQF4ID47.js} +1 -1
  16. package/dist/{chunk-YEVD4A5X.js → chunk-IBROKMFV.js} +2 -2
  17. package/dist/{chunk-XALIFNMD.js → chunk-KBCTII6C.js} +1 -1
  18. package/dist/{chunk-WHG5WE43.js → chunk-KYUQEZZA.js} +1 -1
  19. package/dist/{chunk-WUEQOKJH.js → chunk-LDLOB2UZ.js} +4 -4
  20. package/dist/{chunk-IUF7DW76.js → chunk-M2JQPDUX.js} +39 -9
  21. package/dist/{chunk-MLIXJPKL.js → chunk-MHPKEVEW.js} +1 -0
  22. package/dist/{chunk-TLK2MD4S.js → chunk-R4S6BFOH.js} +1 -1
  23. package/dist/{chunk-VFBQVY4X.js → chunk-TZJT5CRF.js} +1 -1
  24. package/dist/{chunk-C7QZ4UBB.js → chunk-UEMLYPKJ.js} +21 -5
  25. package/dist/{chunk-F6HECAXA.js → chunk-W42KMMH5.js} +140 -101
  26. package/dist/{chunk-WHMXXHPX.js → chunk-XGXDINGM.js} +16 -3
  27. package/dist/{chunk-SABMNPF2.js → chunk-YMWRLAAP.js} +1 -1
  28. package/dist/{chunk-YE3XYB2F.js → chunk-YRSU2X2P.js} +2 -2
  29. package/dist/{client-C4zUZKpj.d.ts → client-3b9HjSzZ.d.ts} +191 -117
  30. package/dist/{deployments-B32QS1CI.d.ts → deployments-BydFVj4Q.d.ts} +798 -235
  31. package/dist/{groups-O6onGPmC.d.ts → groups-CFuTfFqG.d.ts} +15 -9
  32. package/dist/index.d.ts +9 -10
  33. package/dist/index.js +9 -9
  34. package/dist/{integrations-C6_uUh-s.d.ts → integrations-DrbKQSTD.d.ts} +42 -22
  35. package/dist/internal.d.ts +10 -10
  36. package/dist/internal.js +9 -9
  37. package/dist/{offers-BMDNcvwB.d.ts → offers-DAfe1O3_.d.ts} +211 -2
  38. package/dist/{pages-BFloMpyQ.d.ts → pages-ChDVLrgR.d.ts} +95 -10
  39. package/dist/portal-proxy.js +4 -4
  40. package/dist/react/index.d.ts +149 -72
  41. package/dist/react/index.js +65 -10
  42. package/dist/runtime/authoring.js +1 -1
  43. package/dist/runtime/chunks/BG43KQ2T.js +1 -0
  44. package/dist/runtime/chunks/EWU4OKSY.js +62 -0
  45. package/dist/runtime/manifest.json +5 -5
  46. package/dist/runtime/schema.js +1 -1
  47. package/dist/runtime/zod.js +1 -1
  48. package/dist/{schema-C4m9RhCR.d.ts → schema-BA0nRRlt.d.ts} +184 -35
  49. package/dist/schema.d.ts +1265 -697
  50. package/dist/schema.js +96 -12
  51. package/dist/server/index.d.ts +10 -10
  52. package/dist/server/index.js +1644 -1105
  53. package/dist/{submission-input-BbdawqVy.d.ts → submission-input-DxQ6RnKo.d.ts} +2 -2
  54. package/dist/{telegram-browser-CwaxROAZ.d.ts → telegram-browser-o3OIxGrJ.d.ts} +3 -3
  55. package/dist/testing.d.ts +89 -9
  56. package/dist/testing.js +215 -10
  57. package/dist/{transport-CZJOW5Sr.d.ts → transport-D_Eqf78J.d.ts} +8592 -4384
  58. package/dist/wallet-B06zvDXp.d.ts +972 -0
  59. package/dist/{x-1czZFVUW.d.ts → x-C28SNifw.d.ts} +2 -2
  60. package/package.json +2 -2
  61. package/dist/profiles-BoOK03cR.d.ts +0 -299
  62. package/dist/runtime/chunks/IDOMZWRY.js +0 -40
  63. package/dist/runtime/chunks/WKATKZXE.js +0 -1
  64. package/dist/util.d-w9f9t3ua.d.ts +0 -5
  65. package/dist/wallet-Ac7OFpOr.d.ts +0 -228
package/CHANGELOG.md CHANGED
@@ -1,5 +1,90 @@
1
1
  # @domino-sdk/relay
2
2
 
3
+ ## 1.59.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1d5a195: `management.attempts.acceptAnyway({ attempt, reason })` (`POST /attempts/<id>/accept-anyway`, `review` permission) accepts a rejected attempt anyway, for any member, reversing a reviewer's or an evaluator's rejection. The acceptance pays as a reviewer's approval would, with the normal `completion.created` webhook; the rejection stays in the attempt's events beside a `staff-decision` with `decision: "accept-anyway"` and the reason, and the retry cooldown ends. Only the member's latest attempt on a quest that isn't archived qualifies (409 `attempt-superseded`, `quest-archived`), and a cap the acceptance would break refuses it instead of rejecting it again (409 `completion-cooldown`, `budget-exhausted`, `completion-revoked`, `already-completed`). `management.attempts.get` answers `supersededBy`, the member's newer attempt on the quest, or null. The CLI adds `domino attempts accept-anyway ATTEMPT --reason TEXT`.
8
+ - a0c77e4: Archiving or unarchiving a group, pausing or resuming a tracker, and changing the project's schedule state take an optional reason, which the audit log records: `management.groups.archive(group, { reason })` and `unarchive(group, { reason })`, `management.trackers.pause(reference, { actionId, reason })` and `resume`, and `management.schedules.setState(state, { reason })`. A reason is a trimmed string of 1–500 characters, like the other lifecycle reasons; leaving it out works as before. The CLI adds `--reason TEXT` to `domino groups archive|unarchive`, `domino trackers pause|resume` and `domino schedules pause|archive|resume`. Console asks for a reason in a dialog for each of these, and the project schedule menu no longer applies a state as soon as you pick it.
9
+ - 424863f: Operators can restore an entitlement they voided. `management.entitlements.restore(entitlement, { revision, reason })` (`POST /management/v1/entitlements/<id>/restore`, `review` permission) and `domino entitlements restore <id> --revision <n> --reason <text>` make a `void` entitlement `available` again at the tier an accepted completion still earns, and bring back any referral review the void settled. Restoring is refused with 409 `entitlement-status` when a completion revocation voided the entitlement or no accepted completion still earns it (the body names the `completion` to restore instead), when canceling an offer redemption voided it, or when a referral reward was voided before voids kept their reviews. Console Rewards and member detail offer **Restore reward** on a voided reward, and Audit history lists each restore with its reason.
10
+ - 790aa5d: Operators can restore a completion they revoked by mistake. `management.completions.restore({ completion, reason })` (`POST /management/v1/completions/<id>/restore`, `review` permission) and `domino completions restore <completion> --reason <text>` re-apply what the revocation recorded, not a fresh reward evaluation: the points it reversed are awarded again (points it could not reverse are not), its badges, group memberships, tiered rewards, Discord role grants, referral qualifications and streak milestone come back, and budgets stay spent. The result (`CompletionRestoration`) lists what came back. Restoring is refused with 409 `completion-not-revoked` when the completion isn't revoked, and with 409 `occurrence-taken` (naming the `completion` that holds it) when the revocation freed the occurrence and the member completed it again. `members.get(id).revokedCompletions` lists up to 25 revoked completions, each with its revoke's reason and result. Console member detail and attempt detail offer **Restore completion**, and the attempt history and Audit history show the restore beside the revoke.
11
+ - 850a252: `settlementPayoutCsv(exported)` turns the result of `management.leaderboards.settlementExport(id)` into the payout list as CSV, with the columns `member,score,rank,share,amount,unit,wallets`. `domino leaderboard-settlements export` now prints it through this helper, unchanged, and Console's prize settlement panel offers **Download payout list (CSV)** for any pool that is not points, with the same content.
12
+ - 7ac13ef: Solana transactions from `ctx.wallet.transactions()` now carry `signer`: whether the linked wallet signed the transaction. It is `false` for a transfer someone else sent into the wallet, and for results captured before it existed. Check it before rewarding an action. The new `solana-action` snippet completes a quest once per transaction a linked wallet signed that called your program, optionally receiving at least an amount of a token.
13
+ - 5b94440: Anchor instruction decoding for `ctx.wallet.transactions()`. Saving a `settings.solanaProgram()` setting now stores the program's Anchor IDL (legacy or 0.30+), read from its on-chain IDL account, in the published release's new optional `solanaIdls` (`SolanaProgramIdl`: `{ program, source, idl }`, by setting key). For a program without an on-chain IDL, an operator pastes one in Console or sends the new optional `solanaIdls: { [settingKey]: idl | null }` with `quests.updateSettings()` (`anchorIdlSchema`, `AnchorIdl`). With an IDL, each transaction gains optional `instructions`: the program's top-level and inner instructions in call order, decoded as `{ name, args, accounts }` (`WalletInstruction`). An instruction the IDL does not describe is skipped. The new `instruction(tx, name)` helper in `@domino-sdk/relay/authoring` returns the first matching instruction's args, or `null`. The testing kit's `facts.wallet.transactions` accepts `instructions`.
14
+ - 95cb8d8: On-chain action checks on Solana. `ctx.wallet.transactions({ program, since, afterActivation?, mint?, address? })` reads the successful, finalized transactions of the member's linked Solana wallets since `since` that invoked `program` in a top-level or inner instruction, oldest first. It returns `{ program, chain, mint, since, at, complete, transactions: [{ wallet, signature, slot, timestamp, programs, balanceChanges: [{ mint, delta }] }], observedAt }` (`WalletTransactions`, `WalletTransaction`, `WalletBalanceChange`, `walletTransactionsSchema`), with `mint` `"SOL"` for lamports (rent included, the fee the wallet paid left out) and `delta` a signed integer string, or null when the member has no linked Solana wallet, and follows `ctx.wallet.balance()`'s capture, `author-error` and `provider-unavailable` rules. With `mint`, only each wallet's associated token account for that mint is read. `since` may be at most 30 days before the evaluation (`maxWalletTransactionLookback`); each wallet's read fetches at most 1,000 transactions (`maxWalletTransactions`), and a wallet with more returns its newest ones with `complete: false` instead of throwing. `WalletReader.transactions` is optional in the type so that existing test doubles compile; Relay supplies it to every evaluation.
15
+
16
+ The program comes from the new `settings.solanaProgram({ label, default })` setting, a base58 address (`SolanaProgram`, `isSolanaProgram`) stored as a text setting with `picker: "solana-program"`. Publication, Console settings edits and unarchiving check that the account exists on Solana mainnet and is executable.
17
+
18
+ New pure helpers in `@domino-sdk/relay/authoring` read one transaction: `received(tx, mint)` and `spent(tx, mint)` return the wallet's gain or loss as an integer string, or `"0"`; `swapped(tx, { into?, from? })` checks that one mint went down and a different one went up; `invoked(tx, program)`. The testing kit answers `ctx.wallet.transactions()` from `facts.wallet.transactions`.
19
+
20
+ ### Patch Changes
21
+
22
+ - aaa07ad: The SDK and CLI depend on Zod 4.6.5, whose schemas keep their methods on a shared prototype instead of binding about 7 KB of them to every schema instance. Importing the SDK takes far less memory: a Relay backend process that loads the server entry starts with about half the heap. Quest `settings.datetime()` values, member-import times and X post `createdAt` values (including hand-written testing fixtures) still accept minute-precision instants such as `2026-11-01T00:00Z`, which Zod 4.6 alone rejects. An X post read without a `media` field still gives an empty list.
23
+
24
+ One tracker data schema change after a rebuild: a field declared as `z.number().min(0).int()` now stores `minimum: 0`, so Relay refuses negative values at ingestion that the app's own schema already refused. Zod 4.3 stored the safe-integer minimum for that order of checks.
25
+
26
+ ## 1.58.0
27
+
28
+ ### Minor Changes
29
+
30
+ - 321763b: `management.discordRoles.list()` lists every Discord role the project's reward deliveries have granted in the environment, with the quests that requested it and its deliveries counted by status (`pending`, `delivered`, `failed`). It reads the whole delivery history, so a role granted only before the newest page of `management.rewardDeliveries` still appears. The response schema is `discordRoleRewardsSchema`.
31
+
32
+ ### Patch Changes
33
+
34
+ - a2318dd: `stagingPathSchema` refuses paths with control characters and accepts only a path that resolves on the staging host. Browsers drop tab and newline from a URL, so a path such as `/<tab>/example.com` used to pass and open another site after a staging sign-in.
35
+
36
+ ## 1.57.0
37
+
38
+ ### Minor Changes
39
+
40
+ - 7012d1c: Contract state and Cosmos staking reads in quest evaluators.
41
+
42
+ `ctx.wallet.call({ call, args?, address? })` calls one `view` or `pure` EVM contract function once per linked EVM wallet, every call at one block, through dRPC on the chains `management.walletBalanceChains()` lists: state a contract keeps per address, such as `stakedOf(address)`, `getVotes(address)` or `userInfo(uint256, address)`. `{ wallet: true }` in `args` stands for each wallet's address. It returns `{ call, chain, contract, returns, total, wallets: [{ address, value }], at, observedAt }` (`WalletCall`, `walletCallSchema`), with integers as decimal strings and `total` their sum (null for `bool` and `address` returns), or null when the member has no linked EVM wallet. A revert is an `author-error` carrying the contract's reason. The call comes from the new `settings.contractCall({ label, default })` setting (`picker: "contract-call"`): the contract's CAIP-10 ID and a human-readable signature, such as `eip155:8453:0x… function stakedOf(address) view returns (uint256)` (`ContractCall`, `isContractCall`, `parseContractCall`, `parseContractFunction`). Only `view` or `pure` functions with elementary parameters that return one `uint`, `int`, `bool` or `address` are accepted; publication, Console settings edits and unarchiving also check the chain.
43
+
44
+ `ctx.wallet.delegations({ chain, validator?, address? })` reads the native staking delegations of the member's wallets linked on a Cosmos SDK chain Relay lists, at one block, in base units of the chain's staking denomination: `{ chain, denom, validator, total, wallets, validators, at, observedAt }` (`WalletDelegations`, `walletDelegationsSchema`), optionally only to one validator, or null when the member has no wallet on that chain.
45
+
46
+ Both follow `ctx.wallet.balance()`'s capture, `author-error` and `provider-unavailable` rules. `WalletReader.call` and `WalletReader.delegations` are optional in the type so that existing test doubles compile; Relay supplies them to every evaluation, and the testing kit answers them from `facts.wallet.call` and `facts.wallet.delegations`. New `contract-state` and `cosmos-staker` snippets accept members whose view call reaches a minimum, or who delegate at least a minimum, optionally to a configured validator.
47
+
48
+ - 59a01d8: On-chain action checks on EVM chains. `ctx.wallet.events({ event, account, since, afterActivation?, where?, address? })` reads the events of one contract whose indexed address argument `account` is one of the member's linked EVM wallets, from `since` to the chain's finalized block (its safe block on a chain without finality), through dRPC `eth_getLogs` on the chains `management.walletBalanceChains()` lists. It returns `{ event, chain, contract, since, at, finality, logs: [{ wallet, block, timestamp, tx, logIndex, args }], observedAt }` (`WalletEvents`, `walletEventsSchema`) with decoded arguments, or null when the member has no linked EVM wallet, and follows `ctx.wallet.balance()`'s capture, `author-error` and `provider-unavailable` rules. `where` holds equality or `{ gte }` conditions on other arguments (`WalletEventCondition`); `afterActivation` skips events before the quest's activation. `since` may be at most 30 days before the evaluation (`maxWalletEventLookback`), and a read over more than 3,000,000 blocks or 1,000 logs (`maxWalletEventLogs`) throws `author-error`. `WalletReader.events` is optional in the type so that existing test doubles compile; Relay supplies it to every evaluation.
49
+
50
+ The event comes from the new `settings.contractEvent({ label, default })` setting: a CAIP-10 contract, a space and the event's Solidity signature with argument names and `indexed` markers, such as `eip155:8453:0x… Transfer(address indexed from, address indexed to, uint256 value)` (`ContractEvent`, `isContractEvent`, `parseContractEvent`, `ContractEventParts`), stored as a text setting with `picker: "contract-event"`. An event without an indexed address argument is refused. Publication, Console settings edits and unarchiving also check that the chain reports a finalized or safe block and that the address holds a contract.
51
+
52
+ The testing kit answers `ctx.wallet.events()` from `facts.wallet.events`. A new `onchain-action` snippet rewards each new matching event since the later of the quest's activation and the wallet's link, with an optional minimum amount, keyed on `chain:tx:logIndex`.
53
+
54
+ - 956b721: NFT holding checks on EVM chains and Solana. `ctx.wallet.nfts({ collection, address? })` counts the NFTs of one collection the member's linked wallets of its family hold: on EVM, an ERC-721 contract's `balanceOf(owner)`, or one ERC-1155 token ID's `balanceOf(owner, id)`, through dRPC on the chains `management.walletBalanceChains()` lists; on Solana mainnet, the NFTs whose Metaplex metadata names the collection with `verified: true` (SPL Token and Token-2022 accounts holding exactly 1 of a 0-decimal, supply-1 mint; compressed NFTs and Metaplex Core assets are not counted). It returns `{ collection, chain, standard, total, wallets: [{ address, count }], at, observedAt }` (`WalletNfts`, `walletNftsSchema`; `standard` is `"erc721"`, `"erc1155"` or `"metaplex"`), or null when the member has no linked wallet of that family, and follows `ctx.wallet.balance()`'s capture, `author-error` and `provider-unavailable` rules. `WalletReader.nfts` is optional in the type so that existing test doubles compile; Relay supplies it to every evaluation.
55
+
56
+ The collection comes from the new `settings.nft({ label, default })` setting, a CAIP-19 asset type such as `eip155:1/erc721:0x…`, `eip155:8453/erc1155:0x…/1` or `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/nft:<collection mint>` (`NftCollection`, `isNftCollection`, `parseNftCollection`, `NftCollectionParts`), stored as a text setting with `picker: "nft"`. Publication and Console settings edits check it: an EVM chain and that the contract reports the standard through ERC-165 `supportsInterface`, so a token contract or the wrong standard is refused when it is set; a Solana mint must be a Metaplex collection NFT, so a fungible mint, a mint without Metaplex metadata, a print edition or a member NFT is refused. Unarchiving checks it too, and a platform without its dRPC key refuses every EVM collection. `ctx.wallet.balance()` pointed at an ERC-721 or ERC-1155 contract now throws `author-error` naming `ctx.wallet.nfts()` instead of reading a token count; it asks ERC-165 alongside `decimals()` on every token read.
57
+
58
+ The testing kit answers `ctx.wallet.nfts()` from `facts.wallet.nfts`. A new `nft-holder` snippet accepts members whose linked wallets hold at least one NFT from the configured collection, on EVM or Solana.
59
+
60
+ - 1770ada: A seventh starter, `loyalty`: members join a campaign, earn points from its steps, join a members' group through a quest's group membership reward, and spend points on offers, one of them limited to the group with `inGroup`. Console offers it and `domino create --template loyalty` creates it.
61
+
62
+ Starters are now an open list, so adding one no longer changes the SDK's types. `starters` lists every starter as a `Starter` with a plain string `id`, `offeredStarterSchema` checks an ID against it, and `projectCreateInputSchema` and `repositoryCreateSchema` accept any offered starter; `management.createProject` uses the first. `starterTemplates`, `StarterTemplate`, `StarterId`, `starterIdSchema`, `projectInputSchema` and `createRepositorySchema` are deprecated: they keep the first six starters and are removed in 2.0.0. To upgrade, replace `starterTemplates` with `starters` and `starterIdSchema` with `offeredStarterSchema`, and type a starter ID as `string`.
63
+
64
+ - cec850f: Create and change a tracker of every managed source without a deployment, not only X search. `management.trackers.create` and `management.trackers.update` (`POST /trackers`, `POST /trackers/:tracker/update`) take a `source`: `{ kind: "x-search", query }`, `{ kind: "discord-messages", text? }`, `{ kind: "discord-reactions" }`, `{ kind: "telegram-messages" }`, `{ kind: "telegram-reactions" }`, `{ kind: "youtube-shorts" }` or `{ kind: "tiktok-videos" }`. Each is stored as the source its builder makes, such as `telegram.reactions()`, so quests read a data tracker as they read the same tracker in code. `query` alone still creates an X search tracker; create takes exactly one of `query` or `source`. An update's `source` replaces the source's settings but never its kind, which is refused with 422 `validation-failed`. Turning Discord message text off erases the text already stored. `managedTrackerCreateSchema` validates the new input, while `trackerCreateSchema` keeps its X-only shape. `managedTrackerSource(source)` reads a published source by these names, and `managedTrackerSourceKinds` lists them.
65
+
66
+ `domino trackers create KEY --source <kind>` creates one from the CLI, with `--text on` for Discord messages; `domino trackers update TRACKER --text on|off` turns message text on or off. Console **Trackers → New tracker** offers every source.
67
+
68
+ - 94726d8: Organization automation keys (`dak_`): a credential for CI and headless coding agents that no person owns. An organization administrator creates one in Console Settings → API keys for every project or a chosen list, with chosen permissions and an optional permission to create projects. It works as `RELAY_MANAGEMENT_TOKEN`, with `domino login --token-stdin` and the Git credential helper, in the test environment only: live writes, administration and minting other credentials are refused.
69
+
70
+ The management client adds `automationKeys` (`list`, `create`, `addSecret`, `revokeSecret`, `revoke`) with `automationKeyInputSchema`, `automationKeySchema`, `issuedAutomationKeySchema` and `automationKeyPermissionSchema`. `accessSchema` gains an optional `credential` that `/access` and `domino whoami --json` fill for an automation key with its kind and scope.
71
+
72
+ - 6d9f0de: `telegram.messages()` is a tracker source of the messages members post in the project's connected Telegram groups and supergroups, one record per message with the poster's Telegram account as `author`. `data` is `TelegramMessageData`: `chatId`, `chatType`, `messageId`, `replyToMessageId` and `threadId`, never the text. Bots', service and channel messages are not recorded. In SDK 1.x it is a custom source on the reserved namespace `telegram-messages`, which Relay alone writes. The new `telegram-contribution` snippet rewards posting once per member per day.
73
+ - 8d11f64: `wallet.balances({ chain, token })` is a tracker source of daily balance samples that Relay writes itself. Once per project-calendar day, at a time members can't predict, Relay reads one token's balance in every wallet linked by a member who joined the project, every wallet of a run at one pinned EVM block or Cosmos height (on Solana, every read must reach the run's pinned slot). `chain` and `token` are those of `ctx.wallet.balance()`. Each record is one wallet, keyed by its CAIP-10 account on the sampled chain, which is also its `author`; each sample is a new observation whose `occurredAt` is the sample time and whose `data` is `WalletBalanceSample` (`amount` in base units, `decimals`, `block`). A provider outage retries the same block later that day and never writes a zero, so a day with no successful sample breaks a `streak({ days })`. Reward holding for days with `automatic({ tracker, where: { path: "amount", gte: { setting: "threshold" } } })` and `streak({ days })`. In SDK 1.x it is a custom source on the reserved namespace `wallet-balances`, with the chain and token in the new optional `balance` field of custom sources (`walletBalanceSourceSchema`); ingestion refuses the namespace, and a project and environment can have at most 5 such trackers (`limit-reached`).
74
+
75
+ `management.trackers.create` and Console **New tracker** take `{ kind: "wallet-balances", chain, token }` (`managedTrackerSourceSchema`), and `domino trackers create --source wallet-balances` takes `--chain` and `--token`. The new `token-hold-streak` snippet rewards holding a token for 7 days in a row.
76
+
77
+ ## 1.56.0
78
+
79
+ ### Minor Changes
80
+
81
+ - 9ec9f2f: Publishing creates the groups code names. A deployment whose quest `groupMembership(group)` reward or `inGroup(group)` prerequisite, offer `inGroup(group)` requirement, leaderboard `group` or referral `inviterGroup` names a group the environment doesn't have now creates it, with no members and the `defineGroup` handle's title (the key when only a leaderboard or referral program names it), instead of refusing with 422 `validation-failed`. Approving a promotion creates the groups live lacks the same way. The deployment preview and result, and the prepared promotion, list each such group as a `group-created` warning, and the audit history records `group-created` with the deployment or promotion as its reason. An existing group keeps its title and members, and publishing never unarchives one: a `groupMembership` reward naming an archived group still refuses. A project whose code uses groups no longer needs `domino groups create` before its first deployment or promotion.
82
+ - fbe8e64: Offers take prerequisites. `defineOffer({ ..., requires })` accepts the prerequisites quests do, `completed(quest)`, `balanceAtLeast(ledger, minimum)` and `inGroup(group)`, at most 30; `offerDefinitionSchema` and `offerAuthoringSchema` gain an optional `requires`. Publication refuses a required quest or ledger the deployment doesn't know. Redeeming as a member who misses one fails with 409 `prerequisites-incomplete` and `missing`, the shape quest admission uses, before any points or stock are spent. `Offer` gains `requires` and `missing`: for a signed-in member, `relay.offers.list()` and `useOffers()` list the prerequisites they have not met, empty for a read without a member or an offer without `requires`. `availability` keeps its four kinds. Console Rewards shows an offer's requirements on its card, and a promotion carries them to live.
83
+ - cba70f4: Add the organization's billing read. `management.billing.organization()` and `domino billing organization` (`GET /management/v1/organization/billing`) are open to any member of the organization and need no project. They list the projects the caller may read, each with its plan, `live` and `liveState` as `management.usage.plan()` reports them, and its Stripe subscription. They also return the organization's Free projects against their limit (`freeProjects`), the free AI allowance its Free projects share (`freeAi`), the monthly AI allowance across the organization, the trial, whether plan limits are enforced, and whether the caller may open the customer portal (`billing`). `management.billing.organizationPortal()` (`POST /management/v1/organization/billing/portal`) opens the customer portal as `management.billing.portal()` does, returning to Console's organization billing page. `organizationBillingSchema` and the `OrganizationBilling` type are exported from `@domino-sdk/relay/server`, with a reader in `managementResponses`.
84
+ - 6458ebe: Add the project's plan read. `management.usage.plan()` and `domino usage plan` (`GET /management/v1/usage/plan`, `read` permission) return the project's plan and where it came from (`source`), whether it may serve live and why (`live`), live's notice or offline state (`liveState`), the organization's one live trial (`trial`), whether the plan includes a custom domain, the AI builder balance by pool with when it renews (`ai`), the Stripe subscription as `management.billing.read()` reports it, and whether plan limits are enforced. Unlike `management.billing`, it is open to anyone who can read the project. `projectPlanSchema` and the `ProjectPlan` type are exported from `@domino-sdk/relay/server`, with a reader in `managementResponses`.
85
+ - 62c3791: Add TikTok creator accounts and the `tiktok.videos()` tracker source. A signed-in member links their TikTok account through TikTok's consent screen with `relay.auth.creatorAccounts.connect("tiktok")` (`useCreatorAccounts()` in React); the account's subject is its `open_id`, its profile a display name and avatar, and `knownCreatorAccountProviders` now lists `"tiktok"`. Operators read and unlink it like a YouTube channel. `tiktok.videos()` from `@domino-sdk/relay/authoring` reads the public videos on the accounts members linked, only with each member's own token, every `refreshSeconds` of the tracker, as content with a `TikTokVideoBody` (`title`, `description`, `durationSeconds`, `width`, `height`, `createdAt`, `shareUrl`, `isAigc`) and the metrics `views`, `likes`, `comments` and `shares`, so `content()` quests, `performance` and engagement rules use it. A known video the account no longer returns is a content removal; an account whose token needs reconnecting is not read, as `provider-unavailable`. It is a custom source on the reserved namespace `tiktok-videos`, which ingestion refuses. Both are inert until Domino configures TikTok. The `tiktok-videos` capability and the participant and authoring references describe them.
86
+ - a533f93: Add creator accounts and the `youtube.shorts()` tracker source. A signed-in member links the YouTube channel they publish from as a creator account: `relay.auth.creatorAccounts.list()` (`GET /v1/auth/creator-accounts`), `connect(provider)` and `disconnect(provider)`, and `useCreatorAccounts()` in React. A creator account is never a sign-in method, linking another channel replaces the current one, and the account's subject is the channel ID picked on Google's consent screen. Each entry mirrors `AccountConnection` with the channel's `profile`; `provider` is an open string, with `knownCreatorAccountProviders` in `@domino-sdk/relay/schema` listing `"youtube"`, so `CreatorAccount`, `CreatorAccounts` and their schemas sit beside SDK 1.x's closed provider lists. Operators read them on `management.members.get(member).creatorAccounts` and `management.members.creatorAccounts(member)`, and `management.members.unlinkCreatorAccount(member, { provider, subject, revision, reason })` unlinks one with `review` permission; `managedCreatorAccountSchema`, `managedCreatorAccountsSchema` and `memberCreatorAccountUnlinkInputSchema` are exported from `@domino-sdk/relay/server`. `youtube.shorts()` from `@domino-sdk/relay/authoring` reads the Shorts on the channels members linked, every `refreshSeconds` of the tracker, as content with a `YouTubeShortBody` (`title`, `description`, `tags`, `durationSeconds`, `publishedAt`) and the metrics `views`, `likes` and `comments`, so `content()` quests, `performance` and engagement rules use it. It is a custom source on the reserved namespace `youtube-shorts`, which ingestion refuses. Both are inert until Domino configures YouTube. The `creator-accounts` and `youtube-shorts` capabilities and the participant and authoring references describe them.
87
+
3
88
  ## 1.55.0
4
89
 
5
90
  ### Minor Changes
@@ -18,7 +18,6 @@ type DiscordMessage = z.infer<typeof discordMessageSchema>;
18
18
  */
19
19
  declare const discordMessagesSourceSchema: z.ZodObject<{
20
20
  kind: z.ZodLiteral<"discord-messages">;
21
- /** Store each message's text in `data.text`. Off unless set. */
22
21
  text: z.ZodOptional<z.ZodBoolean>;
23
22
  }, z.core.$strict>;
24
23
  /**
@@ -206,11 +205,7 @@ interface TelegramReader {
206
205
  chat: string;
207
206
  }): Promise<TelegramChatMember | null>;
208
207
  }
209
- /**
210
- * The namespace of the tracker source `telegram.reactions()` makes. Relay alone writes its
211
- * records; ingestion into it is refused.
212
- */
213
- declare const telegramReactionsNamespace = "telegram-reactions";
208
+
214
209
  /**
215
210
  * One reaction a Telegram user added to a message, as a `telegram.reactions()` record's `data`.
216
211
  * Every field is a scalar, so a trigger's `where` can select on it.
@@ -229,6 +224,22 @@ declare const telegramReactionDataSchema: z.ZodObject<{
229
224
  }, z.core.$strip>;
230
225
  type TelegramReactionData = z.infer<typeof telegramReactionDataSchema>;
231
226
 
227
+ /**
228
+ * One message a Telegram user posted in a connected group, as a `telegram.messages()` record's
229
+ * `data`. It names the message and never holds its text. Every field is a scalar, so a trigger's
230
+ * `where` can select on it.
231
+ *
232
+ * @compat output
233
+ */
234
+ declare const telegramMessageDataSchema: z.ZodObject<{
235
+ chatId: z.ZodString;
236
+ chatType: z.ZodString;
237
+ messageId: z.ZodNumber;
238
+ replyToMessageId: z.ZodNullable<z.ZodNumber>;
239
+ threadId: z.ZodNullable<z.ZodNumber>;
240
+ }, z.core.$strip>;
241
+ type TelegramMessageData = z.infer<typeof telegramMessageDataSchema>;
242
+
232
243
  declare const authProviderSchema: z.ZodEnum<{
233
244
  discord: "discord";
234
245
  google: "google";
@@ -289,4 +300,4 @@ interface DiscordReader {
289
300
  }): Promise<DiscordMessage | null>;
290
301
  }
291
302
 
292
- export { type AccountConnection as A, discordRewardSchema as B, telegramAccountConnectionSchema as C, type DiscordMessageData as D, telegramChatConnectionSchema as E, telegramChatIdSchema as F, telegramChatMemberSchema as G, telegramChatSchema as H, telegramChatsSchema as I, telegramInitDataSchema as J, telegramMemberInputSchema as K, telegramMiniAppSignInSchema as L, telegramReactionDataSchema as M, telegramReactionsNamespace as N, telegramSignInMethodsSchema as O, type TelegramAccountConnection as T, type AuthProvider as a, type TelegramSignInMethods as b, type DiscordMessageTextData as c, discordMessagesSourceSchema as d, discordReactionsSourceSchema as e, type DiscordReactionData as f, type TelegramReader as g, type DiscordReader as h, type TelegramChatMember as i, type TelegramChatMemberStatus as j, type TelegramReactionData as k, type DiscordMember as l, type DiscordMessage as m, type TelegramChat as n, type TelegramChatConnection as o, type TelegramChats as p, accountConnectionSchema as q, authProviderSchema as r, discordMemberInputSchema as s, discordMemberSchema as t, discordMessageDataSchema as u, discordMessageInputSchema as v, discordMessageSchema as w, discordMessageTextDataSchema as x, discordReactionDataSchema as y, discordResourceSourceSchema as z };
303
+ export { type AccountConnection as A, discordResourceSourceSchema as B, discordRewardSchema as C, type DiscordMessageData as D, telegramAccountConnectionSchema as E, telegramChatConnectionSchema as F, telegramChatIdSchema as G, telegramChatMemberSchema as H, telegramChatSchema as I, telegramChatsSchema as J, telegramInitDataSchema as K, telegramMemberInputSchema as L, telegramMessageDataSchema as M, telegramMiniAppSignInSchema as N, telegramReactionDataSchema as O, telegramSignInMethodsSchema as P, type TelegramAccountConnection as T, type AuthProvider as a, type TelegramSignInMethods as b, type DiscordMessageTextData as c, discordMessagesSourceSchema as d, discordReactionsSourceSchema as e, type DiscordReactionData as f, type TelegramReader as g, type DiscordReader as h, type TelegramChatMember as i, type TelegramChatMemberStatus as j, type TelegramMessageData as k, type TelegramReactionData as l, type DiscordMember as m, type DiscordMessage as n, type TelegramChat as o, type TelegramChatConnection as p, type TelegramChats as q, accountConnectionSchema as r, authProviderSchema as s, discordMemberInputSchema as t, discordMemberSchema as u, discordMessageDataSchema as v, discordMessageInputSchema as w, discordMessageSchema as x, discordMessageTextDataSchema as y, discordReactionDataSchema as z };
@@ -1,4 +1,4 @@
1
- import { O as OpenIdentityKind } from './schema-C4m9RhCR.js';
1
+ import { O as OpenIdentityKind } from './schema-BA0nRRlt.js';
2
2
  import * as z from 'zod';
3
3
 
4
4
  /** One capability call of the captured evaluation run, as Relay stored it. */