Skip to content

Commit 1384a9a

Browse files
committed
Utilities for creating, signing, and verifying offchain messages
1 parent bbc363a commit 1384a9a

File tree

3 files changed

+126
-0
lines changed

3 files changed

+126
-0
lines changed

packages/errors/src/codes.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,23 @@ export const SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGN
190190
export const SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING = 5508010;
191191
export const SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED = 5508011;
192192

193+
// Offchain-message-related errors.
194+
// Reserve error codes in the range [5607000-5607999].
195+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED = 5607000;
196+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE = 5607001;
197+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE = 5607002;
198+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH = 5607003;
199+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH = 5607004;
200+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO = 5607005;
201+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED = 5607006;
202+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH = 5607007;
203+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH = 5607008;
204+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY = 5607009;
205+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO = 5607010;
206+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING = 5607011;
207+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH = 5607012;
208+
export const SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE = 5607013;
209+
193210
// Transaction-related errors.
194211
// Reserve error codes in the range [5663000-5663999].
195212
export const SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES = 5663000;
@@ -485,6 +502,20 @@ export type SolanaErrorCode =
485502
| typeof SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR
486503
| typeof SOLANA_ERROR__MALFORMED_NUMBER_STRING
487504
| typeof SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND
505+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE
506+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE
507+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH
508+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH
509+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED
510+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH
511+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH
512+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY
513+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO
514+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO
515+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH
516+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE
517+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING
518+
| typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED
488519
| typeof SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD
489520
| typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW
490521
| typeof SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR

packages/errors/src/context.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,16 @@ import {
135135
SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR,
136136
SOLANA_ERROR__MALFORMED_NUMBER_STRING,
137137
SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND,
138+
SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE,
139+
SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE,
140+
SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH,
141+
SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH,
142+
SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED,
143+
SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH,
144+
SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH,
145+
SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH,
146+
SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING,
147+
SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED,
138148
SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD,
139149
SOLANA_ERROR__RPC__INTEGER_OVERFLOW,
140150
SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR,
@@ -538,6 +548,43 @@ export type SolanaErrorContext = ReadonlyContextValue<
538548
[SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND]: {
539549
nonceAccountAddress: string;
540550
};
551+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE]: {
552+
expectedAddresses: readonly string[];
553+
unexpectedAddresses: readonly string[];
554+
};
555+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE]: {
556+
actualLength: number;
557+
};
558+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH]: {
559+
missingRequiredSigners: readonly string[];
560+
unexpectedSigners: readonly string[];
561+
};
562+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH]: {
563+
actualLength: number;
564+
};
565+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED]: {
566+
actualBytes: number;
567+
maxBytes: number;
568+
};
569+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH]: {
570+
actualMessageFormat: number;
571+
expectedMessageFormat: number;
572+
};
573+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH]: {
574+
actualLength: number;
575+
specifiedLength: number;
576+
};
577+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH]: {
578+
numRequiredSignatures: number;
579+
signaturesLength: number;
580+
signerAddresses: readonly string[];
581+
};
582+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING]: {
583+
addresses: readonly string[];
584+
};
585+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED]: {
586+
unsupportedVersion: number;
587+
};
541588
[SOLANA_ERROR__RPC_SUBSCRIPTIONS__CANNOT_CREATE_SUBSCRIPTION_PLAN]: {
542589
notificationName: string;
543590
};

packages/errors/src/messages.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,20 @@ import {
156156
SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR,
157157
SOLANA_ERROR__MALFORMED_NUMBER_STRING,
158158
SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND,
159+
SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE,
160+
SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE,
161+
SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH,
162+
SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH,
163+
SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED,
164+
SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH,
165+
SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH,
166+
SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY,
167+
SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO,
168+
SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO,
169+
SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH,
170+
SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE,
171+
SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING,
172+
SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED,
159173
SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD,
160174
SOLANA_ERROR__RPC__INTEGER_OVERFLOW,
161175
SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR,
@@ -487,6 +501,40 @@ export const SolanaErrorMessages: Readonly<{
487501
[SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR]: '$message',
488502
[SOLANA_ERROR__MALFORMED_NUMBER_STRING]: '`$value` cannot be parsed as a `Number`',
489503
[SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND]: 'No nonce account could be found at address `$nonceAccountAddress`',
504+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH]:
505+
'Expected base58 encoded application domain to decode to a byte array of length 32. Actual length: $actualLength.',
506+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE]:
507+
'Attempted to sign an offchain message with an address that is not a signer for it',
508+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE]:
509+
'Expected base58-encoded application domain string of length in the range [32, 44]. Actual length: $actualLength.',
510+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH]:
511+
'The signer addresses in this offchain message envelope do not match the list of ' +
512+
'required signers in the message preamble. These unexpected signers were present in the ' +
513+
'envelope: `[$unexpectedSigners]`. These required signers were missing from the envelope ' +
514+
'`[$missingSigners]`.',
515+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED]:
516+
'The message body provided has a byte-length of $actualBytes. The maximum allowable ' +
517+
'byte-length is $maxBytes',
518+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH]:
519+
'Expected message format $expectedMessageFormat, got $actualMessageFormat',
520+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH]:
521+
'The message length specified in the message preamble is $specifiedLength bytes. The actual length of the message is $actualLength bytes.',
522+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY]: 'Offchain message content must be non-empty',
523+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO]:
524+
'Offchain message must specify the address of at least one required signer',
525+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO]:
526+
'Offchain message envelope must reserve space for at least one signature',
527+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH]:
528+
'The offchain message preamble specifies $numRequiredSignatures required signature(s), got $signaturesLength.',
529+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING]:
530+
'Offchain message is missing signatures for addresses: $addresses.',
531+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE]:
532+
'The message body provided contains characters whose codes fall outside the allowed ' +
533+
'range. In order to ensure clear-signing compatiblity with hardware wallets, the message ' +
534+
'may only contain line feeds and characters in the range [\\x20-\\x7e].',
535+
[SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED]:
536+
'This version of Kit does not support decoding offchain messages with version ' +
537+
'$unsupportedVersion. The current max supported version is 0.',
490538
[SOLANA_ERROR__RPC_SUBSCRIPTIONS__CANNOT_CREATE_SUBSCRIPTION_PLAN]:
491539
"The notification name must end in 'Notifications' and the API must supply a " +
492540
"subscription plan creator function for the notification '$notificationName'.",

0 commit comments

Comments
 (0)