@verbeth/sdk 0.1.4 → 0.1.6
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 +20 -168
- package/dist/esm/src/addresses.d.ts +20 -0
- package/dist/esm/src/addresses.d.ts.map +1 -0
- package/dist/esm/src/addresses.js +33 -0
- package/dist/esm/src/client/HsrTagIndex.d.ts +77 -0
- package/dist/esm/src/client/HsrTagIndex.d.ts.map +1 -0
- package/dist/esm/src/client/HsrTagIndex.js +157 -0
- package/dist/esm/src/client/PendingManager.d.ts +65 -0
- package/dist/esm/src/client/PendingManager.d.ts.map +1 -0
- package/dist/esm/src/client/PendingManager.js +84 -0
- package/dist/esm/src/client/SessionManager.d.ts +65 -0
- package/dist/esm/src/client/SessionManager.d.ts.map +1 -0
- package/dist/esm/src/client/SessionManager.js +146 -0
- package/dist/esm/src/client/VerbethClient.d.ts +153 -99
- package/dist/esm/src/client/VerbethClient.d.ts.map +1 -1
- package/dist/esm/src/client/VerbethClient.js +429 -123
- package/dist/esm/src/client/VerbethClientBuilder.d.ts +105 -0
- package/dist/esm/src/client/VerbethClientBuilder.d.ts.map +1 -0
- package/dist/esm/src/client/VerbethClientBuilder.js +146 -0
- package/dist/esm/src/client/hsrMatcher.d.ts +22 -0
- package/dist/esm/src/client/hsrMatcher.d.ts.map +1 -0
- package/dist/esm/src/client/hsrMatcher.js +31 -0
- package/dist/esm/src/client/index.d.ts +6 -1
- package/dist/esm/src/client/index.d.ts.map +1 -1
- package/dist/esm/src/client/index.js +2 -0
- package/dist/esm/src/client/types.d.ts +151 -10
- package/dist/esm/src/client/types.d.ts.map +1 -1
- package/dist/esm/src/crypto(old).d.ts +46 -0
- package/dist/esm/src/crypto(old).d.ts.map +1 -0
- package/dist/esm/src/crypto(old).js +137 -0
- package/dist/esm/src/crypto.d.ts +7 -29
- package/dist/esm/src/crypto.d.ts.map +1 -1
- package/dist/esm/src/crypto.js +36 -72
- package/dist/esm/src/executor.d.ts +17 -18
- package/dist/esm/src/executor.d.ts.map +1 -1
- package/dist/esm/src/executor.js +54 -70
- package/dist/esm/src/handshake.d.ts +51 -0
- package/dist/esm/src/handshake.d.ts.map +1 -0
- package/dist/esm/src/handshake.js +105 -0
- package/dist/esm/src/identity.d.ts +24 -18
- package/dist/esm/src/identity.d.ts.map +1 -1
- package/dist/esm/src/identity.js +126 -31
- package/dist/esm/src/index.d.ts +11 -7
- package/dist/esm/src/index.d.ts.map +1 -1
- package/dist/esm/src/index.js +10 -7
- package/dist/esm/src/payload.d.ts +3 -30
- package/dist/esm/src/payload.d.ts.map +1 -1
- package/dist/esm/src/payload.js +3 -77
- package/dist/esm/src/pq/kem.d.ts +33 -0
- package/dist/esm/src/pq/kem.d.ts.map +1 -0
- package/dist/esm/src/pq/kem.js +40 -0
- package/dist/esm/src/ratchet/auth.d.ts +34 -0
- package/dist/esm/src/ratchet/auth.d.ts.map +1 -0
- package/dist/esm/src/ratchet/auth.js +88 -0
- package/dist/esm/src/ratchet/codec.d.ts +52 -0
- package/dist/esm/src/ratchet/codec.d.ts.map +1 -0
- package/dist/esm/src/ratchet/codec.js +127 -0
- package/dist/esm/src/ratchet/decrypt.d.ts +28 -0
- package/dist/esm/src/ratchet/decrypt.d.ts.map +1 -0
- package/dist/esm/src/ratchet/decrypt.js +255 -0
- package/dist/esm/src/ratchet/encrypt.d.ts +17 -0
- package/dist/esm/src/ratchet/encrypt.d.ts.map +1 -0
- package/dist/esm/src/ratchet/encrypt.js +78 -0
- package/dist/esm/src/ratchet/index.d.ts +8 -0
- package/dist/esm/src/ratchet/index.d.ts.map +1 -0
- package/dist/esm/src/ratchet/index.js +8 -0
- package/dist/esm/src/ratchet/kdf.d.ts +60 -0
- package/dist/esm/src/ratchet/kdf.d.ts.map +1 -0
- package/dist/esm/src/ratchet/kdf.js +91 -0
- package/dist/esm/src/ratchet/session.d.ts +43 -0
- package/dist/esm/src/ratchet/session.d.ts.map +1 -0
- package/dist/esm/src/ratchet/session.js +139 -0
- package/dist/esm/src/ratchet/types.d.ts +168 -0
- package/dist/esm/src/ratchet/types.d.ts.map +1 -0
- package/dist/esm/src/ratchet/types.js +27 -0
- package/dist/esm/src/safeSessionSigner.d.ts +35 -0
- package/dist/esm/src/safeSessionSigner.d.ts.map +1 -0
- package/dist/esm/src/safeSessionSigner.js +59 -0
- package/dist/esm/src/send.d.ts +32 -24
- package/dist/esm/src/send.d.ts.map +1 -1
- package/dist/esm/src/send.js +84 -39
- package/dist/esm/src/types.d.ts +8 -13
- package/dist/esm/src/types.d.ts.map +1 -1
- package/dist/esm/src/utils/safeSessionSigner.d.ts +23 -0
- package/dist/esm/src/utils/safeSessionSigner.d.ts.map +1 -0
- package/dist/esm/src/utils/safeSessionSigner.js +59 -0
- package/dist/esm/src/utils/txQueue.d.ts +12 -0
- package/dist/esm/src/utils/txQueue.d.ts.map +1 -0
- package/dist/esm/src/utils/txQueue.js +25 -0
- package/dist/esm/src/utils.d.ts +2 -3
- package/dist/esm/src/utils.d.ts.map +1 -1
- package/dist/esm/src/utils.js +5 -5
- package/dist/esm/src/verify.d.ts +9 -25
- package/dist/esm/src/verify.d.ts.map +1 -1
- package/dist/esm/src/verify.js +49 -50
- package/dist/src/addresses.d.ts +20 -0
- package/dist/src/addresses.d.ts.map +1 -0
- package/dist/src/addresses.js +33 -0
- package/dist/src/client/HsrTagIndex.d.ts +77 -0
- package/dist/src/client/HsrTagIndex.d.ts.map +1 -0
- package/dist/src/client/HsrTagIndex.js +157 -0
- package/dist/src/client/PendingManager.d.ts +65 -0
- package/dist/src/client/PendingManager.d.ts.map +1 -0
- package/dist/src/client/PendingManager.js +84 -0
- package/dist/src/client/SessionManager.d.ts +65 -0
- package/dist/src/client/SessionManager.d.ts.map +1 -0
- package/dist/src/client/SessionManager.js +146 -0
- package/dist/src/client/VerbethClient.d.ts +153 -99
- package/dist/src/client/VerbethClient.d.ts.map +1 -1
- package/dist/src/client/VerbethClient.js +429 -123
- package/dist/src/client/VerbethClientBuilder.d.ts +105 -0
- package/dist/src/client/VerbethClientBuilder.d.ts.map +1 -0
- package/dist/src/client/VerbethClientBuilder.js +146 -0
- package/dist/src/client/hsrMatcher.d.ts +22 -0
- package/dist/src/client/hsrMatcher.d.ts.map +1 -0
- package/dist/src/client/hsrMatcher.js +31 -0
- package/dist/src/client/index.d.ts +6 -1
- package/dist/src/client/index.d.ts.map +1 -1
- package/dist/src/client/index.js +2 -0
- package/dist/src/client/types.d.ts +151 -10
- package/dist/src/client/types.d.ts.map +1 -1
- package/dist/src/crypto(old).d.ts +46 -0
- package/dist/src/crypto(old).d.ts.map +1 -0
- package/dist/src/crypto(old).js +137 -0
- package/dist/src/crypto.d.ts +7 -29
- package/dist/src/crypto.d.ts.map +1 -1
- package/dist/src/crypto.js +36 -72
- package/dist/src/executor.d.ts +17 -18
- package/dist/src/executor.d.ts.map +1 -1
- package/dist/src/executor.js +54 -70
- package/dist/src/handshake.d.ts +51 -0
- package/dist/src/handshake.d.ts.map +1 -0
- package/dist/src/handshake.js +105 -0
- package/dist/src/identity.d.ts +24 -18
- package/dist/src/identity.d.ts.map +1 -1
- package/dist/src/identity.js +126 -31
- package/dist/src/index.d.ts +11 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -7
- package/dist/src/payload.d.ts +3 -30
- package/dist/src/payload.d.ts.map +1 -1
- package/dist/src/payload.js +3 -77
- package/dist/src/pq/kem.d.ts +33 -0
- package/dist/src/pq/kem.d.ts.map +1 -0
- package/dist/src/pq/kem.js +40 -0
- package/dist/src/ratchet/auth.d.ts +34 -0
- package/dist/src/ratchet/auth.d.ts.map +1 -0
- package/dist/src/ratchet/auth.js +88 -0
- package/dist/src/ratchet/codec.d.ts +52 -0
- package/dist/src/ratchet/codec.d.ts.map +1 -0
- package/dist/src/ratchet/codec.js +127 -0
- package/dist/src/ratchet/decrypt.d.ts +28 -0
- package/dist/src/ratchet/decrypt.d.ts.map +1 -0
- package/dist/src/ratchet/decrypt.js +255 -0
- package/dist/src/ratchet/encrypt.d.ts +17 -0
- package/dist/src/ratchet/encrypt.d.ts.map +1 -0
- package/dist/src/ratchet/encrypt.js +78 -0
- package/dist/src/ratchet/index.d.ts +8 -0
- package/dist/src/ratchet/index.d.ts.map +1 -0
- package/dist/src/ratchet/index.js +8 -0
- package/dist/src/ratchet/kdf.d.ts +60 -0
- package/dist/src/ratchet/kdf.d.ts.map +1 -0
- package/dist/src/ratchet/kdf.js +91 -0
- package/dist/src/ratchet/session.d.ts +43 -0
- package/dist/src/ratchet/session.d.ts.map +1 -0
- package/dist/src/ratchet/session.js +139 -0
- package/dist/src/ratchet/types.d.ts +168 -0
- package/dist/src/ratchet/types.d.ts.map +1 -0
- package/dist/src/ratchet/types.js +27 -0
- package/dist/src/safeSessionSigner.d.ts +35 -0
- package/dist/src/safeSessionSigner.d.ts.map +1 -0
- package/dist/src/safeSessionSigner.js +59 -0
- package/dist/src/send.d.ts +32 -24
- package/dist/src/send.d.ts.map +1 -1
- package/dist/src/send.js +84 -39
- package/dist/src/types.d.ts +8 -13
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/safeSessionSigner.d.ts +23 -0
- package/dist/src/utils/safeSessionSigner.d.ts.map +1 -0
- package/dist/src/utils/safeSessionSigner.js +59 -0
- package/dist/src/utils/txQueue.d.ts +12 -0
- package/dist/src/utils/txQueue.d.ts.map +1 -0
- package/dist/src/utils/txQueue.js +25 -0
- package/dist/src/utils.d.ts +2 -3
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +5 -5
- package/dist/src/verify.d.ts +9 -25
- package/dist/src/verify.d.ts.map +1 -1
- package/dist/src/verify.js +49 -50
- package/package.json +2 -1
package/dist/src/send.js
CHANGED
|
@@ -1,33 +1,26 @@
|
|
|
1
1
|
// packages/sdk/src/send.ts
|
|
2
2
|
import { keccak256, toUtf8Bytes, hexlify, getBytes } from "ethers";
|
|
3
3
|
import nacl from 'tweetnacl';
|
|
4
|
-
import {
|
|
5
|
-
import { encryptMessage, encryptStructuredPayload, deriveDuplexTopics } from './crypto.js';
|
|
4
|
+
import { encryptStructuredPayload } from './crypto.js';
|
|
6
5
|
import { serializeHandshakeContent, encodeUnifiedPubKeys, createHandshakeResponseContent, } from './payload.js';
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
* Sends an encrypted message assuming recipient's keys were already obtained via handshake.
|
|
10
|
-
* Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint (for tests)
|
|
11
|
-
*/
|
|
12
|
-
export async function sendEncryptedMessage({ executor, topic, message, recipientPubKey, senderAddress, senderSignKeyPair, timestamp }) {
|
|
13
|
-
if (!executor) {
|
|
14
|
-
throw new Error("Executor must be provided");
|
|
15
|
-
}
|
|
16
|
-
const ephemeralKeyPair = nacl.box.keyPair();
|
|
17
|
-
const ciphertext = encryptMessage(message, recipientPubKey, // X25519 for encryption
|
|
18
|
-
ephemeralKeyPair.secretKey, ephemeralKeyPair.publicKey, senderSignKeyPair.secretKey, // Ed25519 for signing
|
|
19
|
-
senderSignKeyPair.publicKey);
|
|
20
|
-
const nonce = getNextNonce(senderAddress, topic);
|
|
21
|
-
return executor.sendMessage(toUtf8Bytes(ciphertext), topic, timestamp, nonce);
|
|
22
|
-
}
|
|
6
|
+
import { computeHybridTagFromResponder } from './crypto.js';
|
|
7
|
+
import { kem } from './pq/kem.js';
|
|
23
8
|
/**
|
|
24
9
|
* Initiates an on-chain handshake with unified keys and mandatory identity proof.
|
|
25
10
|
* Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint (for tests)
|
|
11
|
+
*
|
|
12
|
+
* Includes ML-KEM-768 public key for post-quantum hybrid key exchange.
|
|
13
|
+
*
|
|
14
|
+
* @returns Transaction, ephemeral keypair, and KEM keypair (MUST be persisted for session init)
|
|
26
15
|
*/
|
|
27
|
-
export async function initiateHandshake({ executor, recipientAddress, identityKeyPair,
|
|
16
|
+
export async function initiateHandshake({ executor, recipientAddress, identityKeyPair, plaintextPayload, identityProof, }) {
|
|
28
17
|
if (!executor) {
|
|
29
18
|
throw new Error("Executor must be provided");
|
|
30
19
|
}
|
|
20
|
+
// Generate ephemeral keypair for this handshake
|
|
21
|
+
const ephemeralKeyPair = nacl.box.keyPair();
|
|
22
|
+
// Generate ML-KEM-768 keypair for PQ-hybrid key exchange
|
|
23
|
+
const kemKeyPair = kem.generateKeyPair();
|
|
31
24
|
const recipientHash = keccak256(toUtf8Bytes('contact:' + recipientAddress.toLowerCase()));
|
|
32
25
|
const handshakeContent = {
|
|
33
26
|
plaintextPayload,
|
|
@@ -38,38 +31,90 @@ export async function initiateHandshake({ executor, recipientAddress, identityKe
|
|
|
38
31
|
const unifiedPubKeys = encodeUnifiedPubKeys(identityKeyPair.publicKey, // X25519 for encryption
|
|
39
32
|
identityKeyPair.signingPublicKey // Ed25519 for signing
|
|
40
33
|
);
|
|
41
|
-
|
|
34
|
+
// Ephemeral public key now includes KEM public key (32 + 1184 = 1216 bytes)
|
|
35
|
+
const ephemeralWithKem = new Uint8Array(32 + kem.publicKeyBytes);
|
|
36
|
+
ephemeralWithKem.set(ephemeralKeyPair.publicKey, 0);
|
|
37
|
+
ephemeralWithKem.set(kemKeyPair.publicKey, 32);
|
|
38
|
+
const tx = await executor.initiateHandshake(recipientHash, hexlify(unifiedPubKeys), hexlify(ephemeralWithKem), toUtf8Bytes(serializedPayload));
|
|
39
|
+
return {
|
|
40
|
+
tx,
|
|
41
|
+
ephemeralKeyPair, // Caller MUST persist secretKey for ratchet session init
|
|
42
|
+
kemKeyPair, // Caller MUST also persist secretKey for KEM decapsulation
|
|
43
|
+
};
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
44
46
|
* Responds to a handshake with unified keys and mandatory identity proof.
|
|
45
47
|
* Executor-agnostic: works with EOA, UserOp, and Direct EntryPoint (for tests)
|
|
48
|
+
*
|
|
49
|
+
* Supports PQ-hybrid handshake: if initiator includes KEM public key,
|
|
50
|
+
* encapsulates a shared secret and includes ciphertext in response.
|
|
51
|
+
*
|
|
52
|
+
* @returns Transaction, tag, salt, ephemeral keys, and KEM secret
|
|
46
53
|
*/
|
|
47
|
-
export async function respondToHandshake({ executor,
|
|
48
|
-
responderIdentityKeyPair, responderEphemeralKeyPair, note, identityProof, signer, initiatorIdentityPubKey, }) {
|
|
54
|
+
export async function respondToHandshake({ executor, initiatorEphemeralPubKey, responderIdentityKeyPair, note, identityProof, }) {
|
|
49
55
|
if (!executor) {
|
|
50
56
|
throw new Error("Executor must be provided");
|
|
51
57
|
}
|
|
52
|
-
|
|
53
|
-
//
|
|
58
|
+
// =========================================================================
|
|
59
|
+
// TWO SEPARATE KEYPAIRS for unlinkability:
|
|
60
|
+
//
|
|
61
|
+
// 1. tagKeyPair (R, r): ONLY for tag computation
|
|
62
|
+
// - R goes on-chain as responderEphemeralR
|
|
63
|
+
// - Used by Alice to verify the tag
|
|
64
|
+
// - NOT used for ratchet
|
|
65
|
+
//
|
|
66
|
+
// 2. ratchetKeyPair: For post-handshake encryption and first DH ratchet key
|
|
67
|
+
// - Public key goes INSIDE encrypted payload (not on-chain)
|
|
68
|
+
// - Becomes dhMySecretKey/dhMyPublicKey in ratchet session
|
|
69
|
+
//
|
|
70
|
+
// Why this matters: With a single keypair, the on-chain R would equal the
|
|
71
|
+
// first message's DH header, allowing observers to link HandshakeResponse
|
|
72
|
+
// to subsequent conversation. With two keypairs, there's no on-chain link.
|
|
73
|
+
// =========================================================================
|
|
74
|
+
// Keypair for tag computation - R goes on-chain
|
|
54
75
|
const tagKeyPair = nacl.box.keyPair();
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
76
|
+
// Keypair for ratchet - public key is HIDDEN inside encrypted payload
|
|
77
|
+
const ratchetKeyPair = nacl.box.keyPair();
|
|
78
|
+
// Check if initiator included KEM public key (extended format: 32 + 1184 = 1216 bytes)
|
|
79
|
+
const hasKem = initiatorEphemeralPubKey.length === 32 + kem.publicKeyBytes;
|
|
80
|
+
// Extract X25519 ephemeral key (first 32 bytes)
|
|
81
|
+
const initiatorX25519Pub = hasKem
|
|
82
|
+
? initiatorEphemeralPubKey.slice(0, 32)
|
|
83
|
+
: initiatorEphemeralPubKey;
|
|
84
|
+
// KEM encapsulation FIRST (needed for hybrid tag)
|
|
85
|
+
let kemCiphertext;
|
|
86
|
+
let kemSharedSecret;
|
|
87
|
+
if (hasKem) {
|
|
88
|
+
const initiatorKemPub = initiatorEphemeralPubKey.slice(32, 32 + kem.publicKeyBytes);
|
|
89
|
+
const { ciphertext, sharedSecret } = kem.encapsulate(initiatorKemPub);
|
|
90
|
+
kemCiphertext = ciphertext;
|
|
91
|
+
kemSharedSecret = sharedSecret;
|
|
92
|
+
}
|
|
93
|
+
if (!kemSharedSecret) {
|
|
94
|
+
throw new Error("KEM is required for PQ-secure handshake");
|
|
61
95
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
//
|
|
69
|
-
|
|
96
|
+
// Hybrid tag: combines ECDH(r, viewPubA) + kemSecret
|
|
97
|
+
const inResponseTo = computeHybridTagFromResponder(tagKeyPair.secretKey, initiatorX25519Pub, kemSharedSecret);
|
|
98
|
+
const salt = getBytes(inResponseTo);
|
|
99
|
+
// Response content includes ratchetKeyPair.publicKey (hidden inside encrypted payload)
|
|
100
|
+
// and includes kemCiphertext for PQ-hybrid handshake
|
|
101
|
+
const responseContent = createHandshakeResponseContent(responderIdentityKeyPair.publicKey, // X25519 identity
|
|
102
|
+
responderIdentityKeyPair.signingPublicKey, // Ed25519 signing
|
|
103
|
+
ratchetKeyPair.publicKey, // First DH ratchet key (INSIDE payload)
|
|
104
|
+
note, identityProof, kemCiphertext);
|
|
105
|
+
// Encrypt using ratchetKeyPair (the epk in encrypted payload = ratchetKeyPair.publicKey)
|
|
106
|
+
const payload = encryptStructuredPayload(responseContent, initiatorX25519Pub, ratchetKeyPair.secretKey, ratchetKeyPair.publicKey);
|
|
107
|
+
// Execute transaction - tagKeyPair.publicKey goes on-chain (NOT ratchetKeyPair)
|
|
108
|
+
const tx = await executor.respondToHandshake(inResponseTo, hexlify(tagKeyPair.publicKey), // Tag key on-chain for tag verification
|
|
109
|
+
toUtf8Bytes(payload));
|
|
70
110
|
return {
|
|
71
111
|
tx,
|
|
72
112
|
salt,
|
|
73
|
-
tag: inResponseTo
|
|
113
|
+
tag: inResponseTo,
|
|
114
|
+
// Return RATCHET keys (not tag keys) for session initialization
|
|
115
|
+
// These are DIFFERENT from the on-chain responderEphemeralR
|
|
116
|
+
responderEphemeralSecret: ratchetKeyPair.secretKey,
|
|
117
|
+
responderEphemeralPublic: ratchetKeyPair.publicKey,
|
|
118
|
+
kemSharedSecret,
|
|
74
119
|
};
|
|
75
120
|
}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -18,25 +18,20 @@ export interface HandshakeResponseLog {
|
|
|
18
18
|
responderEphemeralR: string;
|
|
19
19
|
ciphertext: string;
|
|
20
20
|
}
|
|
21
|
-
export interface DuplexTopics {
|
|
22
|
-
/** Initiator → Responder */
|
|
23
|
-
topicOut: `0x${string}`;
|
|
24
|
-
/** Responder → Initiator */
|
|
25
|
-
topicIn: `0x${string}`;
|
|
26
|
-
}
|
|
27
|
-
/** Formato compatto per invio via HSR cifrata */
|
|
28
|
-
export interface TopicInfoWire {
|
|
29
|
-
out: `0x${string}`;
|
|
30
|
-
in: `0x${string}`;
|
|
31
|
-
/** checksum corto per conferma (8 byte, hex) */
|
|
32
|
-
chk: `0x${string}`;
|
|
33
|
-
}
|
|
34
21
|
export interface IdentityKeyPair {
|
|
35
22
|
publicKey: Uint8Array;
|
|
36
23
|
secretKey: Uint8Array;
|
|
37
24
|
signingPublicKey: Uint8Array;
|
|
38
25
|
signingSecretKey: Uint8Array;
|
|
39
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Context used to domain separate identity derivation and proof verification.
|
|
29
|
+
* rpId should be the dapp origin host (eg example.com) or a stable app id.
|
|
30
|
+
*/
|
|
31
|
+
export interface IdentityContext {
|
|
32
|
+
chainId?: number;
|
|
33
|
+
rpId?: string;
|
|
34
|
+
}
|
|
40
35
|
export interface IdentityProof {
|
|
41
36
|
message: string;
|
|
42
37
|
signature: string;
|
package/dist/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAE9B,SAAS,EAAE,UAAU,CAAC;IACtB,SAAS,EAAE,UAAU,CAAC;IAEtB,gBAAgB,EAAE,UAAU,CAAC;IAC7B,gBAAgB,EAAE,UAAU,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,MAAM,mBAAmB,GAAG,OAAO,kBAAkB,SAAS,MAAM,GACtE,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAC5C,eAAO,MAAM,kBAAkB,EAAE,aAAsB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AbstractSigner, type Provider, type Signer, type TransactionRequest, type TransactionResponse, type TypedDataDomain, type TypedDataField } from "ethers";
|
|
2
|
+
export interface SafeSessionSignerOptions {
|
|
3
|
+
provider: Provider;
|
|
4
|
+
safeAddress: string;
|
|
5
|
+
moduleAddress: string;
|
|
6
|
+
verbEthAddress: string;
|
|
7
|
+
sessionSigner: Signer;
|
|
8
|
+
}
|
|
9
|
+
export declare class SafeSessionSigner extends AbstractSigner {
|
|
10
|
+
private module;
|
|
11
|
+
private opts;
|
|
12
|
+
constructor(opts: SafeSessionSignerOptions);
|
|
13
|
+
getAddress(): Promise<string>;
|
|
14
|
+
getSessionSignerAddress(): Promise<string>;
|
|
15
|
+
isSessionValid(): Promise<boolean>;
|
|
16
|
+
isTargetAllowed(): Promise<boolean>;
|
|
17
|
+
signMessage(message: string | Uint8Array): Promise<string>;
|
|
18
|
+
signTransaction(_tx: TransactionRequest): Promise<string>;
|
|
19
|
+
signTypedData(domain: TypedDataDomain, types: Record<string, Array<TypedDataField>>, value: Record<string, any>): Promise<string>;
|
|
20
|
+
sendTransaction(tx: TransactionRequest): Promise<TransactionResponse>;
|
|
21
|
+
connect(provider: Provider): SafeSessionSigner;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=safeSessionSigner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeSessionSigner.d.ts","sourceRoot":"","sources":["../../../src/utils/safeSessionSigner.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EAEd,KAAK,QAAQ,EACb,KAAK,MAAM,EACX,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,QAAQ,CAAC;AAEhB,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AASD,qBAAa,iBAAkB,SAAQ,cAAc;IACnD,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,IAAI,CAA2B;gBAE3B,IAAI,EAAE,wBAAwB;IAiB3B,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAItC,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI1C,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAKlC,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAI1B,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAI1D,eAAe,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzD,aAAa,CAC1B,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,EAC5C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACzB,OAAO,CAAC,MAAM,CAAC;IAQH,eAAe,CAAC,EAAE,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAsB3E,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,iBAAiB;CAGxD"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// packages/sdk/src/utils/safeSessionSigner.ts
|
|
2
|
+
import { AbstractSigner, Contract, } from "ethers";
|
|
3
|
+
const MODULE_ABI = [
|
|
4
|
+
"function execute(address safe, address to, uint256 value, bytes data, uint8 operation) returns (bool)",
|
|
5
|
+
"function isValidSession(address safe, address signer) view returns (bool)",
|
|
6
|
+
"function sessionExpiry(address safe, address signer) view returns (uint256)",
|
|
7
|
+
"function isAllowedTarget(address safe, address target) view returns (bool)",
|
|
8
|
+
];
|
|
9
|
+
export class SafeSessionSigner extends AbstractSigner {
|
|
10
|
+
constructor(opts) {
|
|
11
|
+
super(opts.provider);
|
|
12
|
+
this.opts = opts;
|
|
13
|
+
if (!opts.sessionSigner.provider) {
|
|
14
|
+
throw new Error("SafeSessionSigner: sessionSigner must be connected to a Provider.");
|
|
15
|
+
}
|
|
16
|
+
this.module = new Contract(opts.moduleAddress, MODULE_ABI, opts.sessionSigner);
|
|
17
|
+
}
|
|
18
|
+
async getAddress() {
|
|
19
|
+
return this.opts.safeAddress;
|
|
20
|
+
}
|
|
21
|
+
async getSessionSignerAddress() {
|
|
22
|
+
return this.opts.sessionSigner.getAddress();
|
|
23
|
+
}
|
|
24
|
+
async isSessionValid() {
|
|
25
|
+
const signerAddr = await this.opts.sessionSigner.getAddress();
|
|
26
|
+
return this.module.isValidSession(this.opts.safeAddress, signerAddr);
|
|
27
|
+
}
|
|
28
|
+
async isTargetAllowed() {
|
|
29
|
+
return this.module.isAllowedTarget(this.opts.safeAddress, this.opts.verbEthAddress);
|
|
30
|
+
}
|
|
31
|
+
async signMessage(message) {
|
|
32
|
+
return this.opts.sessionSigner.signMessage(message);
|
|
33
|
+
}
|
|
34
|
+
async signTransaction(_tx) {
|
|
35
|
+
throw new Error("SafeSessionSigner: use sendTransaction() instead.");
|
|
36
|
+
}
|
|
37
|
+
async signTypedData(domain, types, value) {
|
|
38
|
+
const anySigner = this.opts.sessionSigner;
|
|
39
|
+
if (typeof anySigner.signTypedData === "function") {
|
|
40
|
+
return anySigner.signTypedData(domain, types, value);
|
|
41
|
+
}
|
|
42
|
+
throw new Error("SafeSessionSigner: signTypedData not supported.");
|
|
43
|
+
}
|
|
44
|
+
async sendTransaction(tx) {
|
|
45
|
+
if (!tx.to)
|
|
46
|
+
throw new Error("SafeSessionSigner: tx.to required");
|
|
47
|
+
const to = String(tx.to).toLowerCase();
|
|
48
|
+
const verbEth = this.opts.verbEthAddress.toLowerCase();
|
|
49
|
+
if (to !== verbEth) {
|
|
50
|
+
throw new Error(`SafeSessionSigner: only verbEth txs allowed. Got ${tx.to}`);
|
|
51
|
+
}
|
|
52
|
+
const data = tx.data ?? "0x";
|
|
53
|
+
// execute(safe, to, value, data, operation)
|
|
54
|
+
return this.module.execute(this.opts.safeAddress, this.opts.verbEthAddress, 0n, data, 0);
|
|
55
|
+
}
|
|
56
|
+
connect(provider) {
|
|
57
|
+
return new SafeSessionSigner({ ...this.opts, provider });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execute a transaction function with queue serialization.
|
|
3
|
+
*
|
|
4
|
+
* Ensures transactions from the same sender are submitted sequentially,
|
|
5
|
+
* preventing "replacement transaction underpriced" and "nonce too low" errors.
|
|
6
|
+
*
|
|
7
|
+
* @param senderAddress - The sender's address (queue key)
|
|
8
|
+
* @param txFn - Function that submits the transaction
|
|
9
|
+
* @returns The transaction result
|
|
10
|
+
*/
|
|
11
|
+
export declare function withTxQueue<T>(senderAddress: string, txFn: () => Promise<T>): Promise<T>;
|
|
12
|
+
//# sourceMappingURL=txQueue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"txQueue.d.ts","sourceRoot":"","sources":["../../../src/utils/txQueue.ts"],"names":[],"mappings":"AASA;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,CAAC,CAAC,CAWZ"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// packages/sdk/src/utils/txQueue.ts
|
|
2
|
+
/**
|
|
3
|
+
* Transaction queue for serializing blockchain transactions per sender.
|
|
4
|
+
* Prevents nonce conflicts when multiple txs are submitted in rapid succession.
|
|
5
|
+
*/
|
|
6
|
+
const txQueues = new Map();
|
|
7
|
+
/**
|
|
8
|
+
* Execute a transaction function with queue serialization.
|
|
9
|
+
*
|
|
10
|
+
* Ensures transactions from the same sender are submitted sequentially,
|
|
11
|
+
* preventing "replacement transaction underpriced" and "nonce too low" errors.
|
|
12
|
+
*
|
|
13
|
+
* @param senderAddress - The sender's address (queue key)
|
|
14
|
+
* @param txFn - Function that submits the transaction
|
|
15
|
+
* @returns The transaction result
|
|
16
|
+
*/
|
|
17
|
+
export async function withTxQueue(senderAddress, txFn) {
|
|
18
|
+
const previousTx = txQueues.get(senderAddress) ?? Promise.resolve();
|
|
19
|
+
const currentTx = previousTx
|
|
20
|
+
.catch(() => { }) // Don't block on previous errors
|
|
21
|
+
.then(() => txFn());
|
|
22
|
+
// Store the chain (ignore errors for queue tracking)
|
|
23
|
+
txQueues.set(senderAddress, currentTx.catch(() => { }));
|
|
24
|
+
return currentTx;
|
|
25
|
+
}
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { JsonRpcProvider } from "ethers";
|
|
2
2
|
import { type PublicClient } from "viem";
|
|
3
|
-
import { DuplexTopics } from "./types.js";
|
|
4
3
|
export declare function parseBindingMessage(message: string): {
|
|
5
4
|
header?: string;
|
|
6
5
|
address?: string;
|
|
7
6
|
pkEd25519?: `0x${string}`;
|
|
8
7
|
pkX25519?: `0x${string}`;
|
|
8
|
+
executorSafeAddress?: string;
|
|
9
9
|
context?: string;
|
|
10
10
|
version?: string;
|
|
11
11
|
chainId?: number;
|
|
@@ -22,8 +22,7 @@ export declare const ERC6492_SUFFIX = "0x649264926492649264926492649264926492649
|
|
|
22
22
|
export declare function hasERC6492Suffix(sigHex: string): boolean;
|
|
23
23
|
/**
|
|
24
24
|
* Checks if an address is a smart contract that supports EIP-1271 signature verification
|
|
25
|
-
* Returns true if the address has deployed code
|
|
25
|
+
* Returns true if the address has deployed code and implements isValidSignature function
|
|
26
26
|
*/
|
|
27
27
|
export declare function isSmartContract1271(address: string, provider: JsonRpcProvider): Promise<boolean>;
|
|
28
|
-
export declare function pickOutboundTopic(isInitiator: boolean, t: DuplexTopics): `0x${string}`;
|
|
29
28
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/src/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,eAAe,EAGhB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,eAAe,EAGhB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,MAAM,CAAC;AAGd,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CA4BA;AAED,MAAM,MAAM,MAAM,GACd,OAAO,QAAQ,EAAE,eAAe,GAChC,OAAO,QAAQ,EAAE,eAAe,GAChC;IAAE,OAAO,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAA;KAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;CAAE,CAAC;AAe5E,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CAmBvB;AAED,eAAO,MAAM,cAAc,uEAC2C,CAAC;AAEvE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAIxD;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,OAAO,CAAC,CA+DlB"}
|
package/dist/src/utils.js
CHANGED
|
@@ -23,6 +23,10 @@ export function parseBindingMessage(message) {
|
|
|
23
23
|
if (key === "pkx25519") {
|
|
24
24
|
out.pkX25519 = hexlify(val);
|
|
25
25
|
}
|
|
26
|
+
if (key === "executorsafeaddress" || key === "executorsafe") {
|
|
27
|
+
if (val)
|
|
28
|
+
out.executorSafeAddress = getAddress(val);
|
|
29
|
+
}
|
|
26
30
|
if (key === "context")
|
|
27
31
|
out.context = val;
|
|
28
32
|
if (key === "version")
|
|
@@ -70,7 +74,7 @@ export function hasERC6492Suffix(sigHex) {
|
|
|
70
74
|
}
|
|
71
75
|
/**
|
|
72
76
|
* Checks if an address is a smart contract that supports EIP-1271 signature verification
|
|
73
|
-
* Returns true if the address has deployed code
|
|
77
|
+
* Returns true if the address has deployed code and implements isValidSignature function
|
|
74
78
|
*/
|
|
75
79
|
export async function isSmartContract1271(address, provider) {
|
|
76
80
|
try {
|
|
@@ -117,7 +121,3 @@ export async function isSmartContract1271(address, provider) {
|
|
|
117
121
|
return false;
|
|
118
122
|
}
|
|
119
123
|
}
|
|
120
|
-
// picks the correct outbound topic from a DuplexTopics structure
|
|
121
|
-
export function pickOutboundTopic(isInitiator, t) {
|
|
122
|
-
return isInitiator ? t.topicOut : t.topicIn;
|
|
123
|
-
}
|
package/dist/src/verify.d.ts
CHANGED
|
@@ -1,54 +1,38 @@
|
|
|
1
1
|
import { JsonRpcProvider } from "ethers";
|
|
2
|
-
import { HandshakeLog, HandshakeResponseLog, IdentityProof,
|
|
2
|
+
import { HandshakeLog, HandshakeResponseLog, IdentityProof, IdentityContext } from "./types.js";
|
|
3
3
|
import { Rpcish } from "./utils.js";
|
|
4
4
|
/**
|
|
5
5
|
* handshake verification with mandatory identity proof
|
|
6
6
|
*/
|
|
7
|
-
export declare function verifyHandshakeIdentity(handshakeEvent: HandshakeLog, provider: JsonRpcProvider): Promise<boolean>;
|
|
7
|
+
export declare function verifyHandshakeIdentity(handshakeEvent: HandshakeLog, provider: JsonRpcProvider, ctx?: IdentityContext): Promise<boolean>;
|
|
8
8
|
/**
|
|
9
9
|
* handshake response verification with mandatory identity proof
|
|
10
10
|
*/
|
|
11
|
-
export declare function verifyHandshakeResponseIdentity(responseEvent: HandshakeResponseLog, responderIdentityPubKey: Uint8Array, initiatorEphemeralSecretKey: Uint8Array, provider: JsonRpcProvider): Promise<boolean>;
|
|
11
|
+
export declare function verifyHandshakeResponseIdentity(responseEvent: HandshakeResponseLog, responderIdentityPubKey: Uint8Array, initiatorEphemeralSecretKey: Uint8Array, provider: JsonRpcProvider, ctx?: IdentityContext): Promise<boolean>;
|
|
12
12
|
/**
|
|
13
|
-
* Verify
|
|
13
|
+
* Verify IdentityProof for EOAs and smart accounts.
|
|
14
14
|
* - Verifies the signature with viem (EOA / ERC-1271 / ERC-6492).
|
|
15
15
|
* - Parses and checks the expected address and public key against the message content.
|
|
16
16
|
*/
|
|
17
|
-
export declare function verifyIdentityProof(identityProof: IdentityProof,
|
|
17
|
+
export declare function verifyIdentityProof(identityProof: IdentityProof, address: string, expectedUnifiedKeys: {
|
|
18
18
|
identityPubKey: Uint8Array;
|
|
19
19
|
signingPubKey: Uint8Array;
|
|
20
|
-
}, provider: Rpcish): Promise<boolean>;
|
|
21
|
-
export declare function verifyAndExtractHandshakeKeys(handshakeEvent: HandshakeLog, provider: JsonRpcProvider): Promise<{
|
|
20
|
+
}, provider: Rpcish, ctx?: IdentityContext): Promise<boolean>;
|
|
21
|
+
export declare function verifyAndExtractHandshakeKeys(handshakeEvent: HandshakeLog, provider: JsonRpcProvider, ctx?: IdentityContext): Promise<{
|
|
22
22
|
isValid: boolean;
|
|
23
23
|
keys?: {
|
|
24
24
|
identityPubKey: Uint8Array;
|
|
25
25
|
signingPubKey: Uint8Array;
|
|
26
26
|
};
|
|
27
27
|
}>;
|
|
28
|
-
export declare function verifyAndExtractHandshakeResponseKeys(responseEvent: HandshakeResponseLog, initiatorEphemeralSecretKey: Uint8Array, provider: JsonRpcProvider): Promise<{
|
|
28
|
+
export declare function verifyAndExtractHandshakeResponseKeys(responseEvent: HandshakeResponseLog, initiatorEphemeralSecretKey: Uint8Array, initiatorKemSecretKey: Uint8Array, provider: JsonRpcProvider, ctx?: IdentityContext): Promise<{
|
|
29
29
|
isValid: boolean;
|
|
30
30
|
keys?: {
|
|
31
31
|
identityPubKey: Uint8Array;
|
|
32
32
|
signingPubKey: Uint8Array;
|
|
33
33
|
ephemeralPubKey: Uint8Array;
|
|
34
|
+
kemCiphertext?: Uint8Array;
|
|
34
35
|
note?: string;
|
|
35
36
|
};
|
|
36
37
|
}>;
|
|
37
|
-
/**
|
|
38
|
-
* Verify and derive duplex topics from a long-term DH secret.
|
|
39
|
-
* - Accepts either `tag` (inResponseTo) or a raw salt as KDF input.
|
|
40
|
-
* - Recomputes topicOut/topicIn deterministically from the identity DH.
|
|
41
|
-
* - If topicInfo is provided (from HSR), also verify the checksum.
|
|
42
|
-
* - Used by the initiator after decrypting a HandshakeResponse to confirm responder’s topics.
|
|
43
|
-
*/
|
|
44
|
-
export declare function verifyDerivedDuplexTopics({ myIdentitySecretKey, theirIdentityPubKey, tag, salt, topicInfo }: {
|
|
45
|
-
myIdentitySecretKey: Uint8Array;
|
|
46
|
-
theirIdentityPubKey: Uint8Array;
|
|
47
|
-
tag?: `0x${string}`;
|
|
48
|
-
salt?: Uint8Array;
|
|
49
|
-
topicInfo?: TopicInfoWire;
|
|
50
|
-
}): {
|
|
51
|
-
topics: DuplexTopics;
|
|
52
|
-
ok?: boolean;
|
|
53
|
-
};
|
|
54
38
|
//# sourceMappingURL=verify.d.ts.map
|
package/dist/src/verify.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/verify.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/verify.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAiC,MAAM,QAAQ,CAAC;AAGxE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEhG,OAAO,EACL,MAAM,EAGP,MAAM,YAAY,CAAC;AAIpB;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,cAAc,EAAE,YAAY,EAC5B,QAAQ,EAAE,eAAe,EACzB,GAAG,CAAC,EAAE,eAAe,GACpB,OAAO,CAAC,OAAO,CAAC,CAsClB;AAID;;GAEG;AACH,wBAAsB,+BAA+B,CACnD,aAAa,EAAE,oBAAoB,EACnC,uBAAuB,EAAE,UAAU,EACnC,2BAA2B,EAAE,UAAU,EACvC,QAAQ,EAAE,eAAe,EACzB,GAAG,CAAC,EAAE,eAAe,GACpB,OAAO,CAAC,OAAO,CAAC,CA2ClB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,MAAM,EACf,mBAAmB,EAAE;IACnB,cAAc,EAAE,UAAU,CAAC;IAC3B,aAAa,EAAE,UAAU,CAAC;CAC3B,EACD,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,eAAe,GACpB,OAAO,CAAC,OAAO,CAAC,CAgFlB;AAID,wBAAsB,6BAA6B,CACjD,cAAc,EAAE,YAAY,EAC5B,QAAQ,EAAE,eAAe,EACzB,GAAG,CAAC,EAAE,eAAe,GACpB,OAAO,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE;QACL,cAAc,EAAE,UAAU,CAAC;QAC3B,aAAa,EAAE,UAAU,CAAC;KAC3B,CAAC;CACH,CAAC,CAgBD;AAED,wBAAsB,qCAAqC,CACzD,aAAa,EAAE,oBAAoB,EACnC,2BAA2B,EAAE,UAAU,EACvC,qBAAqB,EAAE,UAAU,EACjC,QAAQ,EAAE,eAAe,EACzB,GAAG,CAAC,EAAE,eAAe,GACpB,OAAO,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE;QACL,cAAc,EAAE,UAAU,CAAC;QAC3B,aAAa,EAAE,UAAU,CAAC;QAC1B,eAAe,EAAE,UAAU,CAAC;QAC5B,aAAa,CAAC,EAAE,UAAU,CAAC;QAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH,CAAC,CAkDD"}
|