@solana/offchain-messages 0.0.0 → 5.1.0-canary-20251203224929

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 (63) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +14 -0
  3. package/dist/index.browser.cjs +828 -0
  4. package/dist/index.browser.cjs.map +1 -0
  5. package/dist/index.browser.mjs +788 -0
  6. package/dist/index.browser.mjs.map +1 -0
  7. package/dist/index.native.mjs +788 -0
  8. package/dist/index.native.mjs.map +1 -0
  9. package/dist/index.node.cjs +828 -0
  10. package/dist/index.node.cjs.map +1 -0
  11. package/dist/index.node.mjs +788 -0
  12. package/dist/index.node.mjs.map +1 -0
  13. package/dist/types/application-domain.d.ts +93 -0
  14. package/dist/types/application-domain.d.ts.map +1 -0
  15. package/dist/types/codecs/application-domain.d.ts +54 -0
  16. package/dist/types/codecs/application-domain.d.ts.map +1 -0
  17. package/dist/types/codecs/content.d.ts +6 -0
  18. package/dist/types/codecs/content.d.ts.map +1 -0
  19. package/dist/types/codecs/envelope.d.ts +31 -0
  20. package/dist/types/codecs/envelope.d.ts.map +1 -0
  21. package/dist/types/codecs/message-v0.d.ts +33 -0
  22. package/dist/types/codecs/message-v0.d.ts.map +1 -0
  23. package/dist/types/codecs/message-v1.d.ts +33 -0
  24. package/dist/types/codecs/message-v1.d.ts.map +1 -0
  25. package/dist/types/codecs/message.d.ts +43 -0
  26. package/dist/types/codecs/message.d.ts.map +1 -0
  27. package/dist/types/codecs/preamble-common.d.ts +12 -0
  28. package/dist/types/codecs/preamble-common.d.ts.map +1 -0
  29. package/dist/types/codecs/preamble-v0.d.ts +6 -0
  30. package/dist/types/codecs/preamble-v0.d.ts.map +1 -0
  31. package/dist/types/codecs/preamble-v1.d.ts +6 -0
  32. package/dist/types/codecs/preamble-v1.d.ts.map +1 -0
  33. package/dist/types/codecs/signatures.d.ts +4 -0
  34. package/dist/types/codecs/signatures.d.ts.map +1 -0
  35. package/dist/types/codecs/signing-domain.d.ts +5 -0
  36. package/dist/types/codecs/signing-domain.d.ts.map +1 -0
  37. package/dist/types/content.d.ts +234 -0
  38. package/dist/types/content.d.ts.map +1 -0
  39. package/dist/types/envelope-common.d.ts +9 -0
  40. package/dist/types/envelope-common.d.ts.map +1 -0
  41. package/dist/types/envelope-v0.d.ts +11 -0
  42. package/dist/types/envelope-v0.d.ts.map +1 -0
  43. package/dist/types/envelope-v1.d.ts +11 -0
  44. package/dist/types/envelope-v1.d.ts.map +1 -0
  45. package/dist/types/envelope.d.ts +29 -0
  46. package/dist/types/envelope.d.ts.map +1 -0
  47. package/dist/types/index.d.ts +23 -0
  48. package/dist/types/index.d.ts.map +1 -0
  49. package/dist/types/message-v0.d.ts +75 -0
  50. package/dist/types/message-v0.d.ts.map +1 -0
  51. package/dist/types/message-v1.d.ts +7 -0
  52. package/dist/types/message-v1.d.ts.map +1 -0
  53. package/dist/types/message.d.ts +7 -0
  54. package/dist/types/message.d.ts.map +1 -0
  55. package/dist/types/preamble-v0.d.ts +10 -0
  56. package/dist/types/preamble-v0.d.ts.map +1 -0
  57. package/dist/types/preamble-v1.d.ts +5 -0
  58. package/dist/types/preamble-v1.d.ts.map +1 -0
  59. package/dist/types/signatures.d.ts +138 -0
  60. package/dist/types/signatures.d.ts.map +1 -0
  61. package/dist/types/version.d.ts +2 -0
  62. package/dist/types/version.d.ts.map +1 -0
  63. package/package.json +85 -7
@@ -0,0 +1,788 @@
1
+ import { isAddress, assertIsAddress, getAddressEncoder, getAddressDecoder, address, getAddressFromPublicKey, getPublicKeyFromAddress } from '@solana/addresses';
2
+ import { isSolanaError, SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE, SolanaError, SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE, SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH, SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH, SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO, SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH, SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH, SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO, SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH, SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY, SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE, SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH, SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE, SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE, SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING, SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE, SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_SORTED, SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE, SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION } from '@solana/errors';
3
+ import { transformEncoder, combineCodec, transformDecoder, fixDecoderSize, createDecoder, createEncoder, bytesEqual, fixEncoderSize, offsetDecoder } from '@solana/codecs-core';
4
+ import { getStructEncoder, getBytesEncoder, getStructDecoder, getArrayDecoder, getBytesDecoder, getTupleDecoder, getTupleEncoder, getHiddenPrefixDecoder, getArrayEncoder, getConstantDecoder, getEnumDecoder, getEnumEncoder, getHiddenPrefixEncoder, getConstantEncoder } from '@solana/codecs-data-structures';
5
+ import { getU8Decoder, getU8Encoder, getU16Decoder, getU16Encoder } from '@solana/codecs-numbers';
6
+ import { getUtf8Encoder, getUtf8Decoder } from '@solana/codecs-strings';
7
+ import { signBytes, verifySignature } from '@solana/keys';
8
+
9
+ // src/application-domain.ts
10
+ function isOffchainMessageApplicationDomain(putativeApplicationDomain) {
11
+ return isAddress(putativeApplicationDomain);
12
+ }
13
+ function assertIsOffchainMessageApplicationDomain(putativeApplicationDomain) {
14
+ try {
15
+ assertIsAddress(putativeApplicationDomain);
16
+ } catch (error) {
17
+ if (isSolanaError(error, SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE)) {
18
+ throw new SolanaError(
19
+ SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE,
20
+ error.context
21
+ );
22
+ }
23
+ if (isSolanaError(error, SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH)) {
24
+ throw new SolanaError(
25
+ SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH,
26
+ error.context
27
+ );
28
+ }
29
+ throw error;
30
+ }
31
+ }
32
+ function offchainMessageApplicationDomain(putativeApplicationDomain) {
33
+ assertIsOffchainMessageApplicationDomain(putativeApplicationDomain);
34
+ return putativeApplicationDomain;
35
+ }
36
+ function getOffchainMessageApplicationDomainEncoder() {
37
+ return transformEncoder(
38
+ getAddressEncoder(),
39
+ (putativeApplicationDomain) => offchainMessageApplicationDomain(putativeApplicationDomain)
40
+ );
41
+ }
42
+ function getOffchainMessageApplicationDomainDecoder() {
43
+ return getAddressDecoder();
44
+ }
45
+ function getOffchainMessageApplicationDomainCodec() {
46
+ return combineCodec(getOffchainMessageApplicationDomainEncoder(), getOffchainMessageApplicationDomainDecoder());
47
+ }
48
+ var OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES = new Uint8Array([
49
+ 255,
50
+ 115,
51
+ 111,
52
+ 108,
53
+ 97,
54
+ 110,
55
+ 97,
56
+ 32,
57
+ 111,
58
+ 102,
59
+ 102,
60
+ 99,
61
+ 104,
62
+ 97,
63
+ 105,
64
+ 110
65
+ ]);
66
+ function getOffchainMessageSigningDomainDecoder() {
67
+ return getConstantDecoder(OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES);
68
+ }
69
+ function getOffchainMessageSigningDomainEncoder() {
70
+ return getConstantEncoder(OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES);
71
+ }
72
+
73
+ // src/codecs/preamble-common.ts
74
+ function getSigningDomainPrefixedDecoder(...fields) {
75
+ return getHiddenPrefixDecoder(getStructDecoder(fields), [getOffchainMessageSigningDomainDecoder()]);
76
+ }
77
+ function getSigningDomainPrefixedEncoder(...fields) {
78
+ return getHiddenPrefixEncoder(getStructEncoder(fields), [getOffchainMessageSigningDomainEncoder()]);
79
+ }
80
+ function getVersionTransformer(fixedVersion) {
81
+ return (version) => {
82
+ if (version > 1) {
83
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {
84
+ unsupportedVersion: version
85
+ });
86
+ }
87
+ if (fixedVersion != null && version !== fixedVersion) {
88
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION, {
89
+ actualVersion: version,
90
+ expectedVersion: fixedVersion
91
+ });
92
+ }
93
+ return version;
94
+ };
95
+ }
96
+ function createOffchainMessagePreambleDecoder(version, ...fields) {
97
+ return getSigningDomainPrefixedDecoder(
98
+ ["version", transformDecoder(getU8Decoder(), getVersionTransformer(version))],
99
+ ...fields
100
+ );
101
+ }
102
+ function createOffchainMessagePreambleEncoder(version, ...fields) {
103
+ return getSigningDomainPrefixedEncoder(
104
+ ["version", transformEncoder(getU8Encoder(), getVersionTransformer(version))],
105
+ ...fields
106
+ );
107
+ }
108
+ function decodeRequiredSignatoryAddresses(bytes) {
109
+ const { version, bytesAfterVersion } = getSigningDomainPrefixedDecoder(
110
+ ["version", transformDecoder(getU8Decoder(), getVersionTransformer())],
111
+ ["bytesAfterVersion", getBytesDecoder()]
112
+ ).decode(bytes);
113
+ return offsetDecoder(
114
+ transformDecoder(getArrayDecoder(getAddressDecoder(), { size: getU8Decoder() }), (signatoryAddresses) => {
115
+ if (signatoryAddresses.length === 0) {
116
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO);
117
+ }
118
+ return signatoryAddresses;
119
+ }),
120
+ {
121
+ preOffset: ({ preOffset }) => preOffset + (version === 0 ? 32 + 1 : 0)
122
+ }
123
+ ).decode(bytesAfterVersion);
124
+ }
125
+ function getSignatoriesComparator() {
126
+ return (x, y) => {
127
+ if (x.length !== y.length) {
128
+ return x.length < y.length ? -1 : 1;
129
+ }
130
+ for (let ii = 0; ii < x.length; ii++) {
131
+ if (x[ii] === y[ii]) {
132
+ continue;
133
+ } else {
134
+ return x[ii] < y[ii] ? -1 : 1;
135
+ }
136
+ }
137
+ return 0;
138
+ };
139
+ }
140
+ function getSignaturesToEncode(signaturesMap) {
141
+ const signatures = Object.values(signaturesMap);
142
+ if (signatures.length === 0) {
143
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO);
144
+ }
145
+ return signatures.map((signature) => {
146
+ if (!signature) {
147
+ return new Uint8Array(64).fill(0);
148
+ }
149
+ return signature;
150
+ });
151
+ }
152
+ function getSignaturesEncoder() {
153
+ return transformEncoder(
154
+ getArrayEncoder(fixEncoderSize(getBytesEncoder(), 64), { size: getU8Encoder() }),
155
+ getSignaturesToEncode
156
+ );
157
+ }
158
+
159
+ // src/codecs/envelope.ts
160
+ function getOffchainMessageEnvelopeEncoder() {
161
+ return transformEncoder(
162
+ getStructEncoder([
163
+ ["signatures", getSignaturesEncoder()],
164
+ ["content", getBytesEncoder()]
165
+ ]),
166
+ (envelope) => {
167
+ const signaturesMapAddresses = Object.keys(envelope.signatures).map(address);
168
+ if (signaturesMapAddresses.length === 0) {
169
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO);
170
+ }
171
+ const signatoryAddresses = decodeAndValidateRequiredSignatoryAddresses(envelope.content);
172
+ const missingRequiredSigners = [];
173
+ const unexpectedSigners = [];
174
+ for (const address2 of signatoryAddresses) {
175
+ if (!signaturesMapAddresses.includes(address2)) {
176
+ missingRequiredSigners.push(address2);
177
+ }
178
+ }
179
+ for (const address2 of signaturesMapAddresses) {
180
+ if (!signatoryAddresses.includes(address2)) {
181
+ unexpectedSigners.push(address2);
182
+ }
183
+ }
184
+ if (missingRequiredSigners.length || unexpectedSigners.length) {
185
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH, {
186
+ missingRequiredSigners,
187
+ unexpectedSigners
188
+ });
189
+ }
190
+ const orderedSignatureMap = {};
191
+ for (const address2 of signatoryAddresses) {
192
+ orderedSignatureMap[address2] = envelope.signatures[address2];
193
+ }
194
+ return {
195
+ ...envelope,
196
+ signatures: orderedSignatureMap
197
+ };
198
+ }
199
+ );
200
+ }
201
+ function getOffchainMessageEnvelopeDecoder() {
202
+ return transformDecoder(
203
+ getStructDecoder([
204
+ ["signatures", getArrayDecoder(fixDecoderSize(getBytesDecoder(), 64), { size: getU8Decoder() })],
205
+ ["content", getBytesDecoder()]
206
+ ]),
207
+ decodePartiallyDecodedOffchainMessageEnvelope
208
+ );
209
+ }
210
+ function getOffchainMessageEnvelopeCodec() {
211
+ return combineCodec(getOffchainMessageEnvelopeEncoder(), getOffchainMessageEnvelopeDecoder());
212
+ }
213
+ function decodePartiallyDecodedOffchainMessageEnvelope(offchainMessageEnvelope) {
214
+ const { content, signatures } = offchainMessageEnvelope;
215
+ if (signatures.length === 0) {
216
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO);
217
+ }
218
+ const signatoryAddresses = decodeAndValidateRequiredSignatoryAddresses(content);
219
+ if (signatoryAddresses.length !== signatures.length) {
220
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH, {
221
+ numRequiredSignatures: signatoryAddresses.length,
222
+ signatoryAddresses,
223
+ signaturesLength: signatures.length
224
+ });
225
+ }
226
+ const signaturesMap = {};
227
+ signatoryAddresses.forEach((address2, index) => {
228
+ const signatureForAddress = signatures[index];
229
+ if (signatureForAddress.every((b) => b === 0)) {
230
+ signaturesMap[address2] = null;
231
+ } else {
232
+ signaturesMap[address2] = signatureForAddress;
233
+ }
234
+ });
235
+ return Object.freeze({
236
+ content,
237
+ signatures: Object.freeze(signaturesMap)
238
+ });
239
+ }
240
+ function decodeAndValidateRequiredSignatoryAddresses(bytes) {
241
+ const signatoryAddresses = decodeRequiredSignatoryAddresses(bytes);
242
+ if (signatoryAddresses.length === 0) {
243
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO);
244
+ }
245
+ return signatoryAddresses;
246
+ }
247
+ var MAX_BODY_BYTES = (
248
+ // Largest 16-bit unsigned integer
249
+ 65535
250
+ );
251
+ var MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE = (
252
+ // Space remaining in the mininum IPv6 MTU after network header overhead
253
+ 1232
254
+ );
255
+ var OffchainMessageContentFormat = /* @__PURE__ */ ((OffchainMessageContentFormat3) => {
256
+ OffchainMessageContentFormat3[OffchainMessageContentFormat3["RESTRICTED_ASCII_1232_BYTES_MAX"] = 0] = "RESTRICTED_ASCII_1232_BYTES_MAX";
257
+ OffchainMessageContentFormat3[OffchainMessageContentFormat3["UTF8_1232_BYTES_MAX"] = 1] = "UTF8_1232_BYTES_MAX";
258
+ OffchainMessageContentFormat3[OffchainMessageContentFormat3["UTF8_65535_BYTES_MAX"] = 2] = "UTF8_65535_BYTES_MAX";
259
+ return OffchainMessageContentFormat3;
260
+ })(OffchainMessageContentFormat || {});
261
+ function assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax(putativeContent) {
262
+ if (putativeContent.format !== 0 /* RESTRICTED_ASCII_1232_BYTES_MAX */) {
263
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH, {
264
+ actualMessageFormat: putativeContent.format,
265
+ expectedMessageFormat: 0 /* RESTRICTED_ASCII_1232_BYTES_MAX */
266
+ });
267
+ }
268
+ if (putativeContent.text.length === 0) {
269
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY);
270
+ }
271
+ if (isTextRestrictedAscii(putativeContent.text) === false) {
272
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE);
273
+ }
274
+ const length = getUtf8Encoder().getSizeFromValue(putativeContent.text);
275
+ if (length > MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE) {
276
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {
277
+ actualBytes: length,
278
+ maxBytes: MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE
279
+ });
280
+ }
281
+ }
282
+ function isOffchainMessageContentRestrictedAsciiOf1232BytesMax(putativeContent) {
283
+ if (putativeContent.format !== 0 /* RESTRICTED_ASCII_1232_BYTES_MAX */ || putativeContent.text.length === 0 || isTextRestrictedAscii(putativeContent.text) === false) {
284
+ return false;
285
+ }
286
+ const length = getUtf8Encoder().getSizeFromValue(putativeContent.text);
287
+ return length <= MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE;
288
+ }
289
+ function offchainMessageContentRestrictedAsciiOf1232BytesMax(text) {
290
+ const putativeContent = Object.freeze({
291
+ format: 0 /* RESTRICTED_ASCII_1232_BYTES_MAX */,
292
+ text
293
+ });
294
+ assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax(putativeContent);
295
+ return putativeContent;
296
+ }
297
+ function assertIsOffchainMessageContentUtf8Of1232BytesMax(putativeContent) {
298
+ if (putativeContent.text.length === 0) {
299
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY);
300
+ }
301
+ if (putativeContent.format !== 1 /* UTF8_1232_BYTES_MAX */) {
302
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH, {
303
+ actualMessageFormat: putativeContent.format,
304
+ expectedMessageFormat: 1 /* UTF8_1232_BYTES_MAX */
305
+ });
306
+ }
307
+ const length = getUtf8Encoder().getSizeFromValue(putativeContent.text);
308
+ if (length > MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE) {
309
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {
310
+ actualBytes: length,
311
+ maxBytes: MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE
312
+ });
313
+ }
314
+ }
315
+ function isOffchainMessageContentUtf8Of1232BytesMax(putativeContent) {
316
+ if (putativeContent.format !== 1 /* UTF8_1232_BYTES_MAX */ || putativeContent.text.length === 0) {
317
+ return false;
318
+ }
319
+ const length = getUtf8Encoder().getSizeFromValue(putativeContent.text);
320
+ return length <= MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE;
321
+ }
322
+ function offchainMessageContentUtf8Of1232BytesMax(text) {
323
+ const putativeContent = Object.freeze({
324
+ format: 1 /* UTF8_1232_BYTES_MAX */,
325
+ text
326
+ });
327
+ assertIsOffchainMessageContentUtf8Of1232BytesMax(putativeContent);
328
+ return putativeContent;
329
+ }
330
+ function assertIsOffchainMessageContentUtf8Of65535BytesMax(putativeContent) {
331
+ if (putativeContent.format !== 2 /* UTF8_65535_BYTES_MAX */) {
332
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH, {
333
+ actualMessageFormat: putativeContent.format,
334
+ expectedMessageFormat: 2 /* UTF8_65535_BYTES_MAX */
335
+ });
336
+ }
337
+ if (putativeContent.text.length === 0) {
338
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY);
339
+ }
340
+ const length = getUtf8Encoder().getSizeFromValue(putativeContent.text);
341
+ if (length > MAX_BODY_BYTES) {
342
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {
343
+ actualBytes: length,
344
+ maxBytes: MAX_BODY_BYTES
345
+ });
346
+ }
347
+ }
348
+ function isOffchainMessageContentUtf8Of65535BytesMax(putativeContent) {
349
+ if (putativeContent.format !== 2 /* UTF8_65535_BYTES_MAX */ || putativeContent.text.length === 0) {
350
+ return false;
351
+ }
352
+ const length = getUtf8Encoder().getSizeFromValue(putativeContent.text);
353
+ return length <= MAX_BODY_BYTES;
354
+ }
355
+ function offchainMessageContentUtf8Of65535BytesMax(text) {
356
+ const putativeContent = Object.freeze({
357
+ format: 2 /* UTF8_65535_BYTES_MAX */,
358
+ text
359
+ });
360
+ assertIsOffchainMessageContentUtf8Of65535BytesMax(putativeContent);
361
+ return putativeContent;
362
+ }
363
+ function isTextRestrictedAscii(putativeRestrictedAsciiString) {
364
+ return /^[\x20-\x7e]+$/.test(putativeRestrictedAsciiString);
365
+ }
366
+
367
+ // src/message-v0.ts
368
+ function assertIsOffchainMessageRestrictedAsciiOf1232BytesMax(putativeMessage) {
369
+ assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax(putativeMessage.content);
370
+ }
371
+ function assertIsOffchainMessageUtf8Of1232BytesMax(putativeMessage) {
372
+ assertIsOffchainMessageContentUtf8Of1232BytesMax(putativeMessage.content);
373
+ }
374
+ function assertIsOffchainMessageUtf8Of65535BytesMax(putativeMessage) {
375
+ assertIsOffchainMessageContentUtf8Of65535BytesMax(putativeMessage.content);
376
+ }
377
+ function getOffchainMessageContentFormatDecoder() {
378
+ return getEnumDecoder(OffchainMessageContentFormat, {
379
+ useValuesAsDiscriminators: true
380
+ });
381
+ }
382
+ function getOffchainMessageContentFormatEncoder() {
383
+ return getEnumEncoder(OffchainMessageContentFormat, {
384
+ useValuesAsDiscriminators: true
385
+ });
386
+ }
387
+
388
+ // src/codecs/preamble-v0.ts
389
+ function getOffchainMessageV0PreambleDecoder() {
390
+ return createOffchainMessagePreambleDecoder(
391
+ /* version */
392
+ 0,
393
+ ["applicationDomain", getOffchainMessageApplicationDomainDecoder()],
394
+ ["messageFormat", getOffchainMessageContentFormatDecoder()],
395
+ [
396
+ "requiredSignatories",
397
+ transformDecoder(getArrayDecoder(getAddressDecoder(), { size: getU8Decoder() }), (signatoryAddresses) => {
398
+ if (signatoryAddresses.length === 0) {
399
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO);
400
+ }
401
+ return signatoryAddresses.map((address2) => Object.freeze({ address: address2 }));
402
+ })
403
+ ],
404
+ ["messageLength", getU16Decoder()]
405
+ );
406
+ }
407
+ function getOffchainMessageV0PreambleEncoder() {
408
+ return createOffchainMessagePreambleEncoder(
409
+ /* version */
410
+ 0,
411
+ ["applicationDomain", getOffchainMessageApplicationDomainEncoder()],
412
+ ["messageFormat", getOffchainMessageContentFormatEncoder()],
413
+ [
414
+ "requiredSignatories",
415
+ transformEncoder(
416
+ getArrayEncoder(getAddressEncoder(), { size: getU8Encoder() }),
417
+ (signatoryAddresses) => {
418
+ if (signatoryAddresses.length === 0) {
419
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO);
420
+ }
421
+ return signatoryAddresses.map(({ address: address2 }) => address2);
422
+ }
423
+ )
424
+ ],
425
+ ["messageLength", getU16Encoder()]
426
+ );
427
+ }
428
+
429
+ // src/codecs/message-v0.ts
430
+ function getOffchainMessageV0Decoder() {
431
+ return transformDecoder(
432
+ getTupleDecoder([getOffchainMessageV0PreambleDecoder(), getUtf8Decoder()]),
433
+ ([{ messageLength, messageFormat, requiredSignatories, ...preambleRest }, text]) => {
434
+ const actualLength = getUtf8Encoder().getSizeFromValue(text);
435
+ if (messageLength !== actualLength) {
436
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH, {
437
+ actualLength,
438
+ specifiedLength: messageLength
439
+ });
440
+ }
441
+ const offchainMessage = Object.freeze({
442
+ ...preambleRest,
443
+ content: Object.freeze({
444
+ format: messageFormat,
445
+ text
446
+ }),
447
+ requiredSignatories: Object.freeze(requiredSignatories)
448
+ });
449
+ switch (messageFormat) {
450
+ case 0 /* RESTRICTED_ASCII_1232_BYTES_MAX */: {
451
+ assertIsOffchainMessageRestrictedAsciiOf1232BytesMax(offchainMessage);
452
+ return offchainMessage;
453
+ }
454
+ case 1 /* UTF8_1232_BYTES_MAX */: {
455
+ assertIsOffchainMessageUtf8Of1232BytesMax(offchainMessage);
456
+ return offchainMessage;
457
+ }
458
+ case 2 /* UTF8_65535_BYTES_MAX */: {
459
+ assertIsOffchainMessageUtf8Of65535BytesMax(offchainMessage);
460
+ return offchainMessage;
461
+ }
462
+ default: {
463
+ throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE, {
464
+ unexpectedValue: messageFormat
465
+ });
466
+ }
467
+ }
468
+ }
469
+ );
470
+ }
471
+ function getOffchainMessageV0Encoder() {
472
+ return transformEncoder(
473
+ getTupleEncoder([getOffchainMessageV0PreambleEncoder(), getUtf8Encoder()]),
474
+ (offchainMessage) => {
475
+ const { content, ...preamble } = offchainMessage;
476
+ switch (offchainMessage.content.format) {
477
+ case 0 /* RESTRICTED_ASCII_1232_BYTES_MAX */: {
478
+ assertIsOffchainMessageRestrictedAsciiOf1232BytesMax(offchainMessage);
479
+ break;
480
+ }
481
+ case 1 /* UTF8_1232_BYTES_MAX */: {
482
+ assertIsOffchainMessageUtf8Of1232BytesMax(offchainMessage);
483
+ break;
484
+ }
485
+ case 2 /* UTF8_65535_BYTES_MAX */: {
486
+ assertIsOffchainMessageUtf8Of65535BytesMax(offchainMessage);
487
+ break;
488
+ }
489
+ default: {
490
+ throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE, {
491
+ unexpectedValue: offchainMessage.content
492
+ });
493
+ }
494
+ }
495
+ const messageLength = getUtf8Encoder().getSizeFromValue(content.text);
496
+ const compiledPreamble = {
497
+ ...preamble,
498
+ messageFormat: content.format,
499
+ messageLength
500
+ };
501
+ return [compiledPreamble, content.text];
502
+ }
503
+ );
504
+ }
505
+ function getOffchainMessageV0Codec() {
506
+ return combineCodec(getOffchainMessageV0Encoder(), getOffchainMessageV0Decoder());
507
+ }
508
+ function getOffchainMessageV1PreambleDecoder() {
509
+ return createOffchainMessagePreambleDecoder(
510
+ /* version */
511
+ 1,
512
+ [
513
+ "requiredSignatories",
514
+ transformDecoder(
515
+ getArrayDecoder(fixDecoderSize(getBytesDecoder(), 32), { size: getU8Decoder() }),
516
+ (signatoryAddressesBytes) => {
517
+ if (signatoryAddressesBytes.length === 0) {
518
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO);
519
+ }
520
+ const comparator = getSignatoriesComparator();
521
+ for (let ii = 0; ii < signatoryAddressesBytes.length - 1; ii++) {
522
+ switch (comparator(signatoryAddressesBytes[ii], signatoryAddressesBytes[ii + 1])) {
523
+ case 0:
524
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE);
525
+ case 1:
526
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_SORTED);
527
+ }
528
+ }
529
+ const addressDecoder = getAddressDecoder();
530
+ return signatoryAddressesBytes.map(
531
+ (addressBytes) => Object.freeze({
532
+ address: addressDecoder.decode(addressBytes)
533
+ })
534
+ );
535
+ }
536
+ )
537
+ ]
538
+ );
539
+ }
540
+ function getOffchainMessageV1PreambleEncoder() {
541
+ return createOffchainMessagePreambleEncoder(
542
+ /* version */
543
+ 1,
544
+ [
545
+ "requiredSignatories",
546
+ transformEncoder(
547
+ transformEncoder(
548
+ getArrayEncoder(getBytesEncoder(), { size: getU8Encoder() }),
549
+ (signatoryAddressesBytes) => {
550
+ return signatoryAddressesBytes.toSorted(getSignatoriesComparator());
551
+ }
552
+ ),
553
+ (signatoryAddresses) => {
554
+ if (signatoryAddresses.length === 0) {
555
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO);
556
+ }
557
+ const seenSignatories = /* @__PURE__ */ new Set();
558
+ for (const { address: address2 } of signatoryAddresses) {
559
+ if (seenSignatories.has(address2)) {
560
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE);
561
+ }
562
+ seenSignatories.add(address2);
563
+ }
564
+ const addressEncoder = getAddressEncoder();
565
+ return signatoryAddresses.map(({ address: address2 }) => addressEncoder.encode(address2));
566
+ }
567
+ )
568
+ ]
569
+ );
570
+ }
571
+
572
+ // src/codecs/message-v1.ts
573
+ function getOffchainMessageV1Decoder() {
574
+ return transformDecoder(
575
+ getTupleDecoder([getOffchainMessageV1PreambleDecoder(), getUtf8Decoder()]),
576
+ ([{ requiredSignatories, ...preambleRest }, text]) => {
577
+ if (text.length === 0) {
578
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY);
579
+ }
580
+ return Object.freeze({
581
+ ...preambleRest,
582
+ content: text,
583
+ requiredSignatories: Object.freeze(requiredSignatories)
584
+ });
585
+ }
586
+ );
587
+ }
588
+ function getOffchainMessageV1Encoder() {
589
+ return transformEncoder(
590
+ getTupleEncoder([getOffchainMessageV1PreambleEncoder(), getUtf8Encoder()]),
591
+ (offchainMessage) => {
592
+ const { content, ...compiledPreamble } = offchainMessage;
593
+ if (content.length === 0) {
594
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY);
595
+ }
596
+ return [compiledPreamble, content];
597
+ }
598
+ );
599
+ }
600
+ function getOffchainMessageV1Codec() {
601
+ return combineCodec(getOffchainMessageV1Encoder(), getOffchainMessageV1Decoder());
602
+ }
603
+
604
+ // src/codecs/message.ts
605
+ function getOffchainMessageDecoder() {
606
+ return createDecoder({
607
+ read(bytes, offset) {
608
+ const version = getHiddenPrefixDecoder(getU8Decoder(), [
609
+ // Discard the signing domain
610
+ getOffchainMessageSigningDomainDecoder()
611
+ ]).decode(bytes, offset);
612
+ switch (version) {
613
+ case 0:
614
+ return getOffchainMessageV0Decoder().read(bytes, offset);
615
+ case 1:
616
+ return getOffchainMessageV1Decoder().read(bytes, offset);
617
+ default:
618
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {
619
+ unsupportedVersion: version
620
+ });
621
+ }
622
+ }
623
+ });
624
+ }
625
+ function getOffchainMessageEncoder() {
626
+ return createEncoder({
627
+ getSizeFromValue: (offchainMessage) => {
628
+ const { version } = offchainMessage;
629
+ switch (version) {
630
+ case 0:
631
+ return getOffchainMessageV0Encoder().getSizeFromValue(offchainMessage);
632
+ case 1:
633
+ return getOffchainMessageV1Encoder().getSizeFromValue(offchainMessage);
634
+ default:
635
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {
636
+ unsupportedVersion: version
637
+ });
638
+ }
639
+ },
640
+ write: (offchainMessage, bytes, offset) => {
641
+ const { version } = offchainMessage;
642
+ switch (version) {
643
+ case 0:
644
+ return getOffchainMessageV0Encoder().write(offchainMessage, bytes, offset);
645
+ case 1:
646
+ return getOffchainMessageV1Encoder().write(offchainMessage, bytes, offset);
647
+ default:
648
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {
649
+ unsupportedVersion: version
650
+ });
651
+ }
652
+ }
653
+ });
654
+ }
655
+ function getOffchainMessageCodec() {
656
+ return combineCodec(getOffchainMessageEncoder(), getOffchainMessageDecoder());
657
+ }
658
+
659
+ // src/envelope-common.ts
660
+ function compileOffchainMessageEnvelopeUsingEncoder(offchainMessage, encoder) {
661
+ const offchainMessageBytes = encoder.encode(offchainMessage);
662
+ const signatures = {};
663
+ for (const { address: address2 } of offchainMessage.requiredSignatories) {
664
+ signatures[address2] = null;
665
+ }
666
+ return Object.freeze({
667
+ content: offchainMessageBytes,
668
+ signatures: Object.freeze(signatures)
669
+ });
670
+ }
671
+
672
+ // src/envelope-v0.ts
673
+ function compileOffchainMessageV0Envelope(offchainMessage) {
674
+ return compileOffchainMessageEnvelopeUsingEncoder(offchainMessage, getOffchainMessageV0Encoder());
675
+ }
676
+
677
+ // src/envelope-v1.ts
678
+ function compileOffchainMessageV1Envelope(offchainMessage) {
679
+ return compileOffchainMessageEnvelopeUsingEncoder(offchainMessage, getOffchainMessageV1Encoder());
680
+ }
681
+
682
+ // src/envelope.ts
683
+ function compileOffchainMessageEnvelope(offchainMessage) {
684
+ const { version } = offchainMessage;
685
+ switch (version) {
686
+ case 0:
687
+ return compileOffchainMessageV0Envelope(offchainMessage);
688
+ case 1:
689
+ return compileOffchainMessageV1Envelope(offchainMessage);
690
+ default:
691
+ throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE, {
692
+ unexpectedValue: version
693
+ });
694
+ }
695
+ }
696
+ async function partiallySignOffchainMessageEnvelope(keyPairs, offchainMessageEnvelope) {
697
+ let newSignatures;
698
+ let unexpectedSigners;
699
+ const requiredSignatoryAddresses = decodeRequiredSignatoryAddresses(offchainMessageEnvelope.content);
700
+ await Promise.all(
701
+ keyPairs.map(async (keyPair) => {
702
+ const address2 = await getAddressFromPublicKey(keyPair.publicKey);
703
+ if (!requiredSignatoryAddresses.includes(address2)) {
704
+ unexpectedSigners ||= /* @__PURE__ */ new Set();
705
+ unexpectedSigners.add(address2);
706
+ return;
707
+ }
708
+ if (unexpectedSigners) {
709
+ return;
710
+ }
711
+ const existingSignature = offchainMessageEnvelope.signatures[address2];
712
+ const newSignature = await signBytes(keyPair.privateKey, offchainMessageEnvelope.content);
713
+ if (existingSignature != null && bytesEqual(newSignature, existingSignature)) {
714
+ return;
715
+ }
716
+ newSignatures ||= {};
717
+ newSignatures[address2] = newSignature;
718
+ })
719
+ );
720
+ if (unexpectedSigners && unexpectedSigners.size > 0) {
721
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE, {
722
+ expectedAddresses: requiredSignatoryAddresses,
723
+ unexpectedAddresses: [...unexpectedSigners]
724
+ });
725
+ }
726
+ if (!newSignatures) {
727
+ return offchainMessageEnvelope;
728
+ }
729
+ return Object.freeze({
730
+ ...offchainMessageEnvelope,
731
+ signatures: Object.freeze({
732
+ ...offchainMessageEnvelope.signatures,
733
+ ...newSignatures
734
+ })
735
+ });
736
+ }
737
+ async function signOffchainMessageEnvelope(keyPairs, offchainMessageEnvelope) {
738
+ const out = await partiallySignOffchainMessageEnvelope(keyPairs, offchainMessageEnvelope);
739
+ assertIsFullySignedOffchainMessageEnvelope(out);
740
+ Object.freeze(out);
741
+ return out;
742
+ }
743
+ function isFullySignedOffchainMessageEnvelope(offchainMessage) {
744
+ return Object.entries(offchainMessage.signatures).every(([_, signatureBytes]) => !!signatureBytes);
745
+ }
746
+ function assertIsFullySignedOffchainMessageEnvelope(offchainMessage) {
747
+ const missingSigs = [];
748
+ Object.entries(offchainMessage.signatures).forEach(([address2, signatureBytes]) => {
749
+ if (!signatureBytes) {
750
+ missingSigs.push(address2);
751
+ }
752
+ });
753
+ if (missingSigs.length > 0) {
754
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING, {
755
+ addresses: missingSigs
756
+ });
757
+ }
758
+ }
759
+ async function verifyOffchainMessageEnvelope(offchainMessageEnvelope) {
760
+ let errorContext;
761
+ const requiredSignatories = decodeRequiredSignatoryAddresses(offchainMessageEnvelope.content);
762
+ await Promise.all(
763
+ requiredSignatories.map(async (address2) => {
764
+ const signature = offchainMessageEnvelope.signatures[address2];
765
+ if (signature == null) {
766
+ errorContext ||= {};
767
+ errorContext.signatoriesWithMissingSignatures ||= [];
768
+ errorContext.signatoriesWithMissingSignatures.push(address2);
769
+ } else {
770
+ const publicKey = await getPublicKeyFromAddress(address2);
771
+ if (await verifySignature(publicKey, signature, offchainMessageEnvelope.content)) {
772
+ return true;
773
+ } else {
774
+ errorContext ||= {};
775
+ errorContext.signatoriesWithInvalidSignatures ||= [];
776
+ errorContext.signatoriesWithInvalidSignatures.push(address2);
777
+ }
778
+ }
779
+ })
780
+ );
781
+ if (errorContext) {
782
+ throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE, errorContext);
783
+ }
784
+ }
785
+
786
+ export { OffchainMessageContentFormat, assertIsFullySignedOffchainMessageEnvelope, assertIsOffchainMessageApplicationDomain, assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax, assertIsOffchainMessageContentUtf8Of1232BytesMax, assertIsOffchainMessageContentUtf8Of65535BytesMax, assertIsOffchainMessageRestrictedAsciiOf1232BytesMax, assertIsOffchainMessageUtf8Of1232BytesMax, assertIsOffchainMessageUtf8Of65535BytesMax, compileOffchainMessageEnvelope, compileOffchainMessageV0Envelope, compileOffchainMessageV1Envelope, getOffchainMessageApplicationDomainCodec, getOffchainMessageApplicationDomainDecoder, getOffchainMessageApplicationDomainEncoder, getOffchainMessageCodec, getOffchainMessageDecoder, getOffchainMessageEncoder, getOffchainMessageEnvelopeCodec, getOffchainMessageEnvelopeDecoder, getOffchainMessageEnvelopeEncoder, getOffchainMessageV0Codec, getOffchainMessageV0Decoder, getOffchainMessageV0Encoder, getOffchainMessageV1Codec, getOffchainMessageV1Decoder, getOffchainMessageV1Encoder, isFullySignedOffchainMessageEnvelope, isOffchainMessageApplicationDomain, isOffchainMessageContentRestrictedAsciiOf1232BytesMax, isOffchainMessageContentUtf8Of1232BytesMax, isOffchainMessageContentUtf8Of65535BytesMax, offchainMessageApplicationDomain, offchainMessageContentRestrictedAsciiOf1232BytesMax, offchainMessageContentUtf8Of1232BytesMax, offchainMessageContentUtf8Of65535BytesMax, partiallySignOffchainMessageEnvelope, signOffchainMessageEnvelope, verifyOffchainMessageEnvelope };
787
+ //# sourceMappingURL=index.native.mjs.map
788
+ //# sourceMappingURL=index.native.mjs.map