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