@domino-sdk/relay 1.66.1 → 1.68.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 (72) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/dist/{accounts-_lNsiR2k.d.ts → accounts-DnpKoJCo.d.ts} +210 -3
  3. package/dist/{attempt-captures-BqPggxTU.d.ts → attempt-captures-DMNFMYFb.d.ts} +9 -1
  4. package/dist/authoring.d.ts +352 -40
  5. package/dist/authoring.js +131 -22
  6. package/dist/{automatic-outcomes-BzAvfcpd.d.ts → automatic-outcomes-CQ3vpiQl.d.ts} +2 -2
  7. package/dist/avatar.d.ts +1 -1
  8. package/dist/browser.d.ts +10 -9
  9. package/dist/browser.js +12 -12
  10. package/dist/{catalog-ByZMRS7I.d.ts → catalog-BLGie8Lh.d.ts} +60 -2
  11. package/dist/chunk-4JSPMFO2.js +427 -0
  12. package/dist/{chunk-5LD5DKOM.js → chunk-55WJVFWC.js} +2 -2
  13. package/dist/{chunk-CJDB6W6I.js → chunk-5AKD4ZF3.js} +75 -36
  14. package/dist/{chunk-7MQCQYEE.js → chunk-6UBFSMCM.js} +1 -1
  15. package/dist/{chunk-XCEGNKGH.js → chunk-6YTSRWRB.js} +1254 -700
  16. package/dist/{chunk-OWDIR7ZU.js → chunk-75KF633N.js} +9 -1
  17. package/dist/{chunk-4TC4HK5Y.js → chunk-7YSVZA7A.js} +1 -1
  18. package/dist/{chunk-7HTRIEM7.js → chunk-CZ7NQ7W7.js} +11 -68
  19. package/dist/{chunk-ANVAUOJP.js → chunk-DDJN2T5A.js} +1 -1
  20. package/dist/{chunk-M66Y5OMJ.js → chunk-DNPDR4Z7.js} +16 -9
  21. package/dist/{chunk-FU3W4IQN.js → chunk-EXZVWQOQ.js} +2 -2
  22. package/dist/{chunk-5DYS2OIP.js → chunk-HXTKI34N.js} +14 -2
  23. package/dist/{chunk-FGXLXENM.js → chunk-IW46TW3A.js} +21 -1
  24. package/dist/{chunk-2Y4EZKET.js → chunk-KKHENO57.js} +2 -2
  25. package/dist/{chunk-U66GUVSG.js → chunk-LZXDYSUH.js} +2 -0
  26. package/dist/{chunk-QYHEHMCG.js → chunk-MEUAJIVO.js} +2 -2
  27. package/dist/{chunk-BQXRCJ3N.js → chunk-P4TPW4SY.js} +1 -1
  28. package/dist/{chunk-CGUL4MRE.js → chunk-R3MNZKNJ.js} +1 -1
  29. package/dist/{chunk-R2LHIWAM.js → chunk-SD74HD75.js} +45 -9
  30. package/dist/{chunk-FUFMYKSQ.js → chunk-TYZFVL73.js} +136 -5
  31. package/dist/chunk-VAGGGB6B.js +87 -0
  32. package/dist/{chunk-2HHZV7U3.js → chunk-VRZZB7CQ.js} +1 -1
  33. package/dist/{client-Cze4lfwA.d.ts → client-BMif22WQ.d.ts} +136 -7
  34. package/dist/{dashboards-pVfclkyh.d.ts → dashboards-DMk-vL1q.d.ts} +4 -4
  35. package/dist/{deployments-Cr1tfqrr.d.ts → deployments-BCr418BX.d.ts} +582 -173
  36. package/dist/{identity-integration-Ci2vGKtX.d.ts → identity-integration-r76xaAax.d.ts} +10 -2
  37. package/dist/index.d.ts +10 -10
  38. package/dist/index.js +10 -10
  39. package/dist/internal.d.ts +155 -14
  40. package/dist/internal.js +255 -25
  41. package/dist/{limits-pE04y9O2.d.ts → limits-ByVRQePO.d.ts} +6 -1
  42. package/dist/{offers-Hw2P6tcK.d.ts → offers-xcPbYaEv.d.ts} +2 -2
  43. package/dist/portal-proxy.d.ts +5 -5
  44. package/dist/portal-proxy.js +13 -15
  45. package/dist/react/index.d.ts +38 -15
  46. package/dist/react/index.js +12 -12
  47. package/dist/{reward-deliveries-BCV8hznc.d.ts → reward-deliveries-0VvT6LMj.d.ts} +1 -1
  48. package/dist/runtime/authoring.js +1 -1
  49. package/dist/runtime/chunks/2UDZ6TPL.js +1 -0
  50. package/dist/runtime/manifest.json +3 -3
  51. package/dist/runtime/schema.js +1 -1
  52. package/dist/schema.d.ts +401 -104
  53. package/dist/schema.js +66 -8
  54. package/dist/server/index.d.ts +12 -12
  55. package/dist/server/index.js +2288 -873
  56. package/dist/{sign-in-providers-BAkGjSXo.d.ts → sign-in-providers-C5_753DZ.d.ts} +2 -2
  57. package/dist/solana.d.ts +171 -0
  58. package/dist/solana.js +364 -0
  59. package/dist/{submission-input-ChL1aYNH.d.ts → submission-input-CaL8drIh.d.ts} +2 -2
  60. package/dist/{telegram-browser-BFs4u7lC.d.ts → telegram-browser-DLtHPRBI.d.ts} +6 -108
  61. package/dist/telegram.d.ts +8 -8
  62. package/dist/telegram.js +2 -2
  63. package/dist/testing.d.ts +87 -14
  64. package/dist/testing.js +108 -11
  65. package/dist/{tracker-data-Bl-qPIvZ.d.ts → tracker-data-CAK942sx.d.ts} +300 -3
  66. package/dist/{transport-WE49Ta3A.d.ts → transport-CkidqTOk.d.ts} +5866 -1244
  67. package/dist/{wallet-B7e06v4m.d.ts → wallet-DQtJelQQ.d.ts} +418 -33
  68. package/dist/wallet-browser-dpmr22Xv.d.ts +106 -0
  69. package/package.json +18 -1
  70. package/dist/chunk-UYVJZR33.js +0 -34
  71. package/dist/chunk-UZ765UGH.js +0 -18
  72. package/dist/runtime/chunks/C5V267I7.js +0 -1
@@ -1,6 +1,6 @@
1
- import { J as SignInProvider } from './accounts-_lNsiR2k.js';
1
+ import { J as SignInProvider } from './accounts-DnpKoJCo.js';
2
2
  import * as z from 'zod';
3
- import { a as TelegramSignInMethods } from './submission-input-ChL1aYNH.js';
3
+ import { a as TelegramSignInMethods } from './submission-input-CaL8drIh.js';
4
4
 
5
5
  /**
6
6
  * `GET /v1/auth/providers`, as `relay.auth.providers()` reads it. Exported as a schema only, for the
@@ -0,0 +1,171 @@
1
+ import { TransactionSigner, Rpc, GetAccountInfoApi, GetBlockHeightApi, GetLatestBlockhashApi, GetMinimumBalanceForRentExemptionApi, GetSignatureStatusesApi, SendTransactionApi, KeyPairSigner, Address, Signature } from '@solana/kit';
2
+ import { S as SolanaNetwork } from './wallet-DQtJelQQ.js';
3
+ export { s as solanaDevnet, t as solanaMainnet } from './wallet-DQtJelQQ.js';
4
+ import { M as ManagementClient, W as WebhookEvent, C as CompletionReceipt } from './transport-CkidqTOk.js';
5
+ import 'zod';
6
+ import './accounts-DnpKoJCo.js';
7
+ import './tracker-data-CAK942sx.js';
8
+ import './identity-integration-r76xaAax.js';
9
+ import './reward-deliveries-0VvT6LMj.js';
10
+ import './request-error-D_dUPLwo.js';
11
+ import './action-9Xl0StBg.js';
12
+ import './limits-ByVRQePO.js';
13
+ import './automatic-outcomes-CQ3vpiQl.js';
14
+ import './deployments-BCr418BX.js';
15
+ import './offers-xcPbYaEv.js';
16
+ import './catalog-BLGie8Lh.js';
17
+ import './attempt-captures-DMNFMYFb.js';
18
+
19
+ /**
20
+ * The RPC methods the badge helpers call. `createSolanaRpc(url)` from `@solana/kit` answers all of
21
+ * them.
22
+ */
23
+ type SolanaBadgeRpc = Rpc<GetAccountInfoApi & GetBlockHeightApi & GetLatestBlockhashApi & GetMinimumBalanceForRentExemptionApi & GetSignatureStatusesApi & SendTransactionApi>;
24
+ /** The receipt key `awardSolanaBadge` records a badge under. */
25
+ declare const solanaBadgeReceiptKey = "badge";
26
+ /**
27
+ * What `awardSolanaBadge` did. `minted` and `already-minted` carry the completion's badge
28
+ * receipt; `no-wallet` means the member has no proven Solana wallet, and nothing was sent;
29
+ * `deferred` is `no-wallet` under `whenNoWallet: "defer"`, so `awardOwedSolanaBadges` mints the
30
+ * badge once the member links one; `ignored` means the event is not a quest completion, or its
31
+ * quest is outside `quests`.
32
+ *
33
+ * @experimental A minor release can change the Solana badge helpers.
34
+ */
35
+ type SolanaBadgeAward = {
36
+ status: "minted";
37
+ receipt: CompletionReceipt;
38
+ } | {
39
+ status: "already-minted";
40
+ receipt: CompletionReceipt;
41
+ } | {
42
+ status: "no-wallet";
43
+ } | {
44
+ status: "deferred";
45
+ } | {
46
+ status: "ignored";
47
+ };
48
+ /** @experimental A minor release can change the Solana badge helpers. */
49
+ type AwardSolanaBadgeInput = {
50
+ /**
51
+ * A management client with `points` and `read` permission: it reads the member's wallets and
52
+ * completions and records the receipt.
53
+ */
54
+ management: Pick<ManagementClient, "completions" | "members">;
55
+ /** A delivery `verifyWebhook` verified. Events other than a quest's `completion.created` are ignored. */
56
+ event: WebhookEvent;
57
+ /** The badge's Token-2022 mint, as `createSolanaBadgeMint` created it. */
58
+ mint: string;
59
+ /** The mint authority. It signs the mint and pays the fee and the member's token account rent. */
60
+ authority: TransactionSigner;
61
+ rpc: SolanaBadgeRpc;
62
+ /** The cluster `rpc` serves, recorded on the receipt: `solanaMainnet` or `solanaDevnet`. */
63
+ network: SolanaNetwork;
64
+ /** Award only completions of these quest IDs. Omit to award every quest's completions. */
65
+ quests?: readonly string[];
66
+ /**
67
+ * What happens when the member has no proven Solana wallet. Both send nothing: `skip` (the
68
+ * default) answers `no-wallet`, and `defer` answers `deferred`, for a server that also calls
69
+ * `awardOwedSolanaBadges` on `wallet.linked` to mint the badge once the member links a wallet.
70
+ */
71
+ whenNoWallet?: "skip" | "defer";
72
+ /** Receipt `label` Console shows beside it. */
73
+ label?: string;
74
+ };
75
+ /**
76
+ * Mints one unit of a non-transferable Token-2022 badge to the member's most recently linked
77
+ * proven Solana wallet for a quest's `completion.created` event, and records the transaction as
78
+ * the completion's `badge` receipt. Call it from your webhook handler; your server holds the mint
79
+ * authority and pays the fees.
80
+ *
81
+ * Exactly once per completion, whatever the deliveries and retries. Before sending, it records the
82
+ * signed transaction as a `badge-attempt-<n>` receipt, which only one call can record, and only
83
+ * then sends it. A call that finds an earlier attempt records it as the badge once it landed,
84
+ * sends a new attempt once it failed or its blockhash expired, and otherwise throws
85
+ * `SolanaBadgePendingError` without sending, so the delivery is retried later. It waits for the
86
+ * `confirmed` commitment.
87
+ *
88
+ * Requires the optional peer dependencies `@solana/kit` and `@solana-program/token-2022`.
89
+ *
90
+ * @experimental A minor release can change the Solana badge helpers.
91
+ */
92
+ declare function awardSolanaBadge(input: AwardSolanaBadgeInput): Promise<SolanaBadgeAward>;
93
+ /**
94
+ * What `awardOwedSolanaBadges` did: `awarded` with each owed completion and what
95
+ * `awardSolanaBadge` did for it (`minted`, `already-minted`, or `no-wallet` when the member has
96
+ * unlinked the wallet since), or `ignored` when the event is not a Solana `wallet.linked`.
97
+ *
98
+ * @experimental A minor release can change the Solana badge helpers.
99
+ */
100
+ type OwedSolanaBadges = {
101
+ status: "awarded";
102
+ awards: {
103
+ completion: string;
104
+ quest: string;
105
+ award: SolanaBadgeAward;
106
+ }[];
107
+ } | {
108
+ status: "ignored";
109
+ };
110
+ /**
111
+ * `awardSolanaBadge`'s input for a `wallet.linked` event: the same badge, mint authority and
112
+ * `quests`.
113
+ *
114
+ * @experimental A minor release can change the Solana badge helpers.
115
+ */
116
+ type AwardOwedSolanaBadgesInput = Omit<AwardSolanaBadgeInput, "whenNoWallet">;
117
+ /**
118
+ * Mints the badges a member is owed once they link a Solana wallet: call it from your webhook
119
+ * handler for `wallet.linked`, next to `awardSolanaBadge` with `whenNoWallet: "defer"` for
120
+ * `completion.created`. For a Solana wallet, it lists the member's completions that count (not
121
+ * revoked) of each quest in `quests` (every quest when omitted) and awards each one exactly as
122
+ * `awardSolanaBadge` does, so a completion that has its `badge` receipt mints nothing and a
123
+ * redelivered event mints nothing new. Other events and chains are `ignored`.
124
+ *
125
+ * It mints one completion at a time and throws on the first failure, such as
126
+ * `SolanaBadgePendingError`: fail the delivery so Domino retries it, and the retry skips the badges
127
+ * already minted.
128
+ *
129
+ * @experimental A minor release can change the Solana badge helpers.
130
+ */
131
+ declare function awardOwedSolanaBadges(input: AwardOwedSolanaBadgesInput): Promise<OwedSolanaBadges>;
132
+ /**
133
+ * An earlier call's badge transaction for this completion has not landed yet, and its blockhash
134
+ * is still valid. Nothing was sent; call again later, for example by failing the webhook delivery
135
+ * so Domino retries it.
136
+ *
137
+ * @experimental A minor release can change the Solana badge helpers.
138
+ */
139
+ declare class SolanaBadgePendingError extends Error {
140
+ readonly signature: string;
141
+ readonly code = "badge-pending";
142
+ constructor(signature: string);
143
+ }
144
+ /** @experimental A minor release can change the Solana badge helpers. */
145
+ type CreateSolanaBadgeMintInput = {
146
+ /** Becomes the mint and metadata authority, and pays for the mint account. */
147
+ authority: TransactionSigner;
148
+ rpc: SolanaBadgeRpc;
149
+ /** The badge's on-chain name, symbol and metadata JSON URI, which wallets and explorers show. */
150
+ name: string;
151
+ symbol: string;
152
+ uri: string;
153
+ /** The new mint's key pair. Omit to generate one. */
154
+ mint?: KeyPairSigner;
155
+ };
156
+ /**
157
+ * Creates a badge mint for `awardSolanaBadge`: a Token-2022 mint with 0 decimals, the
158
+ * NonTransferable extension, so its tokens can't move from the wallet they were minted to, and
159
+ * on-mint metadata (the metadata pointer and token metadata extensions). Run it once per badge,
160
+ * for example from a setup script, and keep the mint address.
161
+ *
162
+ * @experimental A minor release can change the Solana badge helpers.
163
+ */
164
+ declare function createSolanaBadgeMint(input: CreateSolanaBadgeMintInput): Promise<{
165
+ mint: Address;
166
+ signature: Signature;
167
+ }>;
168
+ /** The SPL Memo `awardSolanaBadge` attaches to a completion's mint. */
169
+ declare const solanaBadgeMemo: (completion: string) => string;
170
+
171
+ export { type AwardOwedSolanaBadgesInput, type AwardSolanaBadgeInput, type CreateSolanaBadgeMintInput, type OwedSolanaBadges, type SolanaBadgeAward, SolanaBadgePendingError, type SolanaBadgeRpc, SolanaNetwork, awardOwedSolanaBadges, awardSolanaBadge, createSolanaBadgeMint, solanaBadgeMemo, solanaBadgeReceiptKey };
package/dist/solana.js ADDED
@@ -0,0 +1,364 @@
1
+ import {
2
+ maxCompletionReceipts,
3
+ walletLinkedEventDataSchema
4
+ } from "./chunk-4JSPMFO2.js";
5
+ import "./chunk-DNPDR4Z7.js";
6
+ import "./chunk-DDJN2T5A.js";
7
+ import "./chunk-MEUAJIVO.js";
8
+ import "./chunk-MWMCQLCG.js";
9
+ import "./chunk-R3MNZKNJ.js";
10
+ import "./chunk-6UBFSMCM.js";
11
+ import "./chunk-55WJVFWC.js";
12
+ import {
13
+ paginate,
14
+ solanaDevnet,
15
+ solanaMainnet,
16
+ solanaMemoProgram
17
+ } from "./chunk-6YTSRWRB.js";
18
+ import "./chunk-IW46TW3A.js";
19
+
20
+ // src/solana.ts
21
+ import {
22
+ appendTransactionMessageInstructions,
23
+ createTransactionMessage,
24
+ flattenInstructionPlan,
25
+ getBase64EncodedWireTransaction,
26
+ getSignatureFromTransaction,
27
+ pipe,
28
+ setTransactionMessageFeePayerSigner,
29
+ setTransactionMessageLifetimeUsingBlockhash,
30
+ signTransactionMessageWithSigners,
31
+ address,
32
+ generateKeyPairSigner
33
+ } from "@solana/kit";
34
+ import {
35
+ TOKEN_2022_PROGRAM_ADDRESS,
36
+ extension,
37
+ fetchMint,
38
+ findAssociatedTokenPda,
39
+ getCreateMintInstructionPlan,
40
+ getMintToATAInstructionPlan
41
+ } from "@solana-program/token-2022";
42
+ var solanaBadgeReceiptKey = "badge";
43
+ async function awardSolanaBadge(input) {
44
+ const completion = questCompletion(input.event);
45
+ if (!completion || input.quests && !input.quests.includes(completion.quest)) {
46
+ return { status: "ignored" };
47
+ }
48
+ return awardCompletion(input, completion, badgeLookups(input));
49
+ }
50
+ async function awardOwedSolanaBadges(input) {
51
+ const { event, management } = input;
52
+ const linked = event.type === "wallet.linked" ? walletLinkedEventDataSchema.safeParse(event.data) : void 0;
53
+ if (!linked?.success || linked.data.chain !== "solana") {
54
+ return { status: "ignored" };
55
+ }
56
+ const { member } = linked.data;
57
+ const lookups = badgeLookups(input);
58
+ const awards = [];
59
+ for (const quest of input.quests ?? [void 0]) {
60
+ for await (const completion of paginate(
61
+ (cursor) => management.completions.list({ member, quest, cursor, limit: 100 })
62
+ )) {
63
+ if (completion.source?.kind !== "quest") {
64
+ continue;
65
+ }
66
+ awards.push({
67
+ completion: completion.id,
68
+ quest: completion.quest,
69
+ award: await awardCompletion(
70
+ input,
71
+ { id: completion.id, quest: completion.quest, member },
72
+ lookups
73
+ )
74
+ });
75
+ }
76
+ }
77
+ return { status: "awarded", awards };
78
+ }
79
+ function badgeLookups(input) {
80
+ const once = (read) => {
81
+ let value;
82
+ return () => value ??= read();
83
+ };
84
+ const wallets = /* @__PURE__ */ new Map();
85
+ return {
86
+ wallet(member) {
87
+ if (!wallets.has(member)) {
88
+ wallets.set(
89
+ member,
90
+ once(() => provenSolanaWallet(input.management, member))
91
+ );
92
+ }
93
+ return wallets.get(member)();
94
+ },
95
+ decimals: once(
96
+ () => badgeDecimals(input.rpc, address(input.mint), input.authority.address)
97
+ )
98
+ };
99
+ }
100
+ async function awardCompletion(input, completion, lookups) {
101
+ const { management, rpc, authority } = input;
102
+ let receipts = await management.completions.receipts(completion.id);
103
+ const existing = receipts.find(
104
+ (receipt) => receipt.key === solanaBadgeReceiptKey
105
+ );
106
+ if (existing) {
107
+ return { status: "already-minted", receipt: existing };
108
+ }
109
+ const record = (attempt2) => management.completions.recordReceipt(completion.id, {
110
+ key: solanaBadgeReceiptKey,
111
+ network: attempt2.network,
112
+ signature: attempt2.signature,
113
+ ...attempt2.asset === null ? {} : { asset: attempt2.asset },
114
+ ...attempt2.recipient === null ? {} : { recipient: attempt2.recipient },
115
+ ...input.label === void 0 ? {} : { label: input.label }
116
+ });
117
+ const settled = async () => {
118
+ const attempt2 = latestAttempt(receipts);
119
+ const outcome = attempt2 && await attemptOutcome(rpc, attempt2);
120
+ if (outcome === "landed") {
121
+ return { status: "minted", receipt: await record(attempt2) };
122
+ }
123
+ if (outcome === "pending") {
124
+ throw new SolanaBadgePendingError(attempt2.signature);
125
+ }
126
+ return attempt2 ? attemptNumber(attempt2.key) + 1 : 1;
127
+ };
128
+ const next = await settled();
129
+ if (typeof next !== "number") {
130
+ return next;
131
+ }
132
+ if (receipts.length >= maxCompletionReceipts - 1) {
133
+ throw new Error(
134
+ `Completion ${completion.id} holds ${receipts.length} receipts, leaving no room for another badge attempt and the badge`
135
+ );
136
+ }
137
+ const wallet = await lookups.wallet(completion.member);
138
+ if (!wallet) {
139
+ return { status: input.whenNoWallet === "defer" ? "deferred" : "no-wallet" };
140
+ }
141
+ const mint = address(input.mint);
142
+ const owner = address(wallet);
143
+ const decimals = await lookups.decimals();
144
+ const [token] = await findAssociatedTokenPda({
145
+ owner,
146
+ mint,
147
+ tokenProgram: TOKEN_2022_PROGRAM_ADDRESS
148
+ });
149
+ const transaction = await sign(rpc, authority, [
150
+ ...instructions(
151
+ getMintToATAInstructionPlan({
152
+ payer: authority,
153
+ ata: token,
154
+ owner,
155
+ mint,
156
+ mintAuthority: authority,
157
+ amount: 1n,
158
+ decimals
159
+ })
160
+ ),
161
+ memoInstruction(solanaBadgeMemo(completion.id))
162
+ ]);
163
+ let attempt;
164
+ try {
165
+ attempt = await management.completions.recordReceipt(completion.id, {
166
+ key: `${attemptPrefix}${next}`,
167
+ network: input.network,
168
+ signature: transaction.signature,
169
+ asset: mint,
170
+ recipient: owner,
171
+ label: `Badge mint, valid through block height ${transaction.lastValidBlockHeight}`
172
+ });
173
+ } catch (error) {
174
+ if (error.code !== "receipt-conflict") {
175
+ throw error;
176
+ }
177
+ receipts = await management.completions.receipts(completion.id);
178
+ const answer = await settled();
179
+ if (typeof answer !== "number") {
180
+ return answer;
181
+ }
182
+ throw error;
183
+ }
184
+ await sendAndConfirm(rpc, transaction);
185
+ return { status: "minted", receipt: await record(attempt) };
186
+ }
187
+ var SolanaBadgePendingError = class extends Error {
188
+ constructor(signature) {
189
+ super(
190
+ `The badge transaction ${signature} for this completion is still confirming; try again later`
191
+ );
192
+ this.signature = signature;
193
+ this.name = "SolanaBadgePendingError";
194
+ }
195
+ signature;
196
+ code = "badge-pending";
197
+ };
198
+ async function createSolanaBadgeMint(input) {
199
+ const { authority, rpc } = input;
200
+ const mint = input.mint ?? await generateKeyPairSigner();
201
+ const plan = await getCreateMintInstructionPlan(
202
+ {
203
+ getMinimumBalance: async (space) => rpc.getMinimumBalanceForRentExemption(BigInt(space)).send()
204
+ },
205
+ {
206
+ payer: authority,
207
+ newMint: mint,
208
+ decimals: 0,
209
+ mintAuthority: authority,
210
+ extensions: [
211
+ extension("NonTransferable", {}),
212
+ extension("MetadataPointer", {
213
+ authority: authority.address,
214
+ metadataAddress: mint.address
215
+ }),
216
+ extension("TokenMetadata", {
217
+ updateAuthority: authority.address,
218
+ mint: mint.address,
219
+ name: input.name,
220
+ symbol: input.symbol,
221
+ uri: input.uri,
222
+ additionalMetadata: /* @__PURE__ */ new Map()
223
+ })
224
+ ]
225
+ }
226
+ );
227
+ const signature = await sendAndConfirm(
228
+ rpc,
229
+ await sign(rpc, authority, instructions(plan))
230
+ );
231
+ return { mint: mint.address, signature };
232
+ }
233
+ var solanaBadgeMemo = (completion) => `domino-badge:${completion}`;
234
+ function questCompletion(event) {
235
+ const { data } = event;
236
+ const source = data.source;
237
+ const fromQuest = source === void 0 ? typeof data.attempt === "string" : source?.kind === "quest";
238
+ if (event.type !== "completion.created" || !fromQuest || typeof data.completion !== "string" || typeof data.quest !== "string" || typeof data.member !== "string") {
239
+ return null;
240
+ }
241
+ return { id: data.completion, quest: data.quest, member: data.member };
242
+ }
243
+ async function provenSolanaWallet(management, member) {
244
+ let newest;
245
+ for await (const identity of paginate(
246
+ (cursor) => management.members.identityStates.list(member, { cursor, limit: 100 })
247
+ )) {
248
+ if (identity.kind !== "wallet" || identity.chain !== "solana" || !identity.linked || identity.source === "import") {
249
+ continue;
250
+ }
251
+ const candidate = {
252
+ address: identity.address,
253
+ linkedAt: identity.linkedAt ?? -1,
254
+ revision: identity.revision
255
+ };
256
+ if (!newest || candidate.linkedAt > newest.linkedAt || candidate.linkedAt === newest.linkedAt && candidate.revision > newest.revision) {
257
+ newest = candidate;
258
+ }
259
+ }
260
+ return newest?.address;
261
+ }
262
+ async function badgeDecimals(rpc, mint, authority) {
263
+ const account = await fetchMint(rpc, mint, { commitment: "confirmed" });
264
+ if (account.programAddress !== TOKEN_2022_PROGRAM_ADDRESS) {
265
+ throw new Error(`${mint} is not a Token-2022 mint`);
266
+ }
267
+ const mintAuthority = account.data.mintAuthority;
268
+ if (mintAuthority.__option === "None" || mintAuthority.value !== authority) {
269
+ throw new Error(`${authority} is not the mint authority of ${mint}`);
270
+ }
271
+ return account.data.decimals;
272
+ }
273
+ var attemptPrefix = "badge-attempt-";
274
+ var attemptNumber = (key) => Number(key.slice(attemptPrefix.length));
275
+ function latestAttempt(receipts) {
276
+ return receipts.filter((receipt) => /^badge-attempt-[1-9][0-9]*$/.test(receipt.key)).sort((a, b) => attemptNumber(b.key) - attemptNumber(a.key))[0];
277
+ }
278
+ async function attemptOutcome(rpc, attempt) {
279
+ const lastValid = attempt.label?.match(/block height (\d+)$/)?.[1];
280
+ const height = await rpc.getBlockHeight({ commitment: "finalized" }).send();
281
+ const {
282
+ value: [status]
283
+ } = await rpc.getSignatureStatuses([attempt.signature], {
284
+ searchTransactionHistory: true
285
+ }).send();
286
+ if (status?.confirmationStatus === "confirmed" || status?.confirmationStatus === "finalized") {
287
+ return status.err ? "failed" : "landed";
288
+ }
289
+ return lastValid === void 0 || height > BigInt(lastValid) ? "expired" : "pending";
290
+ }
291
+ var memoInstruction = (memo) => ({
292
+ programAddress: address(solanaMemoProgram),
293
+ data: new TextEncoder().encode(memo)
294
+ });
295
+ var instructions = (plan) => flattenInstructionPlan(plan).map((step) => {
296
+ if (step.kind !== "single") {
297
+ throw new Error("Expected a plan of single instructions");
298
+ }
299
+ return step.instruction;
300
+ });
301
+ async function sign(rpc, feePayer, steps) {
302
+ const { value: blockhash } = await rpc.getLatestBlockhash({ commitment: "confirmed" }).send();
303
+ const transaction = await signTransactionMessageWithSigners(
304
+ pipe(
305
+ createTransactionMessage({ version: 0 }),
306
+ (message) => setTransactionMessageFeePayerSigner(feePayer, message),
307
+ (message) => setTransactionMessageLifetimeUsingBlockhash(blockhash, message),
308
+ (message) => appendTransactionMessageInstructions(steps, message)
309
+ )
310
+ );
311
+ return {
312
+ wire: getBase64EncodedWireTransaction(transaction),
313
+ signature: getSignatureFromTransaction(transaction),
314
+ lastValidBlockHeight: blockhash.lastValidBlockHeight
315
+ };
316
+ }
317
+ async function sendAndConfirm(rpc, transaction) {
318
+ try {
319
+ await rpc.sendTransaction(transaction.wire, {
320
+ encoding: "base64",
321
+ preflightCommitment: "confirmed"
322
+ }).send();
323
+ } catch (error) {
324
+ const {
325
+ value: [status]
326
+ } = await rpc.getSignatureStatuses([transaction.signature]).send();
327
+ if (!status) {
328
+ throw error;
329
+ }
330
+ }
331
+ await confirmed(rpc, transaction.signature, transaction.lastValidBlockHeight);
332
+ return transaction.signature;
333
+ }
334
+ async function confirmed(rpc, signature, lastValidBlockHeight) {
335
+ for (; ; ) {
336
+ const {
337
+ value: [status]
338
+ } = await rpc.getSignatureStatuses([signature]).send();
339
+ if (status?.err) {
340
+ throw new Error(
341
+ `Transaction ${signature} failed: ${JSON.stringify(status.err, (_, value) => typeof value === "bigint" ? String(value) : value)}`
342
+ );
343
+ }
344
+ if (status?.confirmationStatus === "confirmed" || status?.confirmationStatus === "finalized") {
345
+ return;
346
+ }
347
+ if (await rpc.getBlockHeight({ commitment: "confirmed" }).send() > lastValidBlockHeight) {
348
+ throw new Error(
349
+ `Transaction ${signature} was not confirmed before its blockhash expired`
350
+ );
351
+ }
352
+ await new Promise((resolve) => setTimeout(resolve, 500));
353
+ }
354
+ }
355
+ export {
356
+ SolanaBadgePendingError,
357
+ awardOwedSolanaBadges,
358
+ awardSolanaBadge,
359
+ createSolanaBadgeMint,
360
+ solanaBadgeMemo,
361
+ solanaBadgeReceiptKey,
362
+ solanaDevnet,
363
+ solanaMainnet
364
+ };
@@ -1,6 +1,6 @@
1
1
  import * as z from 'zod';
2
- import { L as LedgerReference, Q as QuestHandle } from './tracker-data-Bl-qPIvZ.js';
3
- import { B as ProjectGroupReference } from './accounts-_lNsiR2k.js';
2
+ import { L as LedgerReference, Q as QuestHandle } from './tracker-data-CAK942sx.js';
3
+ import { B as ProjectGroupReference } from './accounts-DnpKoJCo.js';
4
4
 
5
5
  declare const completionPrerequisiteSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
6
6
  kind: z.ZodLiteral<"completion">;
@@ -1,111 +1,9 @@
1
- import { c as AuthProvider, J as SignInProvider } from './accounts-_lNsiR2k.js';
2
- import { p as createRelayClient, k as RelayRequestOptions, g as RelayError } from './client-Cze4lfwA.js';
3
- import { a as TelegramSignInMethods } from './submission-input-ChL1aYNH.js';
1
+ import { c as AuthProvider, J as SignInProvider } from './accounts-DnpKoJCo.js';
2
+ import { p as createRelayClient, k as RelayRequestOptions, g as RelayError } from './client-BMif22WQ.js';
3
+ import { a as TelegramSignInMethods } from './submission-input-CaL8drIh.js';
4
4
  import { b as ParticipantSession } from './participant-activity-DXRq4s6K.js';
5
- import { C as CosmosChain, a as CosmosNetwork, m as WalletSigner, k as WalletSignInNetwork } from './wallet-B7e06v4m.js';
6
-
7
- /** An EIP-1193 provider, such as `window.ethereum` or an EIP-6963 announcement's provider. */
8
- type Eip1193Provider = {
9
- request(args: {
10
- method: string;
11
- params?: unknown[] | object;
12
- }): Promise<unknown>;
13
- /** Subscribes to a provider event such as `accountsChanged`; wallets without events leave it out. */
14
- on?(event: string, listener: (...args: unknown[]) => void): unknown;
15
- removeListener?(event: string, listener: (...args: unknown[]) => void): unknown;
16
- };
17
- /** The legacy injected Solana shape Phantom, Solflare and Backpack expose. */
18
- type SolanaInjectedProvider = {
19
- connect(): Promise<unknown>;
20
- publicKey?: {
21
- toBase58(): string;
22
- } | null;
23
- signMessage(message: Uint8Array, display?: "utf8"): Promise<{
24
- signature: Uint8Array;
25
- } | Uint8Array>;
26
- };
27
- /** The part of a Wallet Standard account Relay uses. */
28
- type StandardWalletAccount = {
29
- readonly address: string;
30
- readonly chains: readonly string[];
31
- };
32
- /** The part of a Wallet Standard wallet Relay uses; any conforming wallet object fits. */
33
- type StandardWallet = {
34
- readonly name: string;
35
- readonly icon?: string;
36
- readonly chains: readonly string[];
37
- readonly accounts: readonly StandardWalletAccount[];
38
- readonly features: Readonly<Record<string, unknown>>;
39
- };
40
- /** Keplr's API, which Leap and Cosmostation also implement. */
41
- type KeplrLike = {
42
- enable(chainId: string | string[]): Promise<void>;
43
- getKey(chainId: string): Promise<{
44
- bech32Address: string;
45
- }>;
46
- signArbitrary(chainId: string, signer: string, data: string): Promise<{
47
- signature: string;
48
- pub_key: {
49
- type: string;
50
- value: string;
51
- };
52
- }>;
53
- /** Adds a chain the wallet does not know, after the user approves it. */
54
- experimentalSuggestChain?(chainInfo: CosmosChain["chainInfo"]): Promise<void>;
55
- };
56
- /** A wallet found in the page, ready to pass to `relay.wallets.link`. */
57
- type DiscoveredWallet = {
58
- id: string;
59
- name: string;
60
- icon?: string;
61
- signer: WalletSigner;
62
- };
63
- /** Signs with an EIP-1193 provider through `personal_sign`. */
64
- declare function evmSigner(provider: Eip1193Provider, info?: {
65
- name?: string;
66
- }): WalletSigner;
67
- /** Signs with a legacy injected Solana provider, such as `window.phantom.solana`. */
68
- declare function solanaSigner(provider: SolanaInjectedProvider, info?: {
69
- name?: string;
70
- }): WalletSigner;
71
- /** Signs with a Wallet Standard wallet's `solana:signMessage` feature. */
72
- declare function walletStandardSolanaSigner(wallet: StandardWallet): WalletSigner;
73
- /**
74
- * Signs an ADR-36 message with Keplr or a wallet that implements its API, on the app's chain:
75
- * `{ chainId, chainInfo? }` or `"cosmos:<chain ID>"`. When the wallet does not know the chain and
76
- * `chainInfo` is given, it suggests the chain to the wallet (`experimentalSuggestChain`) and tries
77
- * again; without `chainInfo`, or with a wallet that cannot add chains, it throws an error that
78
- * names the chain. Other failures, such as a rejected request, pass through.
79
- */
80
- declare function cosmosSigner(provider: KeplrLike, chain: CosmosChain | CosmosNetwork, info?: {
81
- name?: string;
82
- }): WalletSigner;
83
- /** EIP-6963 wallets, or `window.ethereum` when none announce themselves within `timeoutMs`. */
84
- declare function discoverEvmWallets(timeoutMs?: number): Promise<DiscoveredWallet[]>;
85
- /** Wallet Standard wallets that can sign Solana messages, then legacy injected providers. */
86
- declare function discoverSolanaWallets(): DiscoveredWallet[];
87
- /**
88
- * Keplr, Leap and Cosmostation, each signing on the app's chain (see `cosmosSigner`). IDs end with
89
- * the chain ID.
90
- */
91
- declare function discoverCosmosWallets(chain: CosmosChain | CosmosNetwork): DiscoveredWallet[];
92
- /**
93
- * The Cosmos SDK chains an app offers wallets on: one chain or several, each as
94
- * `{ chainId, chainInfo? }` or `"cosmos:<chain ID>"`. Relay has no chain list of its own.
95
- */
96
- type CosmosChains = CosmosChain | CosmosNetwork | readonly (CosmosChain | CosmosNetwork)[];
97
- /** The chains in `CosmosChains`, as a list. */
98
- declare function cosmosChainList(chains: CosmosChains | undefined): (CosmosChain | CosmosNetwork)[];
99
- /** An installed wallet that can sign in on one of the project's enabled wallet families. */
100
- type SignInWallet = DiscoveredWallet & {
101
- network: WalletSignInNetwork;
102
- };
103
- /**
104
- * The wallets installed in this browser that can sign in with `families`: EVM wallets first, then
105
- * Solana wallets, then Cosmos wallets once per chain in `cosmos`. Without `cosmos` there are no
106
- * Cosmos wallets. Empty during SSR.
107
- */
108
- declare function discoverSignInWallets(families: readonly WalletSignInNetwork[], cosmos?: CosmosChains): Promise<SignInWallet[]>;
5
+ import { m as WalletSignInNetwork, o as WalletSigner } from './wallet-DQtJelQQ.js';
6
+ import { C as CosmosChains } from './wallet-browser-dpmr22Xv.js';
109
7
 
110
8
  type Auth = ReturnType<typeof createRelayClient>["auth"];
111
9
  /**
@@ -286,4 +184,4 @@ declare function signInOptions(relay: SignInClient, input?: {
286
184
  */
287
185
  declare function telegramMiniAppInitData(): string | null;
288
186
 
289
- export { type CosmosChains as C, type DiscoveredWallet as D, type Eip1193Provider as E, type KeplrLike as K, type OAuthSignInOption as O, type ProviderSignInOption as P, type SignInClient as S, type TelegramSignInOption as T, type WalletSignInOption as W, type EmailSignInOption as a, type SignInIcon as b, type SignInMethods as c, type SignInOption as d, type SignInOptions as e, type SignInUnavailable as f, type SignInWallet as g, type SolanaInjectedProvider as h, type StandardWallet as i, type StandardWalletAccount as j, cosmosChainList as k, cosmosSigner as l, discoverCosmosWallets as m, discoverEvmWallets as n, discoverSignInWallets as o, discoverSolanaWallets as p, evmSigner as q, solanaSigner as r, signInOptions as s, telegramMiniAppInitData as t, walletStandardSolanaSigner as w };
187
+ export { type EmailSignInOption as E, type OAuthSignInOption as O, type ProviderSignInOption as P, type SignInClient as S, type TelegramSignInOption as T, type WalletSignInOption as W, type SignInIcon as a, type SignInMethods as b, type SignInOption as c, type SignInOptions as d, type SignInUnavailable as e, signInOptions as s, telegramMiniAppInitData as t };