diff --git a/bindings_node/src/client.rs b/bindings_node/src/client.rs index 9a8e094e7..5190525f5 100644 --- a/bindings_node/src/client.rs +++ b/bindings_node/src/client.rs @@ -13,12 +13,9 @@ use tracing_subscriber::{fmt, prelude::*}; pub use xmtp_api_grpc::grpc_api_helper::Client as TonicApiClient; use xmtp_cryptography::signature::ed25519_public_key_to_address; use xmtp_id::associations::builder::SignatureRequest; -use xmtp_id::associations::MemberIdentifier; -use xmtp_mls::api::ApiClientWrapper; use xmtp_mls::builder::ClientBuilder; use xmtp_mls::groups::scoped_client::LocalScopedGroupClient; use xmtp_mls::identity::IdentityStrategy; -use xmtp_mls::retry::Retry; use xmtp_mls::storage::{EncryptedMessageStore, EncryptionKey, StorageOption}; use xmtp_mls::Client as MlsClient; use xmtp_proto::xmtp::mls::message_contents::DeviceSyncKind; @@ -303,90 +300,4 @@ impl Client { .map_err(ErrorWrapper::from)?; Ok(state.into_iter().map(Into::into).collect()) } - - #[napi] - pub async fn is_address_authorized(&self, inbox_id: String, address: String) -> Result { - self - .is_member_of_association_state(&inbox_id, &MemberIdentifier::Address(address)) - .await - } - - #[napi] - pub async fn is_installation_authorized( - &self, - inbox_id: String, - installation_id: Uint8Array, - ) -> Result { - self - .is_member_of_association_state( - &inbox_id, - &MemberIdentifier::Installation(installation_id.to_vec()), - ) - .await - } - - async fn is_member_of_association_state( - &self, - inbox_id: &str, - identifier: &MemberIdentifier, - ) -> Result { - let client = &self.inner_client; - let conn = self - .inner_client - .store() - .conn() - .map_err(ErrorWrapper::from)?; - - let association_state = client - .get_association_state(&conn, inbox_id, None) - .await - .map_err(ErrorWrapper::from)?; - - Ok(association_state.get(identifier).is_some()) - } -} - -#[napi] -pub async fn is_installation_authorized( - host: String, - inbox_id: String, - installation_id: Uint8Array, -) -> Result { - is_member_of_association_state( - &host, - &inbox_id, - &MemberIdentifier::Installation(installation_id.to_vec()), - ) - .await -} - -#[napi] -pub async fn is_address_authorized( - host: String, - inbox_id: String, - address: String, -) -> Result { - is_member_of_association_state(&host, &inbox_id, &MemberIdentifier::Address(address)).await -} - -async fn is_member_of_association_state( - host: &str, - inbox_id: &str, - identifier: &MemberIdentifier, -) -> Result { - let api_client = TonicApiClient::create(host, true) - .await - .map_err(ErrorWrapper::from)?; - let api_client = ApiClientWrapper::new(Arc::new(api_client), Retry::default()); - - let is_member = xmtp_mls::identity_updates::is_member_of_association_state( - &api_client, - inbox_id, - identifier, - None, - ) - .await - .map_err(ErrorWrapper::from)?; - - Ok(is_member) } diff --git a/bindings_node/src/inbox_id.rs b/bindings_node/src/inbox_id.rs index 34821514a..b9a4d34a9 100644 --- a/bindings_node/src/inbox_id.rs +++ b/bindings_node/src/inbox_id.rs @@ -1,8 +1,11 @@ use crate::ErrorWrapper; use napi::bindgen_prelude::Result; +use napi::bindgen_prelude::Uint8Array; use napi_derive::napi; +use std::sync::Arc; use xmtp_api_grpc::grpc_api_helper::Client as TonicApiClient; use xmtp_id::associations::generate_inbox_id as xmtp_id_generate_inbox_id; +use xmtp_id::associations::MemberIdentifier; use xmtp_mls::api::ApiClientWrapper; use xmtp_mls::retry::Retry; @@ -37,3 +40,53 @@ pub fn generate_inbox_id(account_address: String) -> Result { let result = xmtp_id_generate_inbox_id(&account_address, &1).map_err(ErrorWrapper::from)?; Ok(result) } + +#[napi] +pub async fn is_installation_authorized( + host: String, + inbox_id: String, + installation_id: Uint8Array, +) -> Result { + is_member_of_association_state( + &host, + &inbox_id, + &MemberIdentifier::Installation(installation_id.to_vec()), + ) + .await +} + +#[napi] +pub async fn is_address_authorized( + host: String, + inbox_id: String, + address: String, +) -> Result { + is_member_of_association_state( + &host, + &inbox_id, + &MemberIdentifier::Address(address.to_lowercase()), + ) + .await +} + +async fn is_member_of_association_state( + host: &str, + inbox_id: &str, + identifier: &MemberIdentifier, +) -> Result { + let api_client = TonicApiClient::create(host, true) + .await + .map_err(ErrorWrapper::from)?; + let api_client = ApiClientWrapper::new(Arc::new(api_client), Retry::default()); + + let is_member = xmtp_mls::identity_updates::is_member_of_association_state( + &api_client, + inbox_id, + identifier, + None, + ) + .await + .map_err(ErrorWrapper::from)?; + + Ok(is_member) +} diff --git a/bindings_node/test/inboxId.test.ts b/bindings_node/test/inboxId.test.ts index bb771853f..d4e4e2139 100644 --- a/bindings_node/test/inboxId.test.ts +++ b/bindings_node/test/inboxId.test.ts @@ -1,6 +1,11 @@ import { describe, expect, it } from 'vitest' import { createRegisteredClient, createUser, TEST_API_URL } from '@test/helpers' -import { generateInboxId, getInboxIdForAddress } from '../dist/index' +import { + generateInboxId, + getInboxIdForAddress, + isAddressAuthorized, + isInstallationAuthorized, +} from '../dist/index' describe('generateInboxId', () => { it('should generate an inbox id', () => { @@ -32,3 +37,29 @@ describe('getInboxIdForAddress', () => { expect(inboxId).toBe(client.inboxId()) }) }) + +describe('isInstallationAuthorized', () => { + it('should return true if installation is authorized', async () => { + const user = createUser() + const client = await createRegisteredClient(user) + const isAuthorized = await isInstallationAuthorized( + TEST_API_URL, + client.inboxId(), + client.installationIdBytes() + ) + expect(isAuthorized).toBe(true) + }) +}) + +describe('isAddressAuthorized', () => { + it('should return true if address is authorized', async () => { + const user = createUser() + const client = await createRegisteredClient(user) + const isAuthorized = await isAddressAuthorized( + TEST_API_URL, + client.inboxId(), + user.account.address + ) + expect(isAuthorized).toBe(true) + }) +})