commit a2e3f9749773c47b6ae7c8c4a06b29c0aa4e0cf6
parent 77b381648ed1e586efb696888beb05b9215c69cf
Author: triesap <tyson@radroots.org>
Date: Tue, 25 Aug 2026 02:16:05 +0000
nip46: bind connect to transport identity
- validate the NIP-46 remote signer key against the transport provider
- reject user and unrelated identities before connection admission
- update the accumulated NIP-46 wave fixture to the protocol identity
- preserve the separate user identity for delegated signing operations
Diffstat:
2 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/src/nip46_wave_080_a.rs b/src/nip46_wave_080_a.rs
@@ -216,7 +216,7 @@ pub(crate) fn connect_request() -> Request {
Request::from_parts(
Method::Connect,
vec![
- keys(3).public_key().to_hex(),
+ keys(2).public_key().to_hex(),
String::new(),
"sign_event:kind:1".to_owned(),
],
diff --git a/src/nip46_work.rs b/src/nip46_work.rs
@@ -449,8 +449,8 @@ pub fn prepare_myc_nip46_work(
if connection.is_some() || provider_deadline.is_some() || secret.is_some() {
return Err(work_error(MycNip46WorkErrorKind::InvalidBinding));
}
- let user = user_binding(providers)?;
- if remote_signer_public_key.to_hex() != user.expected_identity().as_hex() {
+ let transport = transport_binding(providers)?;
+ if remote_signer_public_key.to_hex() != transport.expected_identity().as_hex() {
return Err(work_error(MycNip46WorkErrorKind::InvalidBinding));
}
let permissions = connect_permissions(requested_permissions.as_slice())?;
@@ -607,6 +607,14 @@ fn user_binding(providers: &MycProviderContract) -> Result<&MycProviderBinding,
.ok_or_else(|| work_error(MycNip46WorkErrorKind::InvalidBinding))
}
+fn transport_binding(
+ providers: &MycProviderContract,
+) -> Result<&MycProviderBinding, MycNip46WorkError> {
+ providers
+ .binding(MycProviderRole::Transport)
+ .ok_or_else(|| work_error(MycNip46WorkErrorKind::InvalidBinding))
+}
+
fn sign_event_input(
event: &ConnectUnsignedEvent,
providers: &MycProviderContract,
@@ -989,7 +997,7 @@ mod tests {
let connect = protocol_request(
Method::Connect,
vec![
- keys(3).public_key().to_hex(),
+ keys(2).public_key().to_hex(),
String::new(),
"nip44_encrypt,sign_event:kind:1".into(),
],
@@ -1016,6 +1024,30 @@ mod tests {
)
.expect("admission request");
+ for (request_seed, remote_signer_seed) in [(21, 3), (22, 4)] {
+ let wrong_identity_connect = protocol_request(
+ Method::Connect,
+ vec![
+ keys(remote_signer_seed).public_key().to_hex(),
+ String::new(),
+ ],
+ );
+ let prepared = prepared_request(wrong_identity_connect, request_seed);
+ let record = prepared.signer_request.admitted_record_for_test();
+ assert_eq!(
+ prepare_myc_nip46_work(
+ prepared,
+ record,
+ None,
+ configuration().provider_contract(),
+ MycConnectionTimeUnixMs::new(RECEIVED_AT_MS + 1_000).expect("observation"),
+ None,
+ )
+ .expect_err("connect remote signer identity mismatch"),
+ work_error(MycNip46WorkErrorKind::InvalidBinding)
+ );
+ }
+
let secret_connect = protocol_request(
Method::Connect,
vec![keys(3).public_key().to_hex(), "forbidden-secret".into()],