Skip to content

Commit

Permalink
Expose installation ID bytes when calling inboxState (node + WASM b…
Browse files Browse the repository at this point in the history
…indings) (#1473)

* Update WASM bindings

* Update node bindings

* Prepare node bindings release

* Prepare WASM bindings release

* Refactor installation ID encoding (node)

* Refactor installation ID encoding (WASM)

* Remove ed25519_public_key_to_address

* Fix lint
  • Loading branch information
rygine authored Jan 6, 2025
1 parent 7fe4b38 commit 7f3a583
Show file tree
Hide file tree
Showing 12 changed files with 32 additions and 27 deletions.
4 changes: 4 additions & 0 deletions bindings_node/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# @xmtp/node-bindings

## 0.0.33

- Added installation ID `bytes` to return value of `inboxState`

## 0.0.32

- Add ability to revoke installations from a list of installations
Expand Down
2 changes: 1 addition & 1 deletion bindings_node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@xmtp/node-bindings",
"version": "0.0.32",
"version": "0.0.33",
"repository": {
"type": "git",
"url": "git+https://[email protected]/xmtp/libxmtp.git",
Expand Down
3 changes: 1 addition & 2 deletions bindings_node/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use std::sync::Arc;
use tokio::sync::Mutex;
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_mls::builder::ClientBuilder;
use xmtp_mls::groups::scoped_client::LocalScopedGroupClient;
Expand Down Expand Up @@ -200,7 +199,7 @@ impl Client {

#[napi]
pub fn installation_id(&self) -> String {
ed25519_public_key_to_address(self.inner_client.installation_public_key().as_slice())
hex::encode(self.inner_client.installation_public_key())
}

#[napi]
Expand Down
3 changes: 1 addition & 2 deletions bindings_node/src/conversation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use napi::{
threadsafe_function::{ErrorStrategy, ThreadsafeFunction, ThreadsafeFunctionCallMode},
JsFunction,
};
use xmtp_cryptography::signature::ed25519_public_key_to_address;
use xmtp_mls::{
groups::{
group_metadata::GroupMetadata as XmtpGroupMetadata,
Expand Down Expand Up @@ -231,7 +230,7 @@ impl Conversation {
installation_ids: member
.installation_ids
.into_iter()
.map(|id| ed25519_public_key_to_address(id.as_slice()))
.map(hex::encode)
.collect(),
permission_level: match member.permission_level {
XmtpPermissionLevel::Member => PermissionLevel::Member,
Expand Down
9 changes: 5 additions & 4 deletions bindings_node/src/inbox_state.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use napi::bindgen_prelude::{BigInt, Result};
use napi::bindgen_prelude::{BigInt, Result, Uint8Array};
use napi_derive::napi;
use xmtp_cryptography::signature::ed25519_public_key_to_address;
use xmtp_id::associations::{AssociationState, MemberIdentifier};

use crate::{client::Client, ErrorWrapper};

#[napi(object)]
pub struct Installation {
pub id: String,
pub bytes: Uint8Array,
pub client_timestamp_ns: Option<BigInt>,
pub id: String,
}

#[napi(object)]
Expand All @@ -30,8 +30,9 @@ impl From<AssociationState> for InboxState {
.filter_map(|m| match m.identifier {
MemberIdentifier::Address(_) => None,
MemberIdentifier::Installation(inst) => Some(Installation {
id: ed25519_public_key_to_address(inst.as_slice()),
bytes: Uint8Array::from(inst.as_slice()),
client_timestamp_ns: m.client_timestamp_ns.map(BigInt::from),
id: hex::encode(inst),
}),
})
.collect(),
Expand Down
6 changes: 6 additions & 0 deletions bindings_node/test/Client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ describe('Client', () => {
expect(inboxState.inboxId).toBe(client.inboxId())
expect(inboxState.installations.length).toBe(1)
expect(inboxState.installations[0].id).toBe(client.installationId())
expect(inboxState.installations[0].bytes).toEqual(
client.installationIdBytes()
)
expect(inboxState.accountAddresses).toEqual([
user.account.address.toLowerCase(),
])
Expand All @@ -64,6 +67,9 @@ describe('Client', () => {
expect(inboxState2.inboxId).toBe(client.inboxId())
expect(inboxState.installations.length).toBe(1)
expect(inboxState.installations[0].id).toBe(client.installationId())
expect(inboxState.installations[0].bytes).toEqual(
client.installationIdBytes()
)
expect(inboxState2.accountAddresses).toEqual([
user.account.address.toLowerCase(),
])
Expand Down
4 changes: 4 additions & 0 deletions bindings_wasm/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# @xmtp/wasm-bindings

## 0.0.11

- Added installation ID `bytes` to return value of `inboxState`

## 0.0.10

- Add ability to revoke installations from a list of installations
Expand Down
2 changes: 1 addition & 1 deletion bindings_wasm/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@xmtp/wasm-bindings",
"version": "0.0.10",
"version": "0.0.11",
"type": "module",
"license": "MIT",
"description": "WASM bindings for the libXMTP rust library",
Expand Down
3 changes: 1 addition & 2 deletions bindings_wasm/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use tracing_subscriber::{filter, fmt::format::Pretty};
use wasm_bindgen::prelude::{wasm_bindgen, JsError};
use wasm_bindgen::JsValue;
use xmtp_api_http::XmtpHttpApiClient;
use xmtp_cryptography::signature::ed25519_public_key_to_address;
use xmtp_id::associations::builder::SignatureRequest;
use xmtp_mls::builder::ClientBuilder;
use xmtp_mls::identity::IdentityStrategy;
Expand Down Expand Up @@ -202,7 +201,7 @@ impl Client {

#[wasm_bindgen(getter, js_name = installationId)]
pub fn installation_id(&self) -> String {
ed25519_public_key_to_address(self.inner_client.installation_public_key().as_slice())
hex::encode(self.inner_client.installation_public_key())
}

#[wasm_bindgen(getter, js_name = installationIdBytes)]
Expand Down
3 changes: 1 addition & 2 deletions bindings_wasm/src/conversation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crate::encoded_content::EncodedContent;
use crate::messages::{ListMessagesOptions, Message};
use crate::permissions::{MetadataField, PermissionPolicy, PermissionUpdateType};
use crate::{consent_state::ConsentState, permissions::GroupPermissions};
use xmtp_cryptography::signature::ed25519_public_key_to_address;
use xmtp_mls::groups::{
group_metadata::GroupMetadata as XmtpGroupMetadata,
group_mutable_metadata::MetadataField as XmtpMetadataField,
Expand Down Expand Up @@ -230,7 +229,7 @@ impl Conversation {
installation_ids: member
.installation_ids
.into_iter()
.map(|id| ed25519_public_key_to_address(id.as_slice()))
.map(hex::encode)
.collect(),
permission_level: match member.permission_level {
XmtpPermissionLevel::Member => PermissionLevel::Member,
Expand Down
11 changes: 7 additions & 4 deletions bindings_wasm/src/inbox_state.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use js_sys::Uint8Array;
use wasm_bindgen::{prelude::wasm_bindgen, JsError};
use xmtp_cryptography::signature::ed25519_public_key_to_address;
use xmtp_id::associations::{AssociationState, MemberIdentifier};

use crate::client::Client;

#[wasm_bindgen(getter_with_clone)]
#[derive(Clone)]
pub struct Installation {
pub bytes: Uint8Array,
pub id: String,
#[wasm_bindgen(js_name = clientTimestampNs)]
pub client_timestamp_ns: Option<u64>,
Expand All @@ -15,10 +16,11 @@ pub struct Installation {
#[wasm_bindgen]
impl Installation {
#[wasm_bindgen(constructor)]
pub fn new(id: String, client_timestamp_ns: Option<u64>) -> Self {
pub fn new(bytes: Uint8Array, id: String, client_timestamp_ns: Option<u64>) -> Self {
Self {
id,
bytes,
client_timestamp_ns,
id,
}
}
}
Expand Down Expand Up @@ -63,8 +65,9 @@ impl From<AssociationState> for InboxState {
.filter_map(|m| match m.identifier {
MemberIdentifier::Address(_) => None,
MemberIdentifier::Installation(inst) => Some(Installation {
id: ed25519_public_key_to_address(inst.as_slice()),
bytes: Uint8Array::from(inst.as_slice()),
client_timestamp_ns: m.client_timestamp_ns,
id: hex::encode(inst),
}),
})
.collect(),
Expand Down
9 changes: 0 additions & 9 deletions xmtp_cryptography/src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,6 @@ pub fn h160addr_to_string(bytes: H160) -> String {
s.to_lowercase()
}

// This should ONLY be used for ed25519 keys, not ethereum/secp256k1 keys.
// See: https://sourcegraph.com/github.com/gakonst/ethers-rs@40cc8cc54f7d36aa24147c937772600e5b119399/-/blob/ethers-core/src/types/signature.rs?L110-111
pub fn ed25519_public_key_to_address(bytes: &[u8]) -> String {
let hash = ethers::utils::keccak256(bytes);
let mut s = String::from("x:"); // TODO verify XMTP installation addressing scheme
s.push_str(&hex::encode(&hash[12..]));
s
}

/// Check if an string is a valid ethereum address (valid hex and length 20).
pub fn is_valid_ethereum_address<S: AsRef<str>>(address: S) -> bool {
let address = address.as_ref();
Expand Down

0 comments on commit 7f3a583

Please sign in to comment.