@qrlwallet/connect 5.0.3 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,8 +9,9 @@ Account validation and message-signature verification use the complete 64-byte
9
9
  address. Applications using legacy 20-byte addresses must remain on version 4
10
10
  until their network and wallet support QIP-55.
11
11
 
12
- Wallet typed-data requests are disabled pending a versioned 64-byte address
13
- encoding. The local verifier remains available for address-free typed data.
12
+ `qrl_signTypedData` signs payloads with QIP-55 address fields under
13
+ `QRL-SIGN-TYPED-v2` (one 64-byte word per value); address-free payloads keep
14
+ `QRL-SIGN-TYPED-v1`. See docs/JSON-RPC-REFERENCE.md.
14
15
  The private v3 network is a test network; its availability does not establish
15
16
  compatibility with legacy deployments or contracts.
16
17
 
@@ -173,16 +174,16 @@ The main class. Creates a connection manager and EIP-1193 provider.
173
174
  **Require user approval:**
174
175
  `qrl_requestAccounts`, `qrl_sendTransaction`, `qrl_signTransaction`, `qrl_signMessage`, `qrl_signTypedData`, `wallet_switchQrlChain`
175
176
 
176
- `qrl_signMessage` uses SHAKE256 plus native ML-DSA-87 ctx and returns a rich `{ signature, publicKey, descriptor, signer, digest, schemeVersion }` object. During the QIP-55 port, `qrl_signTypedData` stays in the approval policy and fails locally before relay use. Its v1 encoding fixes addresses to a 32-byte slot, so a new 64-byte encoding needs a new scheme version and regenerated wallet parity vectors.
177
+ `qrl_signMessage` and `qrl_signTypedData` use SHAKE256 plus native ML-DSA-87 ctx and return a rich `{ signature, publicKey, descriptor, signer, digest, schemeVersion }` object (typed data also echoes `domain`). Typed data with QIP-55 address fields is signed under `QRL-SIGN-TYPED-v2`, address-free typed data under `QRL-SIGN-TYPED-v1`.
177
178
 
178
179
  `request()` returns `unknown`. First validate the exact response shape with
179
180
  `isQrlSignedMessageResult` or `isQrlSignedTypedDataResult`, then require
180
181
  `hasSigningDescriptor`. PQP3 authenticates the paired transport session. It
181
182
  does not prove that the returned ML-DSA signature is valid or that its public
182
183
  key belongs to the claimed signer. Authentication and authorization flows must
183
- call `verifyMessageForSigner` or the historical v1 `verifyTypedDataForSigner`
184
- with the original challenge or payload and the expected QIP-55 Q + 128 hex
185
- address.
184
+ call `verifyMessageForSigner` or `verifyTypedDataForSigner` (pass the
185
+ response's `schemeVersion`) with the original challenge or payload and the
186
+ expected QIP-55 Q + 128 hex address.
186
187
 
187
188
  The lower-level `verifyMessageSignature` / `verifyTypedDataSignature` helpers
188
189
  verify only the supplied key and signature; they do not prove that the key
package/dist/index.d.mts CHANGED
@@ -269,8 +269,8 @@ interface EIP6963ProviderInfoOverride {
269
269
  rdns?: string;
270
270
  }
271
271
  /**
272
- * Rich response object returned by `qrl_signMessage` and retained for locked
273
- * `qrl_signTypedData` v1 fixtures. The signature alone is not enough to
272
+ * Rich response object returned by `qrl_signMessage` and
273
+ * `qrl_signTypedData`. The signature alone is not enough to
274
274
  * verify since ML-DSA-87 public keys cannot be recovered from a signature,
275
275
  * so the wallet returns the public key explicitly. Stateless verifiers need
276
276
  * the original payload plus the signature fields below.
@@ -290,24 +290,26 @@ interface QrlSignedResult {
290
290
  signer: string;
291
291
  /** 0x-hex of the 64-byte SHAKE256 digest that was signed. */
292
292
  digest: string;
293
- /** Scheme tag: 'QRL-SIGN-MSG-v1' or 'QRL-SIGN-TYPED-v1'. */
293
+ /** Scheme tag: 'QRL-SIGN-MSG-v1', 'QRL-SIGN-TYPED-v1' or 'QRL-SIGN-TYPED-v2'. */
294
294
  schemeVersion: QrlSigningSchemeVersion;
295
295
  }
296
296
  /** A current wallet response whose descriptor can be signer-bound. */
297
297
  interface QrlSignedResultWithDescriptor extends QrlSignedResult {
298
298
  descriptor: string;
299
299
  }
300
- type QrlSigningSchemeVersion = 'QRL-SIGN-MSG-v1' | 'QRL-SIGN-TYPED-v1';
300
+ type QrlSigningSchemeVersion = 'QRL-SIGN-MSG-v1' | 'QRL-SIGN-TYPED-v1' | 'QRL-SIGN-TYPED-v2';
301
301
  /** Strict wire shape returned by `qrl_signMessage`. */
302
302
  interface QrlSignedMessageResult extends QrlSignedResult {
303
303
  schemeVersion: 'QRL-SIGN-MSG-v1';
304
304
  }
305
305
  /**
306
- * Historical v1 response from `qrl_signTypedData`. It echoes `domain` so a
307
- * stateless verifier does not need to be told the domain out-of-band.
306
+ * Response from `qrl_signTypedData`. It echoes `domain` so a stateless
307
+ * verifier does not need to be told the domain out-of-band. The scheme is
308
+ * v2 when the payload's types reach an `address` field and v1 otherwise;
309
+ * pass `schemeVersion` to `verifyTypedDataForSigner` to have it checked.
308
310
  */
309
311
  interface QrlSignedTypedDataResult extends QrlSignedResult {
310
- schemeVersion: 'QRL-SIGN-TYPED-v1';
312
+ schemeVersion: 'QRL-SIGN-TYPED-v1' | 'QRL-SIGN-TYPED-v2';
311
313
  domain: Record<string, unknown>;
312
314
  }
313
315
  /** Every strict signing-result wire shape understood by this SDK. */
@@ -338,10 +340,9 @@ declare function hasSigningDescriptor(result: unknown): result is QrlSigningResu
338
340
  */
339
341
  type QrlSignMessageParams = [string, string];
340
342
  /**
341
- * Reserved `qrl_signTypedData` params: `[signer, payload]`. This interface
342
- * describes the historical v1 payload retained by the verifier exports. The
343
- * QIP-55 provider rejects requests until a versioned 64-byte encoding is
344
- * defined.
343
+ * `qrl_signTypedData` params: `[signer, payload]`. A payload whose types
344
+ * reach an `address` field is signed under QRL-SIGN-TYPED-v2, any other
345
+ * under v1.
345
346
  */
346
347
  interface QrlTypedDataPayload {
347
348
  types: Record<string, readonly {
@@ -870,8 +871,17 @@ declare class SocketClient extends EventEmitter<SocketClientEvents> {
870
871
  */
871
872
  declare const SCHEME_VERSION_MSG = "QRL-SIGN-MSG-v1";
872
873
  declare const SCHEME_VERSION_TYPED = "QRL-SIGN-TYPED-v1";
874
+ /**
875
+ * Typed data with 64-byte slots, one QRVM word per atomic value, so a QIP-55
876
+ * address fits. A payload uses it exactly when an `address` type is
877
+ * reachable from QRLDomain or the primary type; every other payload keeps
878
+ * v1. See typedData.ts.
879
+ */
880
+ declare const SCHEME_VERSION_TYPED_V2 = "QRL-SIGN-TYPED-v2";
881
+ type TypedDataSchemeVersion = typeof SCHEME_VERSION_TYPED | typeof SCHEME_VERSION_TYPED_V2;
873
882
  declare const SCHEME_TAG_MSG: Uint8Array;
874
883
  declare const SCHEME_TAG_TYPED: Uint8Array;
884
+ declare const SCHEME_TAG_TYPED_V2: Uint8Array;
875
885
  /** SHAKE256 output length used throughout the signing module (NIST L5-matched). */
876
886
  declare const DIGEST_LEN = 64;
877
887
 
@@ -887,7 +897,7 @@ declare const DIGEST_LEN = 64;
887
897
  declare function computeMessageDigest(messageBytes: Uint8Array): Uint8Array;
888
898
 
889
899
  /**
890
- * Historical EIP-712-shaped typed-data encoding for `qrl_signTypedData` v1.
900
+ * EIP-712-shaped typed-data encoding for `qrl_signTypedData`.
891
901
  *
892
902
  * Byte-identical algorithm with the wallet's signing/typedData.ts; this
893
903
  * file is the SDK port (only the import block differs: the SDK routes
@@ -895,10 +905,19 @@ declare function computeMessageDigest(messageBytes: Uint8Array): Uint8Array;
895
905
  * the wallet copy for the spec-level comments; behavior must stay in
896
906
  * lock-step or the cross-repo parity test fails on next CI.
897
907
  *
898
- * The v1 address slot is 32 bytes. QIP-55 address fields fail closed until a
899
- * 64-byte encoding receives a new scheme tag and lockstep wallet fixtures.
900
- * Address-free digests retain their existing encoding.
908
+ * Two schemes share this codec and differ only in the atomic slot size:
909
+ * - QRL-SIGN-TYPED-v1: 32-byte slots, the original layout.
910
+ * - QRL-SIGN-TYPED-v2: 64-byte slots, one QRVM word per atomic value, so a
911
+ * 64-byte QIP-55 address fits one slot. Integers are zero- or
912
+ * sign-extended over 512 bits, bool and address are left-padded, bytesN
913
+ * is right-padded.
914
+ * Strings, bytes, arrays, structs and type hashes are 64-byte SHAKE256
915
+ * digests in both. A payload uses v2 exactly when an `address` type
916
+ * (including address arrays) is reachable from QRLDomain or the primary
917
+ * type, so address-free payloads keep their v1 digests and older verifiers
918
+ * keep working for them.
901
919
  */
920
+
902
921
  declare const TYPED_DATA_LIMITS: Readonly<{
903
922
  maxTypes: 32;
904
923
  maxFieldsPerType: 32;
@@ -928,8 +947,25 @@ interface TypedDataPayload {
928
947
  }
929
948
  declare function encodeType(primary: string, types: TypeMap): string;
930
949
  declare function typeHash(primary: string, types: TypeMap): Uint8Array;
931
- declare function encodeField(type: FieldType, value: unknown, types: TypeMap): Uint8Array;
932
- declare function hashStruct(primary: string, data: Message, types: TypeMap): Uint8Array;
950
+ /**
951
+ * Encode one field. The scheme defaults to the one `types` selects (v2 when
952
+ * any struct has an address field), which matches computeTypedDataDigest
953
+ * when `types` is a payload's full type map.
954
+ */
955
+ declare function encodeField(type: FieldType, value: unknown, types: TypeMap, schemeVersion?: TypedDataSchemeVersion): Uint8Array;
956
+ /**
957
+ * Hash one struct. The scheme defaults to the one `types` selects (v2 when
958
+ * any struct has an address field), which matches computeTypedDataDigest
959
+ * when `types` is a payload's full type map.
960
+ */
961
+ declare function hashStruct(primary: string, data: Message, types: TypeMap, schemeVersion?: TypedDataSchemeVersion): Uint8Array;
962
+ /**
963
+ * The scheme a payload is signed and verified under. It follows from the
964
+ * payload's types alone, so wallet and verifier agree without negotiating.
965
+ */
966
+ declare function typedDataSchemeVersion(payload: unknown): TypedDataSchemeVersion;
967
+ /** The digest-preimage and ML-DSA-87 ctx tag of a typed-data scheme. */
968
+ declare function typedDataSchemeTag(schemeVersion: TypedDataSchemeVersion): Uint8Array;
933
969
  declare function computeTypedDataDigest(payload: unknown): Uint8Array;
934
970
 
935
971
  /**
@@ -961,13 +997,18 @@ interface VerifyTypedDataParams {
961
997
  signature: Uint8Array | string;
962
998
  publicKey: Uint8Array | string;
963
999
  payload: TypedDataPayload;
1000
+ /**
1001
+ * The `schemeVersion` from the wallet response. Optional: the payload's
1002
+ * types decide the scheme, and a supplied value must match it.
1003
+ */
1004
+ schemeVersion?: string | undefined;
964
1005
  }
965
1006
  /**
966
1007
  * Verify against an explicitly supplied ML-DSA public key only. This does not
967
1008
  * bind that key to a Q-address. Use verifyTypedDataForSigner when signer
968
1009
  * identity matters.
969
1010
  */
970
- declare function verifyTypedDataSignature({ signature, publicKey, payload, }: VerifyTypedDataParams): boolean;
1011
+ declare function verifyTypedDataSignature({ signature, publicKey, payload, schemeVersion, }: VerifyTypedDataParams): boolean;
971
1012
  interface VerifyMessageForSignerParams extends VerifyMessageParams {
972
1013
  /** QIP-55 Q + 128 hex address expected by the dApp. */
973
1014
  expectedSigner: string;
@@ -983,7 +1024,7 @@ interface VerifyTypedDataForSignerParams extends VerifyTypedDataParams {
983
1024
  descriptor?: Uint8Array | string | undefined;
984
1025
  }
985
1026
  /** Verify both the typed-data signature and public-key-to-signer binding. */
986
- declare function verifyTypedDataForSigner({ expectedSigner, descriptor, signature, publicKey, payload, }: VerifyTypedDataForSignerParams): boolean;
1027
+ declare function verifyTypedDataForSigner({ expectedSigner, descriptor, signature, publicKey, payload, schemeVersion, }: VerifyTypedDataForSignerParams): boolean;
987
1028
  /**
988
1029
  * @deprecated Use verifyMessageSignature for a key-only check, or
989
1030
  * verifyMessageForSigner when signer identity matters.
@@ -1135,4 +1176,4 @@ declare function isValidJsonRpcMethod(value: unknown): value is string;
1135
1176
  */
1136
1177
  declare function classifyRpcMethod(method: string): RpcMethodPolicy;
1137
1178
 
1138
- export { type AckMessage, BLOB_LEN, CAP_LEN, CID_LEN, ConnectionManager, ConnectionStatus, type DAppMetadata, type DAppSession, DEFAULT_RELAY_URL, DIGEST_LEN, type Domain, type EIP6963ProviderInfoOverride, EXPLICITLY_UNSUPPORTED_METHODS, FP_LEN, type InitiatedKeyExchange, type JsonRpcRequest, type JsonRpcResponse, KeyExchange, KeyExchangeMessageType, MAX_CONNECTION_URI_LENGTH, MAX_JSON_RPC_ID_LENGTH, MAX_JSON_RPC_METHOD_LENGTH, MAX_RELAY_URL_LENGTH, ML_DSA_87_PUBLIC_KEY_BYTES, ML_DSA_87_SIGNATURE_BYTES, ML_DSA_DESCRIPTOR_BYTES, type Message, MessageType, PAIRING_CAPABILITY_LEN, PROTOCOL_VERSION, type ParsedURI, type PendingRequest, type PersistedSession, type ProviderEvents, QRLConnectProvider as QRLConnect, type QRLConnectOptions, QRLConnectProvider, QRL_ADDRESS_BYTES, QRL_ADDRESS_HEX_LENGTH, QRL_CONNECT_PROVIDER_INFO, type QrlSignMessageParams, type QrlSignTypedDataParams, type QrlSignedMessageResult, type QrlSignedResult, type QrlSignedResultWithDescriptor, type QrlSignedTypedDataResult, type QrlSigningResult, type QrlSigningSchemeVersion, type QrlTypedDataPayload, RESTRICTED_METHODS, type RelayMessage, type RpcMethodPolicy, SCHEME_TAG_MSG, SCHEME_TAG_TYPED, SCHEME_VERSION_MSG, SCHEME_VERSION_TYPED, type Session, SocketClient, type StructDef, type SynAckMessage, TYPED_DATA_LIMITS, type TypeMap, type TypedDataPayload, type TypedField, UNRESTRICTED_METHODS, type VerifyMessageForSignerParams, type VerifyMessageParams, type VerifyTypedDataForSignerParams, type VerifyTypedDataParams, attemptWalletRedirect, bytesToHex, cidFromString, cidRandom, cidToString, classifyRpcMethod, computeFingerprint, computeMessageDigest, computeTypedDataDigest, concatBytes, encodeField, encodeType, fingerprintEquals, formatQrlAddressFingerprint, generateConnectionURI, getAppStoreUrl, hasSigningDescriptor, hashStruct, hexToBytes, isCurrentQrlAddress, isMobileBrowser, isQrlSignedMessageResult, isQrlSignedResult, isQrlSignedTypedDataResult, isValidJsonRpcId, isValidJsonRpcMethod, normalizeRelayUrl, parseConnectionURI, qip55AddressFromBytes, typeHash, verifyMessage, verifyMessageForSigner, verifyMessageSignature, verifyTypedData, verifyTypedDataForSigner, verifyTypedDataSignature };
1179
+ export { type AckMessage, BLOB_LEN, CAP_LEN, CID_LEN, ConnectionManager, ConnectionStatus, type DAppMetadata, type DAppSession, DEFAULT_RELAY_URL, DIGEST_LEN, type Domain, type EIP6963ProviderInfoOverride, EXPLICITLY_UNSUPPORTED_METHODS, FP_LEN, type InitiatedKeyExchange, type JsonRpcRequest, type JsonRpcResponse, KeyExchange, KeyExchangeMessageType, MAX_CONNECTION_URI_LENGTH, MAX_JSON_RPC_ID_LENGTH, MAX_JSON_RPC_METHOD_LENGTH, MAX_RELAY_URL_LENGTH, ML_DSA_87_PUBLIC_KEY_BYTES, ML_DSA_87_SIGNATURE_BYTES, ML_DSA_DESCRIPTOR_BYTES, type Message, MessageType, PAIRING_CAPABILITY_LEN, PROTOCOL_VERSION, type ParsedURI, type PendingRequest, type PersistedSession, type ProviderEvents, QRLConnectProvider as QRLConnect, type QRLConnectOptions, QRLConnectProvider, QRL_ADDRESS_BYTES, QRL_ADDRESS_HEX_LENGTH, QRL_CONNECT_PROVIDER_INFO, type QrlSignMessageParams, type QrlSignTypedDataParams, type QrlSignedMessageResult, type QrlSignedResult, type QrlSignedResultWithDescriptor, type QrlSignedTypedDataResult, type QrlSigningResult, type QrlSigningSchemeVersion, type QrlTypedDataPayload, RESTRICTED_METHODS, type RelayMessage, type RpcMethodPolicy, SCHEME_TAG_MSG, SCHEME_TAG_TYPED, SCHEME_TAG_TYPED_V2, SCHEME_VERSION_MSG, SCHEME_VERSION_TYPED, SCHEME_VERSION_TYPED_V2, type Session, SocketClient, type StructDef, type SynAckMessage, TYPED_DATA_LIMITS, type TypeMap, type TypedDataPayload, type TypedDataSchemeVersion, type TypedField, UNRESTRICTED_METHODS, type VerifyMessageForSignerParams, type VerifyMessageParams, type VerifyTypedDataForSignerParams, type VerifyTypedDataParams, attemptWalletRedirect, bytesToHex, cidFromString, cidRandom, cidToString, classifyRpcMethod, computeFingerprint, computeMessageDigest, computeTypedDataDigest, concatBytes, encodeField, encodeType, fingerprintEquals, formatQrlAddressFingerprint, generateConnectionURI, getAppStoreUrl, hasSigningDescriptor, hashStruct, hexToBytes, isCurrentQrlAddress, isMobileBrowser, isQrlSignedMessageResult, isQrlSignedResult, isQrlSignedTypedDataResult, isValidJsonRpcId, isValidJsonRpcMethod, normalizeRelayUrl, parseConnectionURI, qip55AddressFromBytes, typeHash, typedDataSchemeTag, typedDataSchemeVersion, verifyMessage, verifyMessageForSigner, verifyMessageSignature, verifyTypedData, verifyTypedDataForSigner, verifyTypedDataSignature };
package/dist/index.d.ts CHANGED
@@ -269,8 +269,8 @@ interface EIP6963ProviderInfoOverride {
269
269
  rdns?: string;
270
270
  }
271
271
  /**
272
- * Rich response object returned by `qrl_signMessage` and retained for locked
273
- * `qrl_signTypedData` v1 fixtures. The signature alone is not enough to
272
+ * Rich response object returned by `qrl_signMessage` and
273
+ * `qrl_signTypedData`. The signature alone is not enough to
274
274
  * verify since ML-DSA-87 public keys cannot be recovered from a signature,
275
275
  * so the wallet returns the public key explicitly. Stateless verifiers need
276
276
  * the original payload plus the signature fields below.
@@ -290,24 +290,26 @@ interface QrlSignedResult {
290
290
  signer: string;
291
291
  /** 0x-hex of the 64-byte SHAKE256 digest that was signed. */
292
292
  digest: string;
293
- /** Scheme tag: 'QRL-SIGN-MSG-v1' or 'QRL-SIGN-TYPED-v1'. */
293
+ /** Scheme tag: 'QRL-SIGN-MSG-v1', 'QRL-SIGN-TYPED-v1' or 'QRL-SIGN-TYPED-v2'. */
294
294
  schemeVersion: QrlSigningSchemeVersion;
295
295
  }
296
296
  /** A current wallet response whose descriptor can be signer-bound. */
297
297
  interface QrlSignedResultWithDescriptor extends QrlSignedResult {
298
298
  descriptor: string;
299
299
  }
300
- type QrlSigningSchemeVersion = 'QRL-SIGN-MSG-v1' | 'QRL-SIGN-TYPED-v1';
300
+ type QrlSigningSchemeVersion = 'QRL-SIGN-MSG-v1' | 'QRL-SIGN-TYPED-v1' | 'QRL-SIGN-TYPED-v2';
301
301
  /** Strict wire shape returned by `qrl_signMessage`. */
302
302
  interface QrlSignedMessageResult extends QrlSignedResult {
303
303
  schemeVersion: 'QRL-SIGN-MSG-v1';
304
304
  }
305
305
  /**
306
- * Historical v1 response from `qrl_signTypedData`. It echoes `domain` so a
307
- * stateless verifier does not need to be told the domain out-of-band.
306
+ * Response from `qrl_signTypedData`. It echoes `domain` so a stateless
307
+ * verifier does not need to be told the domain out-of-band. The scheme is
308
+ * v2 when the payload's types reach an `address` field and v1 otherwise;
309
+ * pass `schemeVersion` to `verifyTypedDataForSigner` to have it checked.
308
310
  */
309
311
  interface QrlSignedTypedDataResult extends QrlSignedResult {
310
- schemeVersion: 'QRL-SIGN-TYPED-v1';
312
+ schemeVersion: 'QRL-SIGN-TYPED-v1' | 'QRL-SIGN-TYPED-v2';
311
313
  domain: Record<string, unknown>;
312
314
  }
313
315
  /** Every strict signing-result wire shape understood by this SDK. */
@@ -338,10 +340,9 @@ declare function hasSigningDescriptor(result: unknown): result is QrlSigningResu
338
340
  */
339
341
  type QrlSignMessageParams = [string, string];
340
342
  /**
341
- * Reserved `qrl_signTypedData` params: `[signer, payload]`. This interface
342
- * describes the historical v1 payload retained by the verifier exports. The
343
- * QIP-55 provider rejects requests until a versioned 64-byte encoding is
344
- * defined.
343
+ * `qrl_signTypedData` params: `[signer, payload]`. A payload whose types
344
+ * reach an `address` field is signed under QRL-SIGN-TYPED-v2, any other
345
+ * under v1.
345
346
  */
346
347
  interface QrlTypedDataPayload {
347
348
  types: Record<string, readonly {
@@ -870,8 +871,17 @@ declare class SocketClient extends EventEmitter<SocketClientEvents> {
870
871
  */
871
872
  declare const SCHEME_VERSION_MSG = "QRL-SIGN-MSG-v1";
872
873
  declare const SCHEME_VERSION_TYPED = "QRL-SIGN-TYPED-v1";
874
+ /**
875
+ * Typed data with 64-byte slots, one QRVM word per atomic value, so a QIP-55
876
+ * address fits. A payload uses it exactly when an `address` type is
877
+ * reachable from QRLDomain or the primary type; every other payload keeps
878
+ * v1. See typedData.ts.
879
+ */
880
+ declare const SCHEME_VERSION_TYPED_V2 = "QRL-SIGN-TYPED-v2";
881
+ type TypedDataSchemeVersion = typeof SCHEME_VERSION_TYPED | typeof SCHEME_VERSION_TYPED_V2;
873
882
  declare const SCHEME_TAG_MSG: Uint8Array;
874
883
  declare const SCHEME_TAG_TYPED: Uint8Array;
884
+ declare const SCHEME_TAG_TYPED_V2: Uint8Array;
875
885
  /** SHAKE256 output length used throughout the signing module (NIST L5-matched). */
876
886
  declare const DIGEST_LEN = 64;
877
887
 
@@ -887,7 +897,7 @@ declare const DIGEST_LEN = 64;
887
897
  declare function computeMessageDigest(messageBytes: Uint8Array): Uint8Array;
888
898
 
889
899
  /**
890
- * Historical EIP-712-shaped typed-data encoding for `qrl_signTypedData` v1.
900
+ * EIP-712-shaped typed-data encoding for `qrl_signTypedData`.
891
901
  *
892
902
  * Byte-identical algorithm with the wallet's signing/typedData.ts; this
893
903
  * file is the SDK port (only the import block differs: the SDK routes
@@ -895,10 +905,19 @@ declare function computeMessageDigest(messageBytes: Uint8Array): Uint8Array;
895
905
  * the wallet copy for the spec-level comments; behavior must stay in
896
906
  * lock-step or the cross-repo parity test fails on next CI.
897
907
  *
898
- * The v1 address slot is 32 bytes. QIP-55 address fields fail closed until a
899
- * 64-byte encoding receives a new scheme tag and lockstep wallet fixtures.
900
- * Address-free digests retain their existing encoding.
908
+ * Two schemes share this codec and differ only in the atomic slot size:
909
+ * - QRL-SIGN-TYPED-v1: 32-byte slots, the original layout.
910
+ * - QRL-SIGN-TYPED-v2: 64-byte slots, one QRVM word per atomic value, so a
911
+ * 64-byte QIP-55 address fits one slot. Integers are zero- or
912
+ * sign-extended over 512 bits, bool and address are left-padded, bytesN
913
+ * is right-padded.
914
+ * Strings, bytes, arrays, structs and type hashes are 64-byte SHAKE256
915
+ * digests in both. A payload uses v2 exactly when an `address` type
916
+ * (including address arrays) is reachable from QRLDomain or the primary
917
+ * type, so address-free payloads keep their v1 digests and older verifiers
918
+ * keep working for them.
901
919
  */
920
+
902
921
  declare const TYPED_DATA_LIMITS: Readonly<{
903
922
  maxTypes: 32;
904
923
  maxFieldsPerType: 32;
@@ -928,8 +947,25 @@ interface TypedDataPayload {
928
947
  }
929
948
  declare function encodeType(primary: string, types: TypeMap): string;
930
949
  declare function typeHash(primary: string, types: TypeMap): Uint8Array;
931
- declare function encodeField(type: FieldType, value: unknown, types: TypeMap): Uint8Array;
932
- declare function hashStruct(primary: string, data: Message, types: TypeMap): Uint8Array;
950
+ /**
951
+ * Encode one field. The scheme defaults to the one `types` selects (v2 when
952
+ * any struct has an address field), which matches computeTypedDataDigest
953
+ * when `types` is a payload's full type map.
954
+ */
955
+ declare function encodeField(type: FieldType, value: unknown, types: TypeMap, schemeVersion?: TypedDataSchemeVersion): Uint8Array;
956
+ /**
957
+ * Hash one struct. The scheme defaults to the one `types` selects (v2 when
958
+ * any struct has an address field), which matches computeTypedDataDigest
959
+ * when `types` is a payload's full type map.
960
+ */
961
+ declare function hashStruct(primary: string, data: Message, types: TypeMap, schemeVersion?: TypedDataSchemeVersion): Uint8Array;
962
+ /**
963
+ * The scheme a payload is signed and verified under. It follows from the
964
+ * payload's types alone, so wallet and verifier agree without negotiating.
965
+ */
966
+ declare function typedDataSchemeVersion(payload: unknown): TypedDataSchemeVersion;
967
+ /** The digest-preimage and ML-DSA-87 ctx tag of a typed-data scheme. */
968
+ declare function typedDataSchemeTag(schemeVersion: TypedDataSchemeVersion): Uint8Array;
933
969
  declare function computeTypedDataDigest(payload: unknown): Uint8Array;
934
970
 
935
971
  /**
@@ -961,13 +997,18 @@ interface VerifyTypedDataParams {
961
997
  signature: Uint8Array | string;
962
998
  publicKey: Uint8Array | string;
963
999
  payload: TypedDataPayload;
1000
+ /**
1001
+ * The `schemeVersion` from the wallet response. Optional: the payload's
1002
+ * types decide the scheme, and a supplied value must match it.
1003
+ */
1004
+ schemeVersion?: string | undefined;
964
1005
  }
965
1006
  /**
966
1007
  * Verify against an explicitly supplied ML-DSA public key only. This does not
967
1008
  * bind that key to a Q-address. Use verifyTypedDataForSigner when signer
968
1009
  * identity matters.
969
1010
  */
970
- declare function verifyTypedDataSignature({ signature, publicKey, payload, }: VerifyTypedDataParams): boolean;
1011
+ declare function verifyTypedDataSignature({ signature, publicKey, payload, schemeVersion, }: VerifyTypedDataParams): boolean;
971
1012
  interface VerifyMessageForSignerParams extends VerifyMessageParams {
972
1013
  /** QIP-55 Q + 128 hex address expected by the dApp. */
973
1014
  expectedSigner: string;
@@ -983,7 +1024,7 @@ interface VerifyTypedDataForSignerParams extends VerifyTypedDataParams {
983
1024
  descriptor?: Uint8Array | string | undefined;
984
1025
  }
985
1026
  /** Verify both the typed-data signature and public-key-to-signer binding. */
986
- declare function verifyTypedDataForSigner({ expectedSigner, descriptor, signature, publicKey, payload, }: VerifyTypedDataForSignerParams): boolean;
1027
+ declare function verifyTypedDataForSigner({ expectedSigner, descriptor, signature, publicKey, payload, schemeVersion, }: VerifyTypedDataForSignerParams): boolean;
987
1028
  /**
988
1029
  * @deprecated Use verifyMessageSignature for a key-only check, or
989
1030
  * verifyMessageForSigner when signer identity matters.
@@ -1135,4 +1176,4 @@ declare function isValidJsonRpcMethod(value: unknown): value is string;
1135
1176
  */
1136
1177
  declare function classifyRpcMethod(method: string): RpcMethodPolicy;
1137
1178
 
1138
- export { type AckMessage, BLOB_LEN, CAP_LEN, CID_LEN, ConnectionManager, ConnectionStatus, type DAppMetadata, type DAppSession, DEFAULT_RELAY_URL, DIGEST_LEN, type Domain, type EIP6963ProviderInfoOverride, EXPLICITLY_UNSUPPORTED_METHODS, FP_LEN, type InitiatedKeyExchange, type JsonRpcRequest, type JsonRpcResponse, KeyExchange, KeyExchangeMessageType, MAX_CONNECTION_URI_LENGTH, MAX_JSON_RPC_ID_LENGTH, MAX_JSON_RPC_METHOD_LENGTH, MAX_RELAY_URL_LENGTH, ML_DSA_87_PUBLIC_KEY_BYTES, ML_DSA_87_SIGNATURE_BYTES, ML_DSA_DESCRIPTOR_BYTES, type Message, MessageType, PAIRING_CAPABILITY_LEN, PROTOCOL_VERSION, type ParsedURI, type PendingRequest, type PersistedSession, type ProviderEvents, QRLConnectProvider as QRLConnect, type QRLConnectOptions, QRLConnectProvider, QRL_ADDRESS_BYTES, QRL_ADDRESS_HEX_LENGTH, QRL_CONNECT_PROVIDER_INFO, type QrlSignMessageParams, type QrlSignTypedDataParams, type QrlSignedMessageResult, type QrlSignedResult, type QrlSignedResultWithDescriptor, type QrlSignedTypedDataResult, type QrlSigningResult, type QrlSigningSchemeVersion, type QrlTypedDataPayload, RESTRICTED_METHODS, type RelayMessage, type RpcMethodPolicy, SCHEME_TAG_MSG, SCHEME_TAG_TYPED, SCHEME_VERSION_MSG, SCHEME_VERSION_TYPED, type Session, SocketClient, type StructDef, type SynAckMessage, TYPED_DATA_LIMITS, type TypeMap, type TypedDataPayload, type TypedField, UNRESTRICTED_METHODS, type VerifyMessageForSignerParams, type VerifyMessageParams, type VerifyTypedDataForSignerParams, type VerifyTypedDataParams, attemptWalletRedirect, bytesToHex, cidFromString, cidRandom, cidToString, classifyRpcMethod, computeFingerprint, computeMessageDigest, computeTypedDataDigest, concatBytes, encodeField, encodeType, fingerprintEquals, formatQrlAddressFingerprint, generateConnectionURI, getAppStoreUrl, hasSigningDescriptor, hashStruct, hexToBytes, isCurrentQrlAddress, isMobileBrowser, isQrlSignedMessageResult, isQrlSignedResult, isQrlSignedTypedDataResult, isValidJsonRpcId, isValidJsonRpcMethod, normalizeRelayUrl, parseConnectionURI, qip55AddressFromBytes, typeHash, verifyMessage, verifyMessageForSigner, verifyMessageSignature, verifyTypedData, verifyTypedDataForSigner, verifyTypedDataSignature };
1179
+ export { type AckMessage, BLOB_LEN, CAP_LEN, CID_LEN, ConnectionManager, ConnectionStatus, type DAppMetadata, type DAppSession, DEFAULT_RELAY_URL, DIGEST_LEN, type Domain, type EIP6963ProviderInfoOverride, EXPLICITLY_UNSUPPORTED_METHODS, FP_LEN, type InitiatedKeyExchange, type JsonRpcRequest, type JsonRpcResponse, KeyExchange, KeyExchangeMessageType, MAX_CONNECTION_URI_LENGTH, MAX_JSON_RPC_ID_LENGTH, MAX_JSON_RPC_METHOD_LENGTH, MAX_RELAY_URL_LENGTH, ML_DSA_87_PUBLIC_KEY_BYTES, ML_DSA_87_SIGNATURE_BYTES, ML_DSA_DESCRIPTOR_BYTES, type Message, MessageType, PAIRING_CAPABILITY_LEN, PROTOCOL_VERSION, type ParsedURI, type PendingRequest, type PersistedSession, type ProviderEvents, QRLConnectProvider as QRLConnect, type QRLConnectOptions, QRLConnectProvider, QRL_ADDRESS_BYTES, QRL_ADDRESS_HEX_LENGTH, QRL_CONNECT_PROVIDER_INFO, type QrlSignMessageParams, type QrlSignTypedDataParams, type QrlSignedMessageResult, type QrlSignedResult, type QrlSignedResultWithDescriptor, type QrlSignedTypedDataResult, type QrlSigningResult, type QrlSigningSchemeVersion, type QrlTypedDataPayload, RESTRICTED_METHODS, type RelayMessage, type RpcMethodPolicy, SCHEME_TAG_MSG, SCHEME_TAG_TYPED, SCHEME_TAG_TYPED_V2, SCHEME_VERSION_MSG, SCHEME_VERSION_TYPED, SCHEME_VERSION_TYPED_V2, type Session, SocketClient, type StructDef, type SynAckMessage, TYPED_DATA_LIMITS, type TypeMap, type TypedDataPayload, type TypedDataSchemeVersion, type TypedField, UNRESTRICTED_METHODS, type VerifyMessageForSignerParams, type VerifyMessageParams, type VerifyTypedDataForSignerParams, type VerifyTypedDataParams, attemptWalletRedirect, bytesToHex, cidFromString, cidRandom, cidToString, classifyRpcMethod, computeFingerprint, computeMessageDigest, computeTypedDataDigest, concatBytes, encodeField, encodeType, fingerprintEquals, formatQrlAddressFingerprint, generateConnectionURI, getAppStoreUrl, hasSigningDescriptor, hashStruct, hexToBytes, isCurrentQrlAddress, isMobileBrowser, isQrlSignedMessageResult, isQrlSignedResult, isQrlSignedTypedDataResult, isValidJsonRpcId, isValidJsonRpcMethod, normalizeRelayUrl, parseConnectionURI, qip55AddressFromBytes, typeHash, typedDataSchemeTag, typedDataSchemeVersion, verifyMessage, verifyMessageForSigner, verifyMessageSignature, verifyTypedData, verifyTypedDataForSigner, verifyTypedDataSignature };
package/dist/index.js CHANGED
@@ -59,8 +59,10 @@ __export(index_exports, {
59
59
  RESTRICTED_METHODS: () => RESTRICTED_METHODS,
60
60
  SCHEME_TAG_MSG: () => SCHEME_TAG_MSG,
61
61
  SCHEME_TAG_TYPED: () => SCHEME_TAG_TYPED,
62
+ SCHEME_TAG_TYPED_V2: () => SCHEME_TAG_TYPED_V2,
62
63
  SCHEME_VERSION_MSG: () => SCHEME_VERSION_MSG,
63
64
  SCHEME_VERSION_TYPED: () => SCHEME_VERSION_TYPED,
65
+ SCHEME_VERSION_TYPED_V2: () => SCHEME_VERSION_TYPED_V2,
64
66
  SocketClient: () => SocketClient,
65
67
  TYPED_DATA_LIMITS: () => TYPED_DATA_LIMITS,
66
68
  UNRESTRICTED_METHODS: () => UNRESTRICTED_METHODS,
@@ -94,6 +96,8 @@ __export(index_exports, {
94
96
  parseConnectionURI: () => parseConnectionURI,
95
97
  qip55AddressFromBytes: () => qip55AddressFromBytes,
96
98
  typeHash: () => typeHash,
99
+ typedDataSchemeTag: () => typedDataSchemeTag,
100
+ typedDataSchemeVersion: () => typedDataSchemeVersion,
97
101
  verifyMessage: () => verifyMessage,
98
102
  verifyMessageForSigner: () => verifyMessageForSigner,
99
103
  verifyMessageSignature: () => verifyMessageSignature,
@@ -566,7 +570,7 @@ function isQrlSignedTypedDataResult(value) {
566
570
  try {
567
571
  if (!isSigningResultRecord(value)) return false;
568
572
  const keys = hasOwn(value, "descriptor") ? TYPED_RESULT_KEYS_WITH_DESCRIPTOR : TYPED_RESULT_KEYS;
569
- return hasExactOwnKeys(value, keys) && value.schemeVersion === "QRL-SIGN-TYPED-v1" && isSigningResultRecord(value.domain) && hasValidSigningFields(value);
573
+ return hasExactOwnKeys(value, keys) && (value.schemeVersion === "QRL-SIGN-TYPED-v1" || value.schemeVersion === "QRL-SIGN-TYPED-v2") && isSigningResultRecord(value.domain) && hasValidSigningFields(value);
570
574
  } catch {
571
575
  return false;
572
576
  }
@@ -3081,8 +3085,10 @@ var ConnectionManager = _ConnectionManager;
3081
3085
  // src/signing/ctx.ts
3082
3086
  var SCHEME_VERSION_MSG = "QRL-SIGN-MSG-v1";
3083
3087
  var SCHEME_VERSION_TYPED = "QRL-SIGN-TYPED-v1";
3088
+ var SCHEME_VERSION_TYPED_V2 = "QRL-SIGN-TYPED-v2";
3084
3089
  var SCHEME_TAG_MSG = new TextEncoder().encode(SCHEME_VERSION_MSG);
3085
3090
  var SCHEME_TAG_TYPED = new TextEncoder().encode(SCHEME_VERSION_TYPED);
3091
+ var SCHEME_TAG_TYPED_V2 = new TextEncoder().encode(SCHEME_VERSION_TYPED_V2);
3086
3092
  var DIGEST_LEN = 64;
3087
3093
 
3088
3094
  // src/signing/bytes.ts
@@ -3122,7 +3128,14 @@ function concatBytesArr(parts) {
3122
3128
  }
3123
3129
 
3124
3130
  // src/signing/typedData.ts
3125
- var SLOT = 32;
3131
+ var SLOT_BYTES = Object.freeze({
3132
+ [SCHEME_VERSION_TYPED]: 32,
3133
+ [SCHEME_VERSION_TYPED_V2]: 64
3134
+ });
3135
+ var SCHEME_TAGS = Object.freeze({
3136
+ [SCHEME_VERSION_TYPED]: SCHEME_TAG_TYPED,
3137
+ [SCHEME_VERSION_TYPED_V2]: SCHEME_TAG_TYPED_V2
3138
+ });
3126
3139
  var TYPED_DATA_LIMITS = Object.freeze({
3127
3140
  maxTypes: 32,
3128
3141
  maxFieldsPerType: 32,
@@ -3174,6 +3187,12 @@ function parsePayload(payload) {
3174
3187
  var ATOMIC_RE = /^(?:(address|bool|string|bytes)|(u?int)(\d+)|bytes(\d+)|(.+?)\[(\d*)\])$/;
3175
3188
  var IDENTIFIER_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
3176
3189
  var UNSAFE_OBJECT_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
3190
+ function newBudget(schemeVersion) {
3191
+ return {
3192
+ remainingValues: TYPED_DATA_LIMITS.maxEncodedValues,
3193
+ slot: SLOT_BYTES[schemeVersion]
3194
+ };
3195
+ }
3177
3196
  function consumeValue(budget) {
3178
3197
  budget.remainingValues--;
3179
3198
  if (budget.remainingValues < 0) throw new Error("typed data contains too many encoded values");
@@ -3320,29 +3339,29 @@ function encodeType(primary, types) {
3320
3339
  function typeHash(primary, types) {
3321
3340
  return shake256Digest(new TextEncoder().encode(encodeType(primary, types)), DIGEST_LEN);
3322
3341
  }
3323
- function parseQAddress(addr) {
3342
+ function parseQAddress(addr, slot) {
3324
3343
  if (!isCurrentQrlAddress(addr)) {
3325
3344
  throw new Error(`invalid Q-address: ${String(addr)}`);
3326
3345
  }
3327
3346
  const bytes = hexToBytes("0x" + addr.slice(1).toLowerCase());
3328
- if (bytes.length > SLOT) {
3347
+ if (bytes.length > slot) {
3329
3348
  throw new Error("qrl_signTypedData v1 does not support QIP-55 address fields");
3330
3349
  }
3331
3350
  return bytes;
3332
3351
  }
3333
- function padLeft32(bytes) {
3334
- if (bytes.length > SLOT) throw new Error("cannot pad: bytes > 32");
3335
- const out = new Uint8Array(SLOT);
3336
- out.set(bytes, SLOT - bytes.length);
3352
+ function padLeft(bytes, slot) {
3353
+ if (bytes.length > slot) throw new Error(`cannot pad: bytes > ${slot}`);
3354
+ const out = new Uint8Array(slot);
3355
+ out.set(bytes, slot - bytes.length);
3337
3356
  return out;
3338
3357
  }
3339
- function padRight32(bytes) {
3340
- if (bytes.length > SLOT) throw new Error("cannot pad: bytes > 32");
3341
- const out = new Uint8Array(SLOT);
3358
+ function padRight(bytes, slot) {
3359
+ if (bytes.length > slot) throw new Error(`cannot pad: bytes > ${slot}`);
3360
+ const out = new Uint8Array(slot);
3342
3361
  out.set(bytes, 0);
3343
3362
  return out;
3344
3363
  }
3345
- function bigIntToSlot(value, width, signed) {
3364
+ function bigIntToSlot(value, width, signed, slot) {
3346
3365
  if (signed) {
3347
3366
  const limit = 1n << BigInt(width - 1);
3348
3367
  if (value >= limit || value < -limit) {
@@ -3353,11 +3372,12 @@ function bigIntToSlot(value, width, signed) {
3353
3372
  const limit = 1n << BigInt(width);
3354
3373
  if (value >= limit) throw new Error(`uint${width} out of range: ${value}`);
3355
3374
  }
3356
- const slotMask = (1n << 256n) - 1n;
3357
- const repr = value < 0n ? value + (1n << 256n) & slotMask : value;
3358
- const out = new Uint8Array(SLOT);
3375
+ const slotBits = BigInt(slot * 8);
3376
+ const slotMask = (1n << slotBits) - 1n;
3377
+ const repr = value < 0n ? value + (1n << slotBits) & slotMask : value;
3378
+ const out = new Uint8Array(slot);
3359
3379
  let v = repr;
3360
- for (let i = SLOT - 1; i >= 0; i--) {
3380
+ for (let i = slot - 1; i >= 0; i--) {
3361
3381
  out[i] = Number(v & 0xffn);
3362
3382
  v >>= 8n;
3363
3383
  }
@@ -3401,12 +3421,12 @@ function encodeFieldWithBudget(type, value, types, budget, depth) {
3401
3421
  if (typeof value !== "string") {
3402
3422
  throw new Error(`address field expects string: ${typeof value}`);
3403
3423
  }
3404
- return padLeft32(parseQAddress(value));
3424
+ return padLeft(parseQAddress(value, budget.slot), budget.slot);
3405
3425
  case "bool":
3406
3426
  if (typeof value !== "boolean") {
3407
3427
  throw new Error(`bool field expects boolean: ${typeof value}`);
3408
3428
  }
3409
- return padLeft32(new Uint8Array([value ? 1 : 0]));
3429
+ return padLeft(new Uint8Array([value ? 1 : 0]), budget.slot);
3410
3430
  case "string": {
3411
3431
  if (typeof value !== "string") {
3412
3432
  throw new Error(`string field expects string: ${typeof value}`);
@@ -3429,9 +3449,19 @@ function encodeFieldWithBudget(type, value, types, budget, depth) {
3429
3449
  }
3430
3450
  return shake256Digest(hexToBytes(value), DIGEST_LEN);
3431
3451
  case "uintN":
3432
- return bigIntToSlot(parseIntValue(value, `uint${parsed.width}`), parsed.width, false);
3452
+ return bigIntToSlot(
3453
+ parseIntValue(value, `uint${parsed.width}`),
3454
+ parsed.width,
3455
+ false,
3456
+ budget.slot
3457
+ );
3433
3458
  case "intN":
3434
- return bigIntToSlot(parseIntValue(value, `int${parsed.width}`), parsed.width, true);
3459
+ return bigIntToSlot(
3460
+ parseIntValue(value, `int${parsed.width}`),
3461
+ parsed.width,
3462
+ true,
3463
+ budget.slot
3464
+ );
3435
3465
  case "bytesN": {
3436
3466
  if (typeof value !== "string") {
3437
3467
  throw new Error(`bytes${parsed.width} expects 0x-hex string: ${typeof value}`);
@@ -3443,7 +3473,7 @@ function encodeFieldWithBudget(type, value, types, budget, depth) {
3443
3473
  if (raw.length !== parsed.width) {
3444
3474
  throw new Error(`bytes${parsed.width} requires ${parsed.width} bytes, got ${raw.length}`);
3445
3475
  }
3446
- return padRight32(raw);
3476
+ return padRight(raw, budget.slot);
3447
3477
  }
3448
3478
  case "array": {
3449
3479
  if (!Array.isArray(value)) {
@@ -3462,15 +3492,10 @@ function encodeFieldWithBudget(type, value, types, budget, depth) {
3462
3492
  }
3463
3493
  }
3464
3494
  }
3465
- function encodeField(type, value, types) {
3495
+ function encodeField(type, value, types, schemeVersion) {
3466
3496
  validateTypeMap(types);
3467
- return encodeFieldWithBudget(
3468
- type,
3469
- value,
3470
- types,
3471
- { remainingValues: TYPED_DATA_LIMITS.maxEncodedValues },
3472
- 0
3473
- );
3497
+ const scheme = schemeVersion ?? schemeVersionForTypes(types);
3498
+ return encodeFieldWithBudget(type, value, types, newBudget(scheme), 0);
3474
3499
  }
3475
3500
  function hashStructWithBudget(primary, data, types, budget, depth) {
3476
3501
  consumeValue(budget);
@@ -3495,15 +3520,10 @@ function hashStructWithBudget(primary, data, types, budget, depth) {
3495
3520
  }
3496
3521
  return shake256Digest(concatBytesArr(parts), DIGEST_LEN);
3497
3522
  }
3498
- function hashStruct(primary, data, types) {
3523
+ function hashStruct(primary, data, types, schemeVersion) {
3499
3524
  validateTypeMap(types);
3500
- return hashStructWithBudget(
3501
- primary,
3502
- data,
3503
- types,
3504
- { remainingValues: TYPED_DATA_LIMITS.maxEncodedValues },
3505
- 0
3506
- );
3525
+ const scheme = schemeVersion ?? schemeVersionForTypes(types);
3526
+ return hashStructWithBudget(primary, data, types, newBudget(scheme), 0);
3507
3527
  }
3508
3528
  var RESERVED_DOMAIN_FIELDS = {
3509
3529
  name: "string",
@@ -3539,7 +3559,7 @@ function validatePayloadReachability(primary, types) {
3539
3559
  if (!reachable.has(k)) throw new Error(`unused referenced type: ${k}`);
3540
3560
  }
3541
3561
  }
3542
- function computeTypedDataDigest(payload) {
3562
+ function parseAndValidatePayload(payload) {
3543
3563
  const parsed = parsePayload(payload);
3544
3564
  validateTypeMap(parsed.types);
3545
3565
  assertIdentifier(parsed.primaryType, "primary type");
@@ -3548,7 +3568,26 @@ function computeTypedDataDigest(payload) {
3548
3568
  }
3549
3569
  validateDomainTypes(parsed.types);
3550
3570
  validatePayloadReachability(parsed.primaryType, parsed.types);
3551
- const budget = { remainingValues: TYPED_DATA_LIMITS.maxEncodedValues };
3571
+ return parsed;
3572
+ }
3573
+ function schemeVersionForTypes(types) {
3574
+ for (const fields of Object.values(types)) {
3575
+ if (fields.some((f) => baseTypeName(f.type) === "address")) {
3576
+ return SCHEME_VERSION_TYPED_V2;
3577
+ }
3578
+ }
3579
+ return SCHEME_VERSION_TYPED;
3580
+ }
3581
+ function typedDataSchemeVersion(payload) {
3582
+ return schemeVersionForTypes(parseAndValidatePayload(payload).types);
3583
+ }
3584
+ function typedDataSchemeTag(schemeVersion) {
3585
+ return SCHEME_TAGS[schemeVersion];
3586
+ }
3587
+ function computeTypedDataDigest(payload) {
3588
+ const parsed = parseAndValidatePayload(payload);
3589
+ const schemeVersion = schemeVersionForTypes(parsed.types);
3590
+ const budget = newBudget(schemeVersion);
3552
3591
  const domainHash = hashStructWithBudget("QRLDomain", parsed.domain, parsed.types, budget, 0);
3553
3592
  const messageHash = hashStructWithBudget(
3554
3593
  parsed.primaryType,
@@ -3557,7 +3596,10 @@ function computeTypedDataDigest(payload) {
3557
3596
  budget,
3558
3597
  0
3559
3598
  );
3560
- return shake256Digest(concatBytes(SCHEME_TAG_TYPED, domainHash, messageHash), DIGEST_LEN);
3599
+ return shake256Digest(
3600
+ concatBytes(SCHEME_TAGS[schemeVersion], domainHash, messageHash),
3601
+ DIGEST_LEN
3602
+ );
3561
3603
  }
3562
3604
 
3563
3605
  // src/utils/platform.ts
@@ -3749,9 +3791,8 @@ function validateRestrictedRequest(method, params, authorizedAccounts, currentCh
3749
3791
  if (params[0] !== authorizedAccount) {
3750
3792
  throw new Error("qrl_signTypedData signer is not the authorized account");
3751
3793
  }
3752
- throw new Error(
3753
- "qrl_signTypedData is unavailable for QIP-55 until the 64-byte word encoding and signing scheme version are finalized"
3754
- );
3794
+ computeTypedDataDigest(params[1]);
3795
+ return void 0;
3755
3796
  }
3756
3797
  function requiresAuthorizedAccount(method) {
3757
3798
  return method === "qrl_sendTransaction" || method === "qrl_signTransaction" || method === "qrl_signMessage" || method === "qrl_signTypedData";
@@ -4397,9 +4438,13 @@ function verifyMessageBytes(signature, publicKey, messageBytes) {
4397
4438
  const digest = computeMessageDigest(messageBytes);
4398
4439
  return mldsaVerify(signature, digest, publicKey, SCHEME_TAG_MSG);
4399
4440
  }
4400
- function verifyTypedDataBytes(signature, publicKey, payload) {
4441
+ function verifyTypedDataBytes(signature, publicKey, payload, claimedSchemeVersion) {
4442
+ const schemeVersion = typedDataSchemeVersion(payload);
4443
+ if (claimedSchemeVersion !== void 0 && claimedSchemeVersion !== schemeVersion) {
4444
+ return false;
4445
+ }
4401
4446
  const digest = computeTypedDataDigest(payload);
4402
- return mldsaVerify(signature, digest, publicKey, SCHEME_TAG_TYPED);
4447
+ return mldsaVerify(signature, digest, publicKey, typedDataSchemeTag(schemeVersion));
4403
4448
  }
4404
4449
  function verifyMessageSignature({
4405
4450
  signature,
@@ -4419,13 +4464,14 @@ function verifyMessageSignature({
4419
4464
  function verifyTypedDataSignature({
4420
4465
  signature,
4421
4466
  publicKey,
4422
- payload
4467
+ payload,
4468
+ schemeVersion
4423
4469
  }) {
4424
4470
  try {
4425
4471
  const sig = fixedBytesOrHex(signature, ML_DSA_87_SIGNATURE_BYTES);
4426
4472
  const pk = fixedBytesOrHex(publicKey, ML_DSA_87_PUBLIC_KEY_BYTES);
4427
4473
  if (!sig || !pk) return false;
4428
- return verifyTypedDataBytes(sig, pk, payload);
4474
+ return verifyTypedDataBytes(sig, pk, payload, schemeVersion);
4429
4475
  } catch {
4430
4476
  return false;
4431
4477
  }
@@ -4463,7 +4509,8 @@ function verifyTypedDataForSigner({
4463
4509
  descriptor,
4464
4510
  signature,
4465
4511
  publicKey,
4466
- payload
4512
+ payload,
4513
+ schemeVersion
4467
4514
  }) {
4468
4515
  try {
4469
4516
  if (descriptor === void 0) return false;
@@ -4471,7 +4518,7 @@ function verifyTypedDataForSigner({
4471
4518
  const publicKeyBytes = fixedBytesOrHex(publicKey, ML_DSA_87_PUBLIC_KEY_BYTES);
4472
4519
  const signatureBytes = fixedBytesOrHex(signature, ML_DSA_87_SIGNATURE_BYTES);
4473
4520
  if (!descriptorBytes || !publicKeyBytes || !signatureBytes) return false;
4474
- return publicKeyMatchesSigner(expectedSigner, descriptorBytes, publicKeyBytes) && verifyTypedDataBytes(signatureBytes, publicKeyBytes, payload);
4521
+ return publicKeyMatchesSigner(expectedSigner, descriptorBytes, publicKeyBytes) && verifyTypedDataBytes(signatureBytes, publicKeyBytes, payload, schemeVersion);
4475
4522
  } catch {
4476
4523
  return false;
4477
4524
  }
@@ -4513,8 +4560,10 @@ function verifyTypedData(params) {
4513
4560
  RESTRICTED_METHODS,
4514
4561
  SCHEME_TAG_MSG,
4515
4562
  SCHEME_TAG_TYPED,
4563
+ SCHEME_TAG_TYPED_V2,
4516
4564
  SCHEME_VERSION_MSG,
4517
4565
  SCHEME_VERSION_TYPED,
4566
+ SCHEME_VERSION_TYPED_V2,
4518
4567
  SocketClient,
4519
4568
  TYPED_DATA_LIMITS,
4520
4569
  UNRESTRICTED_METHODS,
@@ -4548,6 +4597,8 @@ function verifyTypedData(params) {
4548
4597
  parseConnectionURI,
4549
4598
  qip55AddressFromBytes,
4550
4599
  typeHash,
4600
+ typedDataSchemeTag,
4601
+ typedDataSchemeVersion,
4551
4602
  verifyMessage,
4552
4603
  verifyMessageForSigner,
4553
4604
  verifyMessageSignature,
package/dist/index.mjs CHANGED
@@ -461,7 +461,7 @@ function isQrlSignedTypedDataResult(value) {
461
461
  try {
462
462
  if (!isSigningResultRecord(value)) return false;
463
463
  const keys = hasOwn(value, "descriptor") ? TYPED_RESULT_KEYS_WITH_DESCRIPTOR : TYPED_RESULT_KEYS;
464
- return hasExactOwnKeys(value, keys) && value.schemeVersion === "QRL-SIGN-TYPED-v1" && isSigningResultRecord(value.domain) && hasValidSigningFields(value);
464
+ return hasExactOwnKeys(value, keys) && (value.schemeVersion === "QRL-SIGN-TYPED-v1" || value.schemeVersion === "QRL-SIGN-TYPED-v2") && isSigningResultRecord(value.domain) && hasValidSigningFields(value);
465
465
  } catch {
466
466
  return false;
467
467
  }
@@ -2976,8 +2976,10 @@ var ConnectionManager = _ConnectionManager;
2976
2976
  // src/signing/ctx.ts
2977
2977
  var SCHEME_VERSION_MSG = "QRL-SIGN-MSG-v1";
2978
2978
  var SCHEME_VERSION_TYPED = "QRL-SIGN-TYPED-v1";
2979
+ var SCHEME_VERSION_TYPED_V2 = "QRL-SIGN-TYPED-v2";
2979
2980
  var SCHEME_TAG_MSG = new TextEncoder().encode(SCHEME_VERSION_MSG);
2980
2981
  var SCHEME_TAG_TYPED = new TextEncoder().encode(SCHEME_VERSION_TYPED);
2982
+ var SCHEME_TAG_TYPED_V2 = new TextEncoder().encode(SCHEME_VERSION_TYPED_V2);
2981
2983
  var DIGEST_LEN = 64;
2982
2984
 
2983
2985
  // src/signing/bytes.ts
@@ -3017,7 +3019,14 @@ function concatBytesArr(parts) {
3017
3019
  }
3018
3020
 
3019
3021
  // src/signing/typedData.ts
3020
- var SLOT = 32;
3022
+ var SLOT_BYTES = Object.freeze({
3023
+ [SCHEME_VERSION_TYPED]: 32,
3024
+ [SCHEME_VERSION_TYPED_V2]: 64
3025
+ });
3026
+ var SCHEME_TAGS = Object.freeze({
3027
+ [SCHEME_VERSION_TYPED]: SCHEME_TAG_TYPED,
3028
+ [SCHEME_VERSION_TYPED_V2]: SCHEME_TAG_TYPED_V2
3029
+ });
3021
3030
  var TYPED_DATA_LIMITS = Object.freeze({
3022
3031
  maxTypes: 32,
3023
3032
  maxFieldsPerType: 32,
@@ -3069,6 +3078,12 @@ function parsePayload(payload) {
3069
3078
  var ATOMIC_RE = /^(?:(address|bool|string|bytes)|(u?int)(\d+)|bytes(\d+)|(.+?)\[(\d*)\])$/;
3070
3079
  var IDENTIFIER_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
3071
3080
  var UNSAFE_OBJECT_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
3081
+ function newBudget(schemeVersion) {
3082
+ return {
3083
+ remainingValues: TYPED_DATA_LIMITS.maxEncodedValues,
3084
+ slot: SLOT_BYTES[schemeVersion]
3085
+ };
3086
+ }
3072
3087
  function consumeValue(budget) {
3073
3088
  budget.remainingValues--;
3074
3089
  if (budget.remainingValues < 0) throw new Error("typed data contains too many encoded values");
@@ -3215,29 +3230,29 @@ function encodeType(primary, types) {
3215
3230
  function typeHash(primary, types) {
3216
3231
  return shake256Digest(new TextEncoder().encode(encodeType(primary, types)), DIGEST_LEN);
3217
3232
  }
3218
- function parseQAddress(addr) {
3233
+ function parseQAddress(addr, slot) {
3219
3234
  if (!isCurrentQrlAddress(addr)) {
3220
3235
  throw new Error(`invalid Q-address: ${String(addr)}`);
3221
3236
  }
3222
3237
  const bytes = hexToBytes("0x" + addr.slice(1).toLowerCase());
3223
- if (bytes.length > SLOT) {
3238
+ if (bytes.length > slot) {
3224
3239
  throw new Error("qrl_signTypedData v1 does not support QIP-55 address fields");
3225
3240
  }
3226
3241
  return bytes;
3227
3242
  }
3228
- function padLeft32(bytes) {
3229
- if (bytes.length > SLOT) throw new Error("cannot pad: bytes > 32");
3230
- const out = new Uint8Array(SLOT);
3231
- out.set(bytes, SLOT - bytes.length);
3243
+ function padLeft(bytes, slot) {
3244
+ if (bytes.length > slot) throw new Error(`cannot pad: bytes > ${slot}`);
3245
+ const out = new Uint8Array(slot);
3246
+ out.set(bytes, slot - bytes.length);
3232
3247
  return out;
3233
3248
  }
3234
- function padRight32(bytes) {
3235
- if (bytes.length > SLOT) throw new Error("cannot pad: bytes > 32");
3236
- const out = new Uint8Array(SLOT);
3249
+ function padRight(bytes, slot) {
3250
+ if (bytes.length > slot) throw new Error(`cannot pad: bytes > ${slot}`);
3251
+ const out = new Uint8Array(slot);
3237
3252
  out.set(bytes, 0);
3238
3253
  return out;
3239
3254
  }
3240
- function bigIntToSlot(value, width, signed) {
3255
+ function bigIntToSlot(value, width, signed, slot) {
3241
3256
  if (signed) {
3242
3257
  const limit = 1n << BigInt(width - 1);
3243
3258
  if (value >= limit || value < -limit) {
@@ -3248,11 +3263,12 @@ function bigIntToSlot(value, width, signed) {
3248
3263
  const limit = 1n << BigInt(width);
3249
3264
  if (value >= limit) throw new Error(`uint${width} out of range: ${value}`);
3250
3265
  }
3251
- const slotMask = (1n << 256n) - 1n;
3252
- const repr = value < 0n ? value + (1n << 256n) & slotMask : value;
3253
- const out = new Uint8Array(SLOT);
3266
+ const slotBits = BigInt(slot * 8);
3267
+ const slotMask = (1n << slotBits) - 1n;
3268
+ const repr = value < 0n ? value + (1n << slotBits) & slotMask : value;
3269
+ const out = new Uint8Array(slot);
3254
3270
  let v = repr;
3255
- for (let i = SLOT - 1; i >= 0; i--) {
3271
+ for (let i = slot - 1; i >= 0; i--) {
3256
3272
  out[i] = Number(v & 0xffn);
3257
3273
  v >>= 8n;
3258
3274
  }
@@ -3296,12 +3312,12 @@ function encodeFieldWithBudget(type, value, types, budget, depth) {
3296
3312
  if (typeof value !== "string") {
3297
3313
  throw new Error(`address field expects string: ${typeof value}`);
3298
3314
  }
3299
- return padLeft32(parseQAddress(value));
3315
+ return padLeft(parseQAddress(value, budget.slot), budget.slot);
3300
3316
  case "bool":
3301
3317
  if (typeof value !== "boolean") {
3302
3318
  throw new Error(`bool field expects boolean: ${typeof value}`);
3303
3319
  }
3304
- return padLeft32(new Uint8Array([value ? 1 : 0]));
3320
+ return padLeft(new Uint8Array([value ? 1 : 0]), budget.slot);
3305
3321
  case "string": {
3306
3322
  if (typeof value !== "string") {
3307
3323
  throw new Error(`string field expects string: ${typeof value}`);
@@ -3324,9 +3340,19 @@ function encodeFieldWithBudget(type, value, types, budget, depth) {
3324
3340
  }
3325
3341
  return shake256Digest(hexToBytes(value), DIGEST_LEN);
3326
3342
  case "uintN":
3327
- return bigIntToSlot(parseIntValue(value, `uint${parsed.width}`), parsed.width, false);
3343
+ return bigIntToSlot(
3344
+ parseIntValue(value, `uint${parsed.width}`),
3345
+ parsed.width,
3346
+ false,
3347
+ budget.slot
3348
+ );
3328
3349
  case "intN":
3329
- return bigIntToSlot(parseIntValue(value, `int${parsed.width}`), parsed.width, true);
3350
+ return bigIntToSlot(
3351
+ parseIntValue(value, `int${parsed.width}`),
3352
+ parsed.width,
3353
+ true,
3354
+ budget.slot
3355
+ );
3330
3356
  case "bytesN": {
3331
3357
  if (typeof value !== "string") {
3332
3358
  throw new Error(`bytes${parsed.width} expects 0x-hex string: ${typeof value}`);
@@ -3338,7 +3364,7 @@ function encodeFieldWithBudget(type, value, types, budget, depth) {
3338
3364
  if (raw.length !== parsed.width) {
3339
3365
  throw new Error(`bytes${parsed.width} requires ${parsed.width} bytes, got ${raw.length}`);
3340
3366
  }
3341
- return padRight32(raw);
3367
+ return padRight(raw, budget.slot);
3342
3368
  }
3343
3369
  case "array": {
3344
3370
  if (!Array.isArray(value)) {
@@ -3357,15 +3383,10 @@ function encodeFieldWithBudget(type, value, types, budget, depth) {
3357
3383
  }
3358
3384
  }
3359
3385
  }
3360
- function encodeField(type, value, types) {
3386
+ function encodeField(type, value, types, schemeVersion) {
3361
3387
  validateTypeMap(types);
3362
- return encodeFieldWithBudget(
3363
- type,
3364
- value,
3365
- types,
3366
- { remainingValues: TYPED_DATA_LIMITS.maxEncodedValues },
3367
- 0
3368
- );
3388
+ const scheme = schemeVersion ?? schemeVersionForTypes(types);
3389
+ return encodeFieldWithBudget(type, value, types, newBudget(scheme), 0);
3369
3390
  }
3370
3391
  function hashStructWithBudget(primary, data, types, budget, depth) {
3371
3392
  consumeValue(budget);
@@ -3390,15 +3411,10 @@ function hashStructWithBudget(primary, data, types, budget, depth) {
3390
3411
  }
3391
3412
  return shake256Digest(concatBytesArr(parts), DIGEST_LEN);
3392
3413
  }
3393
- function hashStruct(primary, data, types) {
3414
+ function hashStruct(primary, data, types, schemeVersion) {
3394
3415
  validateTypeMap(types);
3395
- return hashStructWithBudget(
3396
- primary,
3397
- data,
3398
- types,
3399
- { remainingValues: TYPED_DATA_LIMITS.maxEncodedValues },
3400
- 0
3401
- );
3416
+ const scheme = schemeVersion ?? schemeVersionForTypes(types);
3417
+ return hashStructWithBudget(primary, data, types, newBudget(scheme), 0);
3402
3418
  }
3403
3419
  var RESERVED_DOMAIN_FIELDS = {
3404
3420
  name: "string",
@@ -3434,7 +3450,7 @@ function validatePayloadReachability(primary, types) {
3434
3450
  if (!reachable.has(k)) throw new Error(`unused referenced type: ${k}`);
3435
3451
  }
3436
3452
  }
3437
- function computeTypedDataDigest(payload) {
3453
+ function parseAndValidatePayload(payload) {
3438
3454
  const parsed = parsePayload(payload);
3439
3455
  validateTypeMap(parsed.types);
3440
3456
  assertIdentifier(parsed.primaryType, "primary type");
@@ -3443,7 +3459,26 @@ function computeTypedDataDigest(payload) {
3443
3459
  }
3444
3460
  validateDomainTypes(parsed.types);
3445
3461
  validatePayloadReachability(parsed.primaryType, parsed.types);
3446
- const budget = { remainingValues: TYPED_DATA_LIMITS.maxEncodedValues };
3462
+ return parsed;
3463
+ }
3464
+ function schemeVersionForTypes(types) {
3465
+ for (const fields of Object.values(types)) {
3466
+ if (fields.some((f) => baseTypeName(f.type) === "address")) {
3467
+ return SCHEME_VERSION_TYPED_V2;
3468
+ }
3469
+ }
3470
+ return SCHEME_VERSION_TYPED;
3471
+ }
3472
+ function typedDataSchemeVersion(payload) {
3473
+ return schemeVersionForTypes(parseAndValidatePayload(payload).types);
3474
+ }
3475
+ function typedDataSchemeTag(schemeVersion) {
3476
+ return SCHEME_TAGS[schemeVersion];
3477
+ }
3478
+ function computeTypedDataDigest(payload) {
3479
+ const parsed = parseAndValidatePayload(payload);
3480
+ const schemeVersion = schemeVersionForTypes(parsed.types);
3481
+ const budget = newBudget(schemeVersion);
3447
3482
  const domainHash = hashStructWithBudget("QRLDomain", parsed.domain, parsed.types, budget, 0);
3448
3483
  const messageHash = hashStructWithBudget(
3449
3484
  parsed.primaryType,
@@ -3452,7 +3487,10 @@ function computeTypedDataDigest(payload) {
3452
3487
  budget,
3453
3488
  0
3454
3489
  );
3455
- return shake256Digest(concatBytes(SCHEME_TAG_TYPED, domainHash, messageHash), DIGEST_LEN);
3490
+ return shake256Digest(
3491
+ concatBytes(SCHEME_TAGS[schemeVersion], domainHash, messageHash),
3492
+ DIGEST_LEN
3493
+ );
3456
3494
  }
3457
3495
 
3458
3496
  // src/utils/platform.ts
@@ -3644,9 +3682,8 @@ function validateRestrictedRequest(method, params, authorizedAccounts, currentCh
3644
3682
  if (params[0] !== authorizedAccount) {
3645
3683
  throw new Error("qrl_signTypedData signer is not the authorized account");
3646
3684
  }
3647
- throw new Error(
3648
- "qrl_signTypedData is unavailable for QIP-55 until the 64-byte word encoding and signing scheme version are finalized"
3649
- );
3685
+ computeTypedDataDigest(params[1]);
3686
+ return void 0;
3650
3687
  }
3651
3688
  function requiresAuthorizedAccount(method) {
3652
3689
  return method === "qrl_sendTransaction" || method === "qrl_signTransaction" || method === "qrl_signMessage" || method === "qrl_signTypedData";
@@ -4292,9 +4329,13 @@ function verifyMessageBytes(signature, publicKey, messageBytes) {
4292
4329
  const digest = computeMessageDigest(messageBytes);
4293
4330
  return mldsaVerify(signature, digest, publicKey, SCHEME_TAG_MSG);
4294
4331
  }
4295
- function verifyTypedDataBytes(signature, publicKey, payload) {
4332
+ function verifyTypedDataBytes(signature, publicKey, payload, claimedSchemeVersion) {
4333
+ const schemeVersion = typedDataSchemeVersion(payload);
4334
+ if (claimedSchemeVersion !== void 0 && claimedSchemeVersion !== schemeVersion) {
4335
+ return false;
4336
+ }
4296
4337
  const digest = computeTypedDataDigest(payload);
4297
- return mldsaVerify(signature, digest, publicKey, SCHEME_TAG_TYPED);
4338
+ return mldsaVerify(signature, digest, publicKey, typedDataSchemeTag(schemeVersion));
4298
4339
  }
4299
4340
  function verifyMessageSignature({
4300
4341
  signature,
@@ -4314,13 +4355,14 @@ function verifyMessageSignature({
4314
4355
  function verifyTypedDataSignature({
4315
4356
  signature,
4316
4357
  publicKey,
4317
- payload
4358
+ payload,
4359
+ schemeVersion
4318
4360
  }) {
4319
4361
  try {
4320
4362
  const sig = fixedBytesOrHex(signature, ML_DSA_87_SIGNATURE_BYTES);
4321
4363
  const pk = fixedBytesOrHex(publicKey, ML_DSA_87_PUBLIC_KEY_BYTES);
4322
4364
  if (!sig || !pk) return false;
4323
- return verifyTypedDataBytes(sig, pk, payload);
4365
+ return verifyTypedDataBytes(sig, pk, payload, schemeVersion);
4324
4366
  } catch {
4325
4367
  return false;
4326
4368
  }
@@ -4358,7 +4400,8 @@ function verifyTypedDataForSigner({
4358
4400
  descriptor,
4359
4401
  signature,
4360
4402
  publicKey,
4361
- payload
4403
+ payload,
4404
+ schemeVersion
4362
4405
  }) {
4363
4406
  try {
4364
4407
  if (descriptor === void 0) return false;
@@ -4366,7 +4409,7 @@ function verifyTypedDataForSigner({
4366
4409
  const publicKeyBytes = fixedBytesOrHex(publicKey, ML_DSA_87_PUBLIC_KEY_BYTES);
4367
4410
  const signatureBytes = fixedBytesOrHex(signature, ML_DSA_87_SIGNATURE_BYTES);
4368
4411
  if (!descriptorBytes || !publicKeyBytes || !signatureBytes) return false;
4369
- return publicKeyMatchesSigner(expectedSigner, descriptorBytes, publicKeyBytes) && verifyTypedDataBytes(signatureBytes, publicKeyBytes, payload);
4412
+ return publicKeyMatchesSigner(expectedSigner, descriptorBytes, publicKeyBytes) && verifyTypedDataBytes(signatureBytes, publicKeyBytes, payload, schemeVersion);
4370
4413
  } catch {
4371
4414
  return false;
4372
4415
  }
@@ -4407,8 +4450,10 @@ export {
4407
4450
  RESTRICTED_METHODS,
4408
4451
  SCHEME_TAG_MSG,
4409
4452
  SCHEME_TAG_TYPED,
4453
+ SCHEME_TAG_TYPED_V2,
4410
4454
  SCHEME_VERSION_MSG,
4411
4455
  SCHEME_VERSION_TYPED,
4456
+ SCHEME_VERSION_TYPED_V2,
4412
4457
  SocketClient,
4413
4458
  TYPED_DATA_LIMITS,
4414
4459
  UNRESTRICTED_METHODS,
@@ -4442,6 +4487,8 @@ export {
4442
4487
  parseConnectionURI,
4443
4488
  qip55AddressFromBytes,
4444
4489
  typeHash,
4490
+ typedDataSchemeTag,
4491
+ typedDataSchemeVersion,
4445
4492
  verifyMessage,
4446
4493
  verifyMessageForSigner,
4447
4494
  verifyMessageSignature,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qrlwallet/connect",
3
- "version": "5.0.3",
3
+ "version": "5.1.0",
4
4
  "packageManager": "npm@10.9.8",
5
5
  "description": "Connect your dApp to QRL Wallet via QR code or deep link",
6
6
  "main": "dist/index.js",