@utxopia/sdk 0.1.0-alpha.1

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 (94) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +171 -0
  3. package/package.json +108 -0
  4. package/packages/btc-client/src/esplora-client.ts +153 -0
  5. package/packages/btc-client/src/index.ts +3 -0
  6. package/packages/btc-client/src/op-return.ts +93 -0
  7. package/packages/btc-client/src/types.ts +112 -0
  8. package/packages/sdk/README.md +277 -0
  9. package/packages/sdk/dist/announcement-client.d.ts +64 -0
  10. package/packages/sdk/dist/announcement-client.js +337 -0
  11. package/packages/sdk/dist/auditor-ciphertext.d.ts +72 -0
  12. package/packages/sdk/dist/auditor-ciphertext.js +135 -0
  13. package/packages/sdk/dist/auditor.d.ts +115 -0
  14. package/packages/sdk/dist/auditor.js +292 -0
  15. package/packages/sdk/dist/bitcoin/ika.d.ts +47 -0
  16. package/packages/sdk/dist/bitcoin/ika.js +74 -0
  17. package/packages/sdk/dist/bitcoin/index.d.ts +2 -0
  18. package/packages/sdk/dist/bitcoin/index.js +1 -0
  19. package/packages/sdk/dist/bound-params.d.ts +96 -0
  20. package/packages/sdk/dist/bound-params.js +249 -0
  21. package/packages/sdk/dist/chadbuffer.d.ts +124 -0
  22. package/packages/sdk/dist/chadbuffer.js +405 -0
  23. package/packages/sdk/dist/claim-link.d.ts +30 -0
  24. package/packages/sdk/dist/claim-link.js +50 -0
  25. package/packages/sdk/dist/client.d.ts +233 -0
  26. package/packages/sdk/dist/client.js +416 -0
  27. package/packages/sdk/dist/commitment-tree.d.ts +268 -0
  28. package/packages/sdk/dist/commitment-tree.js +564 -0
  29. package/packages/sdk/dist/config.d.ts +177 -0
  30. package/packages/sdk/dist/config.js +426 -0
  31. package/packages/sdk/dist/core/esplora.d.ts +110 -0
  32. package/packages/sdk/dist/core/esplora.js +187 -0
  33. package/packages/sdk/dist/core/mempool.d.ts +60 -0
  34. package/packages/sdk/dist/core/mempool.js +107 -0
  35. package/packages/sdk/dist/crypto-babyjub.d.ts +105 -0
  36. package/packages/sdk/dist/crypto-babyjub.js +312 -0
  37. package/packages/sdk/dist/crypto-ed25519.d.ts +116 -0
  38. package/packages/sdk/dist/crypto-ed25519.js +235 -0
  39. package/packages/sdk/dist/crypto.d.ts +59 -0
  40. package/packages/sdk/dist/crypto.js +140 -0
  41. package/packages/sdk/dist/event-client.d.ts +64 -0
  42. package/packages/sdk/dist/event-client.js +165 -0
  43. package/packages/sdk/dist/events.d.ts +127 -0
  44. package/packages/sdk/dist/events.js +305 -0
  45. package/packages/sdk/dist/explorer.d.ts +86 -0
  46. package/packages/sdk/dist/explorer.js +197 -0
  47. package/packages/sdk/dist/index.d.ts +61 -0
  48. package/packages/sdk/dist/index.js +216 -0
  49. package/packages/sdk/dist/instructions.d.ts +1125 -0
  50. package/packages/sdk/dist/instructions.js +1760 -0
  51. package/packages/sdk/dist/keys.d.ts +467 -0
  52. package/packages/sdk/dist/keys.js +799 -0
  53. package/packages/sdk/dist/logger.d.ts +10 -0
  54. package/packages/sdk/dist/logger.js +40 -0
  55. package/packages/sdk/dist/magicblock.d.ts +90 -0
  56. package/packages/sdk/dist/magicblock.js +164 -0
  57. package/packages/sdk/dist/merkle.d.ts +82 -0
  58. package/packages/sdk/dist/merkle.js +141 -0
  59. package/packages/sdk/dist/note.d.ts +348 -0
  60. package/packages/sdk/dist/note.js +483 -0
  61. package/packages/sdk/dist/pda.d.ts +160 -0
  62. package/packages/sdk/dist/pda.js +384 -0
  63. package/packages/sdk/dist/pool-state.d.ts +100 -0
  64. package/packages/sdk/dist/pool-state.js +126 -0
  65. package/packages/sdk/dist/poseidon.d.ts +53 -0
  66. package/packages/sdk/dist/poseidon.js +136 -0
  67. package/packages/sdk/dist/prover/index.d.ts +10 -0
  68. package/packages/sdk/dist/prover/index.js +10 -0
  69. package/packages/sdk/dist/prover/mobile.d.ts +45 -0
  70. package/packages/sdk/dist/prover/mobile.js +227 -0
  71. package/packages/sdk/dist/prover/web.d.ts +136 -0
  72. package/packages/sdk/dist/prover/web.js +597 -0
  73. package/packages/sdk/dist/psbt.d.ts +73 -0
  74. package/packages/sdk/dist/psbt.js +202 -0
  75. package/packages/sdk/dist/selective-disclosure.d.ts +181 -0
  76. package/packages/sdk/dist/selective-disclosure.js +172 -0
  77. package/packages/sdk/dist/sender-memo.d.ts +149 -0
  78. package/packages/sdk/dist/sender-memo.js +250 -0
  79. package/packages/sdk/dist/sns-resolver.d.ts +121 -0
  80. package/packages/sdk/dist/sns-resolver.js +229 -0
  81. package/packages/sdk/dist/solana/connection.d.ts +77 -0
  82. package/packages/sdk/dist/solana/connection.js +133 -0
  83. package/packages/sdk/dist/solana/priority-fee.d.ts +78 -0
  84. package/packages/sdk/dist/solana/priority-fee.js +137 -0
  85. package/packages/sdk/dist/stealth.d.ts +429 -0
  86. package/packages/sdk/dist/stealth.js +703 -0
  87. package/packages/sdk/dist/taproot.d.ts +172 -0
  88. package/packages/sdk/dist/taproot.js +494 -0
  89. package/packages/sdk/dist/token-registry.d.ts +96 -0
  90. package/packages/sdk/dist/token-registry.js +122 -0
  91. package/packages/sdk/dist/utils/encoding.d.ts +19 -0
  92. package/packages/sdk/dist/utils/encoding.js +29 -0
  93. package/packages/sdk/dist/vk-registry.d.ts +100 -0
  94. package/packages/sdk/dist/vk-registry.js +212 -0
@@ -0,0 +1,305 @@
1
+ /**
2
+ * Event parser for UTXOpia sol_log_data events
3
+ *
4
+ * Events are emitted by the on-chain program as base64-encoded log data.
5
+ * Transaction logs contain lines like: "Program data: <base64>"
6
+ * Each base64 segment decodes to one slice from sol_log_data.
7
+ *
8
+ * ## Events
9
+ *
10
+ * - 0x02 NullifierSpent: disc(1) + hash(32) + op_type(1) = 34 bytes
11
+ * - 0x03 StealthAnnouncement: disc(1) + type(1) + ephemeral(32) + amount(8) + commitment(32) + leaf_index(4) = 78 bytes
12
+ * - 0x0B NullifiersBatch: flat payload in single segment
13
+ * - 0x0C AnnouncementsBatch: flat payload in single segment
14
+ */
15
+ /** Event discriminators matching contracts/programs/utxopia/src/utils/events.rs */
16
+ export const EVENT_NULLIFIER_SPENT = 0x02;
17
+ export const EVENT_STEALTH_ANNOUNCEMENT = 0x03;
18
+ export const EVENT_NULLIFIERS_BATCH = 0x0b;
19
+ export const EVENT_ANNOUNCEMENTS_BATCH = 0x0c;
20
+ /** Phase 2: sender memo (XChaCha20-Poly1305 AEAD payload). */
21
+ export const EVENT_SENDER_MEMO = 0x12;
22
+ export const EVENT_BTC_ORIGIN_ATTESTATION = 0x15;
23
+ /** Method-Y: auditor ciphertext emitted alongside every shielded deposit into a permissioned pool. */
24
+ export const EVENT_AUDITOR_CIPHERTEXT = 0x16;
25
+ /**
26
+ * Parse a nullifier spent event from decoded sol_log_data segments.
27
+ * Expected: disc(1) + nullifier_hash(32) + op_type(1)
28
+ */
29
+ export function parseNullifierSpentEvent(segments) {
30
+ if (segments.length < 3)
31
+ return null;
32
+ if (segments[0].length !== 1 || segments[0][0] !== EVENT_NULLIFIER_SPENT)
33
+ return null;
34
+ const nullifierHash = segments[1];
35
+ if (nullifierHash.length !== 32)
36
+ return null;
37
+ const opType = segments[2];
38
+ if (opType.length !== 1)
39
+ return null;
40
+ return {
41
+ type: "nullifier_spent",
42
+ nullifierHash,
43
+ operationType: opType[0],
44
+ };
45
+ }
46
+ /**
47
+ * Parse a stealth announcement event from decoded sol_log_data segments.
48
+ * v1: disc(1) + type(1) + ephemeral_pub(32) + encrypted_amount(8) + commitment(32) + leaf_index(4) = 6 segments
49
+ * v2: + token_id(32) = 7 segments
50
+ */
51
+ export function parseStealthAnnouncementEvent(segments) {
52
+ if (segments.length < 6)
53
+ return null;
54
+ if (segments[0].length !== 1 || segments[0][0] !== EVENT_STEALTH_ANNOUNCEMENT)
55
+ return null;
56
+ const atype = segments[1];
57
+ if (atype.length !== 1)
58
+ return null;
59
+ const ephemeralPub = segments[2];
60
+ if (ephemeralPub.length !== 32)
61
+ return null;
62
+ const encryptedAmount = segments[3];
63
+ if (encryptedAmount.length !== 8)
64
+ return null;
65
+ const commitment = segments[4];
66
+ if (commitment.length !== 32)
67
+ return null;
68
+ const liBytes = segments[5];
69
+ if (liBytes.length !== 4)
70
+ return null;
71
+ const view = new DataView(liBytes.buffer, liBytes.byteOffset, 4);
72
+ const leafIndex = view.getUint32(0, true);
73
+ // v2: token_id at segment 6
74
+ let tokenId;
75
+ if (segments.length >= 7 && segments[6].length === 32) {
76
+ tokenId = segments[6];
77
+ }
78
+ return {
79
+ type: "stealth_announcement",
80
+ announcementType: atype[0],
81
+ ephemeralPub,
82
+ encryptedAmount,
83
+ commitment,
84
+ leafIndex,
85
+ tokenId,
86
+ };
87
+ }
88
+ /**
89
+ * Parse an association-set update event (Phase 3) from decoded sol_log_data segments.
90
+ * Layout: disc(1) + new_root(32) + status(1) + version_le(8)
91
+ */
92
+ /**
93
+ * Parse a BTC origin attestation event from decoded sol_log_data segments.
94
+ * Layout: disc(1) + block_height(8 LE) + deposit_txid(32) + sweep_vout(4 LE)
95
+ * + commitment(32) + amount_sats(8 LE)
96
+ */
97
+ export function parseBtcOriginAttestationEvent(segments) {
98
+ if (segments.length < 6)
99
+ return null;
100
+ if (segments[0].length !== 1 || segments[0][0] !== EVENT_BTC_ORIGIN_ATTESTATION)
101
+ return null;
102
+ const bhBytes = segments[1];
103
+ if (bhBytes.length !== 8)
104
+ return null;
105
+ let blockHeight = 0n;
106
+ for (let i = 7; i >= 0; i--)
107
+ blockHeight = (blockHeight << 8n) | BigInt(bhBytes[i]);
108
+ const depositTxid = segments[2];
109
+ if (depositTxid.length !== 32)
110
+ return null;
111
+ const voutBytes = segments[3];
112
+ if (voutBytes.length !== 4)
113
+ return null;
114
+ const sweepVout = new DataView(voutBytes.buffer, voutBytes.byteOffset, 4).getUint32(0, true);
115
+ const commitment = segments[4];
116
+ if (commitment.length !== 32)
117
+ return null;
118
+ const amtBytes = segments[5];
119
+ if (amtBytes.length !== 8)
120
+ return null;
121
+ let amountSats = 0n;
122
+ for (let i = 7; i >= 0; i--)
123
+ amountSats = (amountSats << 8n) | BigInt(amtBytes[i]);
124
+ return {
125
+ type: "btc_origin_attestation",
126
+ blockHeight,
127
+ depositTxid,
128
+ sweepVout,
129
+ commitment,
130
+ amountSats,
131
+ };
132
+ }
133
+ /**
134
+ * Parse a sender memo event (Phase 2) from decoded sol_log_data segments.
135
+ * Layout: disc(1) + nonce(24) + ciphertext_and_tag(56) + commitment(32) + leaf_index(4)
136
+ */
137
+ export function parseSenderMemoEvent(segments) {
138
+ if (segments.length < 5)
139
+ return null;
140
+ if (segments[0].length !== 1 || segments[0][0] !== EVENT_SENDER_MEMO)
141
+ return null;
142
+ const nonce = segments[1];
143
+ if (nonce.length !== 24)
144
+ return null;
145
+ const ciphertextWithTag = segments[2];
146
+ if (ciphertextWithTag.length !== 56)
147
+ return null;
148
+ const commitment = segments[3];
149
+ if (commitment.length !== 32)
150
+ return null;
151
+ const liBytes = segments[4];
152
+ if (liBytes.length !== 4)
153
+ return null;
154
+ const leafIndex = new DataView(liBytes.buffer, liBytes.byteOffset, 4).getUint32(0, true);
155
+ return { type: "sender_memo", nonce, ciphertextWithTag, commitment, leafIndex };
156
+ }
157
+ /**
158
+ * Parse batched nullifiers from a single flat segment.
159
+ * Layout: disc(1) + count(1) + op_type(1) + [hash(32)] x count
160
+ */
161
+ function parseNullifiersBatch(data) {
162
+ if (data.length < 3)
163
+ return [];
164
+ const count = data[1];
165
+ const opType = data[2];
166
+ const expectedLen = 3 + count * 32;
167
+ if (data.length < expectedLen)
168
+ return [];
169
+ const events = [];
170
+ for (let i = 0; i < count; i++) {
171
+ const offset = 3 + i * 32;
172
+ events.push({
173
+ type: "nullifier_spent",
174
+ nullifierHash: data.slice(offset, offset + 32),
175
+ operationType: opType,
176
+ });
177
+ }
178
+ return events;
179
+ }
180
+ /**
181
+ * Parse batched announcements from a single flat segment.
182
+ * v1: disc(1) + count(1) + [type(1) + ephemeral(32) + amount(8) + commitment(32) + leaf_index(4)] x count (77 per item)
183
+ * v2: disc(1) + count(1) + [type(1) + ephemeral(32) + amount(8) + commitment(32) + leaf_index(4) + token_id(32)] x count (109 per item)
184
+ */
185
+ function parseAnnouncementsBatch(data) {
186
+ if (data.length < 2)
187
+ return [];
188
+ const count = data[1];
189
+ if (count === 0)
190
+ return [];
191
+ // Detect v1 vs v2 by checking total size
192
+ const remainingBytes = data.length - 2;
193
+ const v2ItemSize = 109;
194
+ const v1ItemSize = 77;
195
+ const isV2 = remainingBytes >= count * v2ItemSize;
196
+ const itemSize = isV2 ? v2ItemSize : v1ItemSize;
197
+ const expectedLen = 2 + count * itemSize;
198
+ if (data.length < expectedLen)
199
+ return [];
200
+ const events = [];
201
+ for (let i = 0; i < count; i++) {
202
+ const offset = 2 + i * itemSize;
203
+ const liView = new DataView(data.buffer, data.byteOffset + offset + 73, 4);
204
+ const event = {
205
+ type: "stealth_announcement",
206
+ announcementType: data[offset],
207
+ ephemeralPub: data.slice(offset + 1, offset + 33),
208
+ encryptedAmount: data.slice(offset + 33, offset + 41),
209
+ commitment: data.slice(offset + 41, offset + 73),
210
+ leafIndex: liView.getUint32(0, true),
211
+ };
212
+ if (isV2) {
213
+ event.tokenId = data.slice(offset + 77, offset + 109);
214
+ }
215
+ events.push(event);
216
+ }
217
+ return events;
218
+ }
219
+ /**
220
+ * Parse an auditor ciphertext event (Method-Y) from decoded sol_log_data segments.
221
+ * Layout: disc(1) + commitment(32) + blob(112)
222
+ */
223
+ export function parseAuditorCiphertextEvent(segments) {
224
+ if (segments.length < 3)
225
+ return null;
226
+ if (segments[0].length !== 1 || segments[0][0] !== EVENT_AUDITOR_CIPHERTEXT)
227
+ return null;
228
+ const commitment = segments[1];
229
+ if (commitment.length !== 32)
230
+ return null;
231
+ const blob = segments[2];
232
+ if (blob.length !== 112)
233
+ return null;
234
+ return { type: "auditor_ciphertext", commitment, blob };
235
+ }
236
+ function decodeBase64(b64) {
237
+ const binary = atob(b64);
238
+ const bytes = new Uint8Array(binary.length);
239
+ for (let i = 0; i < binary.length; i++) {
240
+ bytes[i] = binary.charCodeAt(i);
241
+ }
242
+ return bytes;
243
+ }
244
+ /**
245
+ * Parse program events from Solana transaction log messages.
246
+ *
247
+ * sol_log_data emits log lines in the format:
248
+ * "Program data: <base64_segment1> <base64_segment2> ..."
249
+ *
250
+ * @param logs - Array of log message strings from a transaction
251
+ * @param programId - Optional program ID to filter events (matches "Program <id> invoke" blocks)
252
+ */
253
+ export function parseProgramEvents(logs, programId) {
254
+ const events = [];
255
+ const DATA_PREFIX = "Program data: ";
256
+ for (const line of logs) {
257
+ if (!line.startsWith(DATA_PREFIX))
258
+ continue;
259
+ const b64Parts = line.slice(DATA_PREFIX.length).split(" ");
260
+ const segments = b64Parts.map(decodeBase64);
261
+ if (segments.length === 0)
262
+ continue;
263
+ // Handle batch events (single flat segment)
264
+ if (segments.length === 1 && segments[0].length > 1) {
265
+ const disc = segments[0][0];
266
+ if (disc === EVENT_NULLIFIERS_BATCH) {
267
+ events.push(...parseNullifiersBatch(segments[0]));
268
+ continue;
269
+ }
270
+ if (disc === EVENT_ANNOUNCEMENTS_BATCH) {
271
+ events.push(...parseAnnouncementsBatch(segments[0]));
272
+ continue;
273
+ }
274
+ }
275
+ if (segments[0].length !== 1)
276
+ continue;
277
+ const disc = segments[0][0];
278
+ if (disc === EVENT_NULLIFIER_SPENT) {
279
+ const event = parseNullifierSpentEvent(segments);
280
+ if (event)
281
+ events.push(event);
282
+ }
283
+ else if (disc === EVENT_STEALTH_ANNOUNCEMENT) {
284
+ const event = parseStealthAnnouncementEvent(segments);
285
+ if (event)
286
+ events.push(event);
287
+ }
288
+ else if (disc === EVENT_SENDER_MEMO) {
289
+ const event = parseSenderMemoEvent(segments);
290
+ if (event)
291
+ events.push(event);
292
+ }
293
+ else if (disc === EVENT_BTC_ORIGIN_ATTESTATION) {
294
+ const event = parseBtcOriginAttestationEvent(segments);
295
+ if (event)
296
+ events.push(event);
297
+ }
298
+ else if (disc === EVENT_AUDITOR_CIPHERTEXT) {
299
+ const event = parseAuditorCiphertextEvent(segments);
300
+ if (event)
301
+ events.push(event);
302
+ }
303
+ }
304
+ return events;
305
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Explorer utilities for UTXOPIA
3
+ *
4
+ * Types, parsers, and fetchers for browsing on-chain UTXOpia activity:
5
+ * - Deposits (from event indexer)
6
+ * - Transfers (from event indexer)
7
+ * - Redemptions (RedemptionRequest accounts)
8
+ */
9
+ import type { RpcClient } from "./commitment-tree";
10
+ /** NullifierRecord account size (1 byte — slim layout, just discriminator) */
11
+ export declare const NULLIFIER_RECORD_SIZE = 1;
12
+ /** RedemptionRequest account size (178 bytes):
13
+ * disc(1) status(1) btc_script_len(1) signing_approved(1) processing_slot(4) request_id(8)
14
+ * requester(32) amount_sats(8) service_fee(8) total_input_sats(8) btc_script(34)
15
+ * token_id(32) reserved_count(1) approved_inputs(4) _padding2(3) inputs_commitment(32).
16
+ *
17
+ * This is a `dataSize` filter, so a stale value silently returns nothing rather than failing:
18
+ * it sat at 138 — the struct's length before reserved_count/approved_inputs/inputs_commitment
19
+ * were added — and matched no account on chain. `RedemptionRequest::LEN` is pinned by a test
20
+ * on the program side; update both together. Field offsets below are unaffected. */
21
+ export declare const REDEMPTION_REQUEST_SIZE = 178;
22
+ /** NullifierRecord discriminator byte */
23
+ export declare const NULLIFIER_RECORD_DISCRIMINATOR = 3;
24
+ /** RedemptionRequest discriminator byte */
25
+ export declare const REDEMPTION_REQUEST_DISCRIMINATOR = 4;
26
+ /** Human-readable labels for nullifier operation types */
27
+ export declare const OPERATION_TYPE_LABELS: Record<number, string>;
28
+ /** Parsed deposit from indexer event data */
29
+ export interface ExplorerDeposit {
30
+ pubkey: string;
31
+ amountSats: bigint;
32
+ leafIndex: bigint;
33
+ /** Commitment hex (from indexer events, not on-chain) */
34
+ commitment?: string;
35
+ /** Unix timestamp (from indexer events, not on-chain) */
36
+ createdAt?: number;
37
+ /** Ephemeral public key hex (from stealth announcement) */
38
+ ephemeralPub?: string;
39
+ /** Solana transaction signature */
40
+ txSignature?: string;
41
+ }
42
+ /** Transfer event — either a new commitment or a spent nullifier */
43
+ export interface ExplorerTransferEvent {
44
+ type: "commitment" | "nullifier";
45
+ pubkey: string;
46
+ timestamp: number;
47
+ commitment?: string;
48
+ leafIndex?: bigint;
49
+ nullifierHash?: string;
50
+ operationType?: string;
51
+ spentBy?: string;
52
+ }
53
+ /** Parsed redemption request */
54
+ export interface ExplorerRedemption {
55
+ pubkey: string;
56
+ requestId: bigint;
57
+ amountSats: bigint;
58
+ /** Service fee in satoshis, locked at request time */
59
+ serviceFee: bigint;
60
+ status: "Pending" | "Processing" | "Failed";
61
+ requester: string;
62
+ btcScript: string;
63
+ /** Slot when processing started (from PDA data[4..8]) — 0 if still Pending */
64
+ processingSlot: number;
65
+ }
66
+ /** Parse a NullifierRecord account (1 byte — slim layout)
67
+ * Only confirms existence (discriminator = 0x03). Metadata from indexer events. */
68
+ export declare function parseNullifierRecord(pubkey: string, _data: Uint8Array): ExplorerTransferEvent;
69
+ /** Parse a RedemptionRequest account (138 bytes, raw scriptPubKey) */
70
+ export declare function parseRedemptionRequest(pubkey: string, data: Uint8Array): ExplorerRedemption;
71
+ /** Indexer leaf data for enriching explorer deposits */
72
+ export interface IndexerLeaf {
73
+ leaf_index: number;
74
+ commitment: string;
75
+ created_at: number;
76
+ announcement_type?: number;
77
+ amount_sats?: number;
78
+ ephemeral_pub?: string;
79
+ tx_signature?: string;
80
+ }
81
+ /** Fetch all deposit announcements from indexer data */
82
+ export declare function fetchExplorerDeposits(_rpc: RpcClient, _programId: string, indexerLeaves?: IndexerLeaf[]): Promise<ExplorerDeposit[]>;
83
+ /** Fetch all transfer events from indexer data */
84
+ export declare function fetchExplorerTransfers(_rpc: RpcClient, _programId: string, indexerLeaves?: IndexerLeaf[]): Promise<ExplorerTransferEvent[]>;
85
+ /** Fetch all redemption requests */
86
+ export declare function fetchExplorerRedemptions(rpc: RpcClient, programId: string): Promise<ExplorerRedemption[]>;
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Explorer utilities for UTXOPIA
3
+ *
4
+ * Types, parsers, and fetchers for browsing on-chain UTXOpia activity:
5
+ * - Deposits (from event indexer)
6
+ * - Transfers (from event indexer)
7
+ * - Redemptions (RedemptionRequest accounts)
8
+ */
9
+ // =============================================================================
10
+ // Constants
11
+ // =============================================================================
12
+ /** NullifierRecord account size (1 byte — slim layout, just discriminator) */
13
+ export const NULLIFIER_RECORD_SIZE = 1;
14
+ /** RedemptionRequest account size (178 bytes):
15
+ * disc(1) status(1) btc_script_len(1) signing_approved(1) processing_slot(4) request_id(8)
16
+ * requester(32) amount_sats(8) service_fee(8) total_input_sats(8) btc_script(34)
17
+ * token_id(32) reserved_count(1) approved_inputs(4) _padding2(3) inputs_commitment(32).
18
+ *
19
+ * This is a `dataSize` filter, so a stale value silently returns nothing rather than failing:
20
+ * it sat at 138 — the struct's length before reserved_count/approved_inputs/inputs_commitment
21
+ * were added — and matched no account on chain. `RedemptionRequest::LEN` is pinned by a test
22
+ * on the program side; update both together. Field offsets below are unaffected. */
23
+ export const REDEMPTION_REQUEST_SIZE = 178;
24
+ /** NullifierRecord discriminator byte */
25
+ export const NULLIFIER_RECORD_DISCRIMINATOR = 0x03;
26
+ /** RedemptionRequest discriminator byte */
27
+ export const REDEMPTION_REQUEST_DISCRIMINATOR = 0x04;
28
+ /** Max plausible plaintext amount: 21M BTC in sats */
29
+ const MAX_PLAINTEXT_SATS = 21000000n * 100000000n;
30
+ /** Human-readable labels for nullifier operation types */
31
+ export const OPERATION_TYPE_LABELS = {
32
+ 0: "Full Withdrawal",
33
+ 1: "Partial Withdrawal",
34
+ 2: "Private Transfer",
35
+ 3: "Transfer",
36
+ 4: "Split",
37
+ 5: "Join",
38
+ };
39
+ // =============================================================================
40
+ // Helpers
41
+ // =============================================================================
42
+ function toHex(bytes) {
43
+ return Array.from(bytes)
44
+ .map((b) => b.toString(16).padStart(2, "0"))
45
+ .join("");
46
+ }
47
+ function readU64LE(data, offset) {
48
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
49
+ return view.getBigUint64(offset, true);
50
+ }
51
+ function readI64LE(data, offset) {
52
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
53
+ return Number(view.getBigInt64(offset, true));
54
+ }
55
+ function bs58Encode(bytes) {
56
+ const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
57
+ let num = 0n;
58
+ for (const byte of bytes) {
59
+ num = num * 256n + BigInt(byte);
60
+ }
61
+ let encoded = "";
62
+ while (num > 0n) {
63
+ const remainder = num % 58n;
64
+ num = num / 58n;
65
+ encoded = ALPHABET[Number(remainder)] + encoded;
66
+ }
67
+ for (const byte of bytes) {
68
+ if (byte === 0)
69
+ encoded = "1" + encoded;
70
+ else
71
+ break;
72
+ }
73
+ return encoded || "1";
74
+ }
75
+ function decodeBase64(b64) {
76
+ const binary = atob(b64);
77
+ const bytes = new Uint8Array(binary.length);
78
+ for (let i = 0; i < binary.length; i++) {
79
+ bytes[i] = binary.charCodeAt(i);
80
+ }
81
+ return bytes;
82
+ }
83
+ // =============================================================================
84
+ // Parsers
85
+ // =============================================================================
86
+ /** Parse a NullifierRecord account (1 byte — slim layout)
87
+ * Only confirms existence (discriminator = 0x03). Metadata from indexer events. */
88
+ export function parseNullifierRecord(pubkey, _data) {
89
+ return {
90
+ type: "nullifier",
91
+ pubkey,
92
+ timestamp: 0, // metadata available from indexer
93
+ };
94
+ }
95
+ /** Parse a RedemptionRequest account (138 bytes, raw scriptPubKey) */
96
+ export function parseRedemptionRequest(pubkey, data) {
97
+ const statusByte = data[1];
98
+ const status = statusByte === 1 ? "Processing" : statusByte === 2 ? "Failed" : "Pending";
99
+ const scriptLen = data[2];
100
+ // data[3] = padding, data[4..8] = processing_slot (u32 LE)
101
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
102
+ const processingSlot = view.getUint32(4, true);
103
+ return {
104
+ pubkey,
105
+ requestId: readU64LE(data, 8),
106
+ amountSats: readU64LE(data, 48),
107
+ serviceFee: readU64LE(data, 56),
108
+ status,
109
+ requester: bs58Encode(data.slice(16, 48)),
110
+ // btc_script starts at offset 72 (after total_input_sats at 64..72).
111
+ btcScript: toHex(data.slice(72, 72 + Math.min(scriptLen, 34))),
112
+ processingSlot,
113
+ };
114
+ }
115
+ // =============================================================================
116
+ // RPC helpers
117
+ // =============================================================================
118
+ async function fetchAccountsBySize(rpc, programId, dataSize) {
119
+ const accounts = await rpc.getProgramAccounts(programId, {
120
+ filters: [{ dataSize }],
121
+ encoding: "base64",
122
+ });
123
+ return accounts.map((acc) => {
124
+ const raw = typeof acc.account.data === "string"
125
+ ? acc.account.data
126
+ : // @solana/kit returns [base64String, "base64"]
127
+ acc.account.data[0];
128
+ return {
129
+ pubkey: String(acc.pubkey),
130
+ data: decodeBase64(raw),
131
+ };
132
+ });
133
+ }
134
+ /** Fetch all deposit announcements from indexer data */
135
+ export async function fetchExplorerDeposits(_rpc, _programId, indexerLeaves) {
136
+ if (!indexerLeaves || indexerLeaves.length === 0)
137
+ return [];
138
+ return indexerLeaves
139
+ .filter((leaf) => leaf.announcement_type === 0) // deposits only
140
+ .map((leaf) => ({
141
+ pubkey: "", // no PDA — data comes from events
142
+ amountSats: BigInt(leaf.amount_sats ?? 0),
143
+ leafIndex: BigInt(leaf.leaf_index),
144
+ commitment: leaf.commitment,
145
+ createdAt: leaf.created_at,
146
+ ephemeralPub: leaf.ephemeral_pub,
147
+ txSignature: leaf.tx_signature,
148
+ }))
149
+ .sort((a, b) => {
150
+ const aHasTime = (a.createdAt ?? 0) > 0;
151
+ const bHasTime = (b.createdAt ?? 0) > 0;
152
+ if (aHasTime && bHasTime)
153
+ return (b.createdAt ?? 0) - (a.createdAt ?? 0);
154
+ if (aHasTime && !bHasTime)
155
+ return -1;
156
+ if (!aHasTime && bHasTime)
157
+ return 1;
158
+ return Number(b.leafIndex - a.leafIndex);
159
+ });
160
+ }
161
+ /** Fetch all transfer events from indexer data */
162
+ export async function fetchExplorerTransfers(_rpc, _programId, indexerLeaves) {
163
+ if (!indexerLeaves || indexerLeaves.length === 0)
164
+ return [];
165
+ const events = [];
166
+ for (const leaf of indexerLeaves) {
167
+ if (leaf.announcement_type === 0)
168
+ continue; // skip deposits
169
+ events.push({
170
+ type: "commitment",
171
+ pubkey: "",
172
+ timestamp: leaf.created_at ?? 0,
173
+ commitment: leaf.commitment,
174
+ leafIndex: BigInt(leaf.leaf_index),
175
+ });
176
+ }
177
+ // Sort by timestamp descending (most recent first); if no timestamp, by leafIndex high→low
178
+ events.sort((a, b) => {
179
+ const aHasTime = a.timestamp > 0;
180
+ const bHasTime = b.timestamp > 0;
181
+ if (aHasTime && bHasTime)
182
+ return b.timestamp - a.timestamp;
183
+ if (aHasTime && !bHasTime)
184
+ return -1;
185
+ if (!aHasTime && bHasTime)
186
+ return 1;
187
+ return Number((b.leafIndex ?? 0n) - (a.leafIndex ?? 0n));
188
+ });
189
+ return events;
190
+ }
191
+ /** Fetch all redemption requests */
192
+ export async function fetchExplorerRedemptions(rpc, programId) {
193
+ const accounts = await fetchAccountsBySize(rpc, programId, REDEMPTION_REQUEST_SIZE);
194
+ return accounts
195
+ .map(({ pubkey, data }) => parseRedemptionRequest(pubkey, data))
196
+ .sort((a, b) => Number(b.requestId - a.requestId));
197
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * UTXOpia SDK v3.0 (JoinSplit Architecture)
3
+ *
4
+ * Complete client library for interacting with the UTXOpia protocol.
5
+ * Private Bitcoin using ZK proofs.
6
+ *
7
+ * Networks: Solana deployments + Bitcoin testnet4/regtest/mainnet
8
+ *
9
+ * ## Quick Start
10
+ * ```typescript
11
+ * import { createNonInteractiveDeposit, generateJoinSplitProof, buildTransactInstruction } from '@utxopia/sdk';
12
+ *
13
+ * // 1. DEPOSIT: Generate BTC address + compact OP_RETURN payload.
14
+ * const deposit = await createNonInteractiveDeposit(meta, custodyInternalKey, 'testnet', undefined, opReturnContext);
15
+ * console.log('Send BTC to:', deposit.btcAddress);
16
+ *
17
+ * // 2. TRANSACT: JoinSplit proof for private transfer
18
+ * const proof = await generateJoinSplitProof(inputs);
19
+ *
20
+ * // 3. BUILD: Create Solana instruction
21
+ * const ix = buildTransactInstruction(options);
22
+ * ```
23
+ */
24
+ export { bigintToBytes, bytesToBigint, hexToBytes, bytesToHex, sha256Hash, x25519Ecdh, ed25519GenerateKeyPair, ed25519PubToX25519, ed25519PrivToX25519, x25519PubFromPriv, x25519EcdhRaw, encryptAmountEd25519, decryptAmountEd25519, randomFieldElement, BN254_FIELD_PRIME, babyJubMul, BABYJUB_BASE8, } from "./crypto";
25
+ export { deriveKeysFromWallet, deriveKeysFromSeed, deriveKeysFromSeedCircuit, deriveKeysFromAuthSignature, setupKeysFromAuthSignature, generateRandomAuthSignature, setupKeysFromWallet, setupKeysFromSeed, recreateStealthAddress, eddsaPoseidonSign, eddsaPoseidonSignWithScalar, eddsaGetPrivScalar, eddsaGetPubKey, createStealthMetaAddress, serializeStealthMetaAddress, deserializeStealthMetaAddress, encodeStealthMetaAddress, decodeStealthMetaAddress, clearUTXOpiaKeys, serializeKeysForStorage, deserializeKeysFromStorage, PASSKEY_CHAIN_SCOPE_DOMAIN, deriveChainScopedPasskeySeed, passkeyStorageOwner, type UTXOpiaKeys, type KeySetupResult, type AuthSignatureKeyDerivationOptions, type AuthSignatureKeySetupResult, type ChainScopedPasskeyOptions, type PasskeyChainScope, type SerializedKeysForStorage, type StealthMetaAddress, type WalletSignerAdapter, } from "./keys";
26
+ export { ViewPermissions, hasPermission, isDelegatedKeyValid, isSlotInDelegatedRange, createDelegatedViewKey, serializeDelegatedViewKey, deserializeDelegatedViewKey, makeDelegationRecord, fingerprintDelegatedKey, clearDelegatedViewKey, extractViewOnlyBundle, type DelegatedViewKey, type DelegationRecord, } from "./keys";
27
+ export { auditScan, auditScanCiphertexts, auditRecordsToCsv, type AuditDirection, type AuditRecord, type AuditScanAnnouncement, type AuditScanOptions, type AuditScanSummary, type OnChainSenderMemo, } from "./auditor";
28
+ export { encryptAuditorCiphertext, decryptAuditorCiphertext, buildAuditorCiphertextForNote, resolveAuditorCiphertext, AUDITOR_CIPHERTEXT_BYTES, type AuditorNotePlain, type AuditorCiphertextInput, } from "./auditor-ciphertext";
29
+ export { generateAuditorViewingKeypair, deriveAuditorViewingKeypair, } from "./keys";
30
+ export { encryptSenderMemo, decryptSenderMemo, deriveOutgoingViewingKey, packSenderMemo, unpackSenderMemo, packSenderMemoForInstruction, buildSenderMemosForTransact, generateSenderMemoNonce, SENDER_MEMO_AMOUNT_BYTES, SENDER_MEMO_CIPHERTEXT_BYTES, SENDER_MEMO_COMMITMENT_BYTES, SENDER_MEMO_NONCE_BYTES, SENDER_MEMO_PACKED_BYTES, SENDER_MEMO_TAG_BYTES, SENDER_MEMO_TOKEN_BYTES, type SenderMemoPlain, type SenderMemoCiphertext, type SenderMemoOutput, } from "./sender-memo";
31
+ export { generateOwnershipProof, generateRangeSumProof, computeRangeSumAttestation, pickRangeSumVariant, RANGE_SUM_N, RANGE_SUM_VARIANTS, RANGE_SUM_SIZES, type OwnershipProofInputs, type OwnershipPublicInputs, type RangeSumAttestationStyle, type RangeSumProofInputs, type RangeSumPublicInputs, } from "./selective-disclosure";
32
+ export { initPoseidon, isPoseidonReady, poseidonHashSync, computeUnifiedCommitmentSync, computeNullifierSync, hashNullifierSync, computeMPKSync, computeNPKSync, computeJoinSplitCommitmentSync, computeJoinSplitNullifierSync, computeTokenId, reduceToField, } from "./poseidon";
33
+ export { fetchTokenConfig, getTokenId, fetchSupportedTokens, fetchEnabledTokens, parseTokenConfig, type TokenConfigData, type SupportedToken, } from "./token-registry";
34
+ export { MAGICBLOCK_DELEGATION_PROGRAM_ID, MAGICBLOCK_DEVNET_ROUTER_URL, MAGICBLOCK_DEVNET_ROUTER_WS_URL, MAGICBLOCK_EPHEMERAL_VAULT_ID, MAGICBLOCK_MAGIC_CONTEXT_ID, MAGICBLOCK_MAGIC_PROGRAM_ID, MAGICBLOCK_MAX_PER_MEMBERS, MAGICBLOCK_PERMISSION_PROGRAM_ID, MAGICBLOCK_PER_MEMBER_FLAGS, MAGICBLOCK_VALIDATOR_IDENTITIES, buildDefaultPrivacyDomain, buildMagicBlockPerMemberFlags, deriveMagicBlockCommitRecordPDA, deriveMagicBlockCommitStatePDA, deriveMagicBlockDelegateBufferPDA, deriveMagicBlockDelegationMetadataPDA, deriveMagicBlockDelegationRecordPDA, deriveMagicBlockPermissionPDA, deriveMagicBlockUndelegateBufferPDA, requiresMagicBlockEndpoint, getMagicBlockEndpoint, getMagicBlockValidatorIdentity, createMagicBlockRouterConnection, type BuildPrivacyDomainOptions, type MagicBlockEndpointConfig, type MagicBlockExecutionMode, type MagicBlockPolicyMode, type MagicBlockPerMemberFlagName, type MagicBlockValidatorRegion, type PrivacyDomainConfig, type PrivacyDomainKind, } from "./magicblock";
35
+ export { generateNote, createNoteFromSecrets, serializeNote, deserializeNote, noteHasComputedHashes, getNotePublicKeyX, computeNoteCommitment, computeNoteNullifier, formatBtc, parseBtc, deriveNote, deriveNotes, deriveMasterKey, deriveNoteFromMaster, estimateSeedStrength, createNote, prepareWithdrawal, createStealthNote, serializeStealthNote, deserializeStealthNote, type Note, type SerializedNote, type NoteData, type StealthNote, type SerializedStealthNote, createJoinSplitNote, computeJoinSplitNoteNullifier, serializeJoinSplitNote, deserializeJoinSplitNote, type JoinSplitNote, type SerializedJoinSplitNote, } from "./note";
36
+ export { createMerkleProof, createMerkleProofFromBigints, proofToCircomFormat, proofToOnChainFormat, createEmptyMerkleProof, leafIndexToPathIndices, pathIndicesToLeafIndex, validateMerkleProofStructure, parseMerkleProofResponse, TREE_DEPTH, ROOT_HISTORY_SIZE, MAX_LEAVES, ZERO_VALUE, type MerkleProof, } from "./merkle";
37
+ export { deriveTaprootAddress, deriveTaprootAddressWithRefund, buildRefundScript, computeTapLeafHash, verifyTaprootAddress, createP2TRScriptPubkey, parseP2TRScriptPubkey, isValidBitcoinAddress, getInternalKey, createCustomInternalKey, createOpReturnScriptFromPayload, buildDepositOpReturn, parseDepositOpReturn, encodeDepositOpReturnHeader, decodeDepositOpReturnHeader, validateDepositOpReturnContext, computeDepositPoolTag, DEPOSIT_DESTINATION_CHAIN, DEPOSIT_BITCOIN_NETWORK, DEPOSIT_OP_RETURN_VERSION, DEPOSIT_POOL_TAG_SIZE, DEPOSIT_OP_RETURN_SIZE, type DepositDestinationChain, type DepositBitcoinNetwork, type DepositOpReturnContext, type ParsedDepositOpReturn, } from "./taproot";
38
+ export { encodeClaimLink, decodeClaimLink, parseClaimUrl, } from "./claim-link";
39
+ export type { ProofData, MerkleProofInput, CircuitType, JoinSplitProofInputs, } from "./prover/web";
40
+ export { uploadTransactionToBuffer, uploadProofToBuffer, closeBuffer, readBufferData, fetchRawTransaction, fetchMerkleProof, prepareVerifyDeposit, buildMerkleProof, needsBuffer as bufferNeedsBuffer, getProofSource, calculateUploadTransactions, CHADBUFFER_PROGRAM_ID, AUTHORITY_SIZE, MAX_DATA_PER_WRITE, SOLANA_TX_SIZE_LIMIT, type ProofUploadResult, } from "./chadbuffer";
41
+ export { computeBoundParamsHash, computeSolanaDomainBoundParamsHash, computeSolanaDomainSeparator, computeStealthDataHash, createTransferBoundParams, createUnshieldBoundParams, createRedeemBoundParams, SOLANA_BOUND_CHAIN_ID, SOLANA_DEVNET_BOUND_CHAIN_ID, SOLANA_MAINNET_BOUND_CHAIN_ID, DEFAULT_BOUND_PARAMS, type BoundParams, type BoundParamsMode, type SolanaPrivacyDomainContext, type SolanaPrivacyDomainKind, } from "./bound-params";
42
+ export { getConfig, setConfig, createConfig, initConfig, DEVNET_CONFIG, MAINNET_CONFIG, LOCALNET_CONFIG, TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, ATA_PROGRAM_ID, UTXOPIA_POLICY_PROGRAM_ID, SDK_VERSION, DEPLOYMENT_INFO, JOINSPLIT_TREE_DEPTH, type NetworkConfig, type NetworkType, } from "./config";
43
+ export { POOL_STATE_DISCRIMINATOR, POOL_STATE_LEN, POOL_STATE_OFFSETS, POOL_FLAG, parsePoolState, parsePoolFees, BPS_DENOMINATOR, computeBpsFee, feeShareBps, } from "./pool-state";
44
+ export type { PoolState, PoolFees } from "./pool-state";
45
+ export { PDA_SEEDS, poolStateSeeds, commitmentTreeSeeds, tokenConfigSeeds, poolConfigSeeds, nullifierRecordSeeds, redemptionRequestSeeds, vkRegistrySeeds, depositReceiptSeeds, policyApprovalSeeds, exitDestinationSeeds, lightClientSeeds, blockHeaderSeeds, heightIndexSeeds, verifiedTransactionSeeds, derivePoolStatePDA, deriveCommitmentTreePDA, deriveNullifierRecordPDA, derivePolicyApprovalPDA, deriveExitDestinationPDA, EXIT_KIND_SOLANA_OWNER, EXIT_KIND_BTC_SCRIPT, deriveLightClientPDA, deriveBlockHeaderPDA, deriveHeightIndexPDA, deriveVkRegistryPDA, deriveRedemptionRequestPDA, deriveTokenConfigPDA, derivePoolConfigPDA, deriveDepositReceiptPDA, commitmentToBytes, } from "./pda";
46
+ export { createStealthDeposit, createStealthDepositWithKeys, createStealthOutput, createStealthOutputWithKeys, createStealthOutputForCommitment, packStealthOutputForCircuit, scanAnnouncements, scanAnnouncementsViewOnly, scanAnnouncementsViewOnlyMulti, exportViewOnlyKeys, encodeViewOnlyKeys, decodeViewOnlyKeys, prepareClaimInputs, scanUnifiedNotes, scanUnifiedNotesMulti, encryptAmount, decryptAmount, computeNullifierHashForNote, computeNullifierBytes, parseAnnouncementsFromHex, createDepositFromConfig, createDirectVaultDeposit, isDepositForViewer, isDepositForViewerHex, ANNOUNCEMENT_TYPE_DEPOSIT, ANNOUNCEMENT_TYPE_TRANSFER, type StealthDeposit, type StealthOutputData, type StealthOutputWithKeys, type CircuitStealthOutput, type ScannedNote, type ClaimInputs as StealthClaimInputs, type OnChainStealthAnnouncement, type ConnectionAdapter, type ViewOnlyKeys, type ViewOnlyScannedNote, createNonInteractiveDeposit, pickIkaCustodyKey, type NonInteractiveDepositResult, type NonInteractiveDepositWithRefundResult, } from "./stealth";
47
+ export { buildDepositPsbt, estimateDepositFee, fetchUtxos, selectUtxos, type BuildDepositPsbtParams, type BuildDepositPsbtResult, type UtxoDescriptor, } from "./psbt";
48
+ export { EsploraClient, esploraTestnet, esploraMainnet, type EsploraTransaction, type EsploraVin, type EsploraVout, type EsploraStatus, type EsploraAddressInfo, type EsploraUtxo, type EsploraMerkleProof, type EsploraNetwork, } from "./core/esplora";
49
+ export { MempoolClient, mempoolTestnet, mempoolMainnet, reverseBytes, type BlockHeader, type TransactionInfo, type SPVProofData, } from "./core/mempool";
50
+ export { estimatePriorityFee, buildPriorityFeeInstructionData, encodeSetComputeUnitLimit, encodeSetComputeUnitPrice, getHeliusRpcUrl, DEFAULT_COMPUTE_UNITS, DEFAULT_PRIORITY_FEE, COMPUTE_BUDGET_DISCRIMINATORS, type PriorityFeeConfig, type PriorityFeeEstimate, type PriorityFeeInstructions, } from "./solana/priority-fee";
51
+ export { setDebug } from "./logger";
52
+ export { createFetchConnectionAdapter, createConnectionAdapterFromWeb3, createConnectionAdapterFromKit, getConnectionAdapter, clearConnectionAdapterCache, type RpcConfig, type Web3Connection, type KitRpc, } from "./solana/connection";
53
+ export { resolveSnsName, resolveStealthName, parseSnsStealthData, isSnsStealthAddress, isAuditorDisclosable, SnsComplianceFlags, SNS_COMPLIANCE_AUDITOR_OFFSET, SNS_COMPLIANCE_AUDITOR_BYTES, deriveParentDomainKey, SNS_STEALTH_DATA_SIZE, type SnsStealthAddress, } from "./sns-resolver";
54
+ export { COMMITMENT_TREE_DISCRIMINATOR, parseCommitmentTreeData, isValidRoot, fetchCommitmentTree, getCommitmentIndex, saveCommitmentIndex, CommitmentTreeIndex, buildCommitmentTreeFromChain, fetchLeafIndexForCommitment, fetchMerkleProofForCommitment, getMerkleProofFromTree, type CommitmentTreeState, type RpcClient, type OnChainMerkleProof, } from "./commitment-tree";
55
+ export { INSTRUCTION_DISCRIMINATORS, buildShieldInstructionData, buildShieldInstruction, type ShieldInstructionOptions, buildApproveRedemptionSigningInstructionData, buildApproveRedemptionSigningInstruction, buildCancelRedemptionInstructionData, buildCancelRedemptionInstruction, type CancelRedemptionInstructionOptions, bigintTo32Bytes, bytes32ToBigint, buildTransactInstructionData, buildTransactInstruction, buildRedeemInstructionData, buildUnshieldInstructionData, buildUnshieldInstruction, buildProposePoolUpdateInstructionData, buildProposePoolUpdateInstruction, buildExecutePoolUpdateInstructionData, buildExecutePoolUpdateInstruction, buildCancelPoolUpdateInstructionData, buildCancelPoolUpdateInstruction, buildRotateTreeInstructionData, buildRotateTreeInstruction, type RotateTreeOptions, buildMagicBlockDelegateInstructionData, buildMagicBlockDelegateInstruction, buildMagicBlockCommitInstructionData, buildMagicBlockCommitInstruction, buildMagicBlockPerPermissionInstructionData, buildMagicBlockPerPermissionInstruction, buildPolicyRequestHash, buildPolicyIntentParts, buildRegisterExitDestinationInstruction, buildRegisterExitDestinationInstructionData, MAX_POLICY_INTENT_PARTS, buildInitializePolicyApprovalInstructionData, buildInitializePolicyApprovalInstruction, buildPolicyApprovalDecisionInstruction, buildPolicyApprovalCommitInstruction, buildCompleteDepositPermissionedInstructionData, buildCompleteDepositPermissionedInstruction, buildShieldPermissionedInstructionData, buildShieldPermissionedInstruction, buildRotateAuditorInstructionData, buildRotateAuditorInstruction, type MagicBlockDelegateTarget, type MagicBlockDelegateInstructionOptions, type MagicBlockCommitInstructionOptions, type MagicBlockPerPermissionOperation, type MagicBlockPerPermissionMember, type MagicBlockPerPermissionInstructionOptions, type PolicyApprovalDecision, type InitializePolicyApprovalOptions, type CompleteDepositPermissionedOptions, type ShieldPermissionedInstructionOptions, type RotateAuditorOptions, buildVerifyTransactionInstructionData, buildCompleteDepositInstructionData, buildSetPoolConfigInstructionData, parsePoolConfig, type ParsedPoolConfig, POOL_CONFIG_DISCRIMINATOR, POOL_CONFIG_LEN, POOL_SCRIPT_MAX_LEN, type Instruction, type ApproveRedemptionSigningInstructionOptions, type TransactInstructionOptions, type UnshieldInstructionOptions, type ProposePoolUpdateOptions, type ExecutePoolUpdateOptions, type CancelPoolUpdateOptions, } from "./instructions";
56
+ export { VK_REGISTRY_DISCRIMINATOR, VK_REGISTRY_LEN, MAX_IC_POINTS, MAX_SAFE_JOINSPLIT_SIZE, INIT_VK_REGISTRY_DISCRIMINATOR, UPDATE_VK_REGISTRY_DISCRIMINATOR, joinSplitNumPublicInputs, computeVkHash, vkeyJsonToVkMaterial, buildVkRegistryData, parseVkRegistry, assertVkRegistryForShape, isVkRegistryReady, type JoinSplitVkMaterial, type SnarkjsVkeyJson, type ParsedVkRegistry, } from "./vk-registry";
57
+ export { fetchExplorerDeposits, fetchExplorerTransfers, fetchExplorerRedemptions, parseNullifierRecord, parseRedemptionRequest, NULLIFIER_RECORD_SIZE, REDEMPTION_REQUEST_SIZE, NULLIFIER_RECORD_DISCRIMINATOR, REDEMPTION_REQUEST_DISCRIMINATOR, OPERATION_TYPE_LABELS, type ExplorerDeposit, type ExplorerTransferEvent, type ExplorerRedemption, type IndexerLeaf, } from "./explorer";
58
+ export { parseProgramEvents, parseNullifierSpentEvent, parseStealthAnnouncementEvent, parseSenderMemoEvent, parseBtcOriginAttestationEvent, parseAuditorCiphertextEvent, EVENT_NULLIFIER_SPENT, EVENT_STEALTH_ANNOUNCEMENT, EVENT_NULLIFIERS_BATCH, EVENT_ANNOUNCEMENTS_BATCH, EVENT_SENDER_MEMO, EVENT_BTC_ORIGIN_ATTESTATION, EVENT_AUDITOR_CIPHERTEXT, type NullifierSpentEvent, type StealthAnnouncementEvent, type SenderMemoEvent, type BtcOriginAttestationEvent, type AuditorCiphertextEvent, type ProgramEvent, } from "./events";
59
+ export { AnnouncementClient, type AnnouncementClientConfig, type AnnouncementListener, } from "./announcement-client";
60
+ export { EventClient, type LeafInsertedEvent as EventLeafInserted, type NullifierSpentEvent as EventNullifierSpent, type AnnouncementEvent as EventAnnouncement, type ServerEvent as EventServerEvent, type EventListener, type TreeStatusResponse, type NullifierPdasResponse, } from "./event-client";
61
+ export { UTXOpiaClient, type UTXOpiaClientConfig, type TokenDefinition, type InboxNote as ClientInboxNote, } from "./client";