mirror of
https://github.com/aljazceru/pubky-core.git
synced 2026-01-17 21:24:19 +01:00
Feat(client): getHomeserver (#86)
* added method * added wasm rust analyzer section * getHomeserver wasm * updated readme * getHomeserver js test * correct js typing * fixed js getHomeserver call * fmt and clippy * Update pubky/README.md Co-authored-by: SHAcollision <127778313+SHAcollision@users.noreply.github.com> * moved get_homeserver from internal to auth * reuse extract_host_from_packet * removed unused imports * removed version from testnet * fixed tests --------- Co-authored-by: SHAcollision <127778313+SHAcollision@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
5393b4575a
commit
3e761720de
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2174,6 +2174,7 @@ dependencies = [
|
||||
"getrandom 0.3.1",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mainline",
|
||||
"pkarr",
|
||||
"pubky-common",
|
||||
"pubky-testnet",
|
||||
|
||||
@@ -15,12 +15,13 @@ anyhow = "1.0.95"
|
||||
http-relay = "0.2.0"
|
||||
mainline = "5.2.0"
|
||||
pkarr-relay = "0.5.7"
|
||||
pubky = { version = "0.4.1", path = "../pubky" }
|
||||
pubky-common = { version = "0.3.1", path = "../pubky-common" }
|
||||
pubky-homeserver = { version = "0.1.1", path = "../pubky-homeserver" }
|
||||
tokio = { version = "1.43.0", features = ["full"] }
|
||||
tracing-subscriber = "0.3.19"
|
||||
url = "2.5.4"
|
||||
|
||||
pubky = { path = "../pubky" }
|
||||
pubky-common = { path = "../pubky-common" }
|
||||
pubky-homeserver = { path = "../pubky-homeserver" }
|
||||
|
||||
[dev-dependencies]
|
||||
tracing-subscriber = "0.3.19"
|
||||
|
||||
@@ -59,6 +59,7 @@ futures-lite = "2.6.0"
|
||||
pubky-testnet = { path = "../pubky-testnet" }
|
||||
tokio = "1.43.0"
|
||||
tracing-subscriber = "0.3.19"
|
||||
mainline = "5.3.1"
|
||||
|
||||
[build-dependencies]
|
||||
cfg_aliases = "0.2.1"
|
||||
|
||||
@@ -53,3 +53,27 @@ async fn main () {
|
||||
## Example code
|
||||
|
||||
Check more [examples](https://github.com/pubky/pubky-core/tree/main/examples) for using the Pubky client.
|
||||
|
||||
## Wasm Rust Analyzer
|
||||
|
||||
In vscode with the rust-analyzer, wasm behind the `#[cfg(wasm_browser)]` guard is not type checked. To fix this, add
|
||||
a `.vscode/settings.json` file in the root of this project with the following content:
|
||||
|
||||
```json
|
||||
{
|
||||
"rust-analyzer.cargo.target": "wasm32-unknown-unknown"
|
||||
}
|
||||
```
|
||||
|
||||
If not done already, you need to add the wasm target: `cargo target add wasm32-unknown-unknown`.
|
||||
|
||||
This is just a workaround because it enables the wasm feature in all workspace member which creates problems.
|
||||
So it is best to enable this settings only temporarily for wasm development and then turn it off again before commiting the
|
||||
changes. This is a [rust-analyzer issue](https://github.com/rust-lang/rust-analyzer/issues/11900#issuecomment-1166638234).
|
||||
|
||||
## How To Build/Test the NPM Package
|
||||
|
||||
1. Go to `pubky/pkg`.
|
||||
2. Run `npm run build`.
|
||||
3. Run a testnet mainline DHT, Pkarr relay and Homeserver `npm run testnet`
|
||||
4. Run tests with `npm run test`.
|
||||
@@ -103,3 +103,36 @@ test("Auth: 3rd party signin", async (t) => {
|
||||
let session = await client.session(authedPubky);
|
||||
t.deepEqual(session.capabilities(), capabilities.split(','))
|
||||
})
|
||||
|
||||
|
||||
test('getHomeserver not found', async (t) => {
|
||||
const client = Client.testnet();
|
||||
|
||||
const keypair = Keypair.random()
|
||||
const publicKey = keypair.publicKey()
|
||||
|
||||
try {
|
||||
let homeserver = await client.getHomeserver(publicKey);
|
||||
t.fail("getHomeserver should NOT be found.");
|
||||
} catch (e) {
|
||||
t.pass("getHomeserver should NOT be found.");
|
||||
}
|
||||
})
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
test('getHomeserver success', async (t) => {
|
||||
const client = Client.testnet();
|
||||
|
||||
const keypair = Keypair.random()
|
||||
const publicKey = keypair.publicKey()
|
||||
|
||||
const signupToken = await createSignupToken(client)
|
||||
|
||||
await client.signup(keypair, HOMESERVER_PUBLICKEY, signupToken);
|
||||
|
||||
let homeserver = await client.getHomeserver(publicKey);
|
||||
t.is(homeserver.z32(), HOMESERVER_PUBLICKEY.z32(), "homeserver is correct");
|
||||
})
|
||||
@@ -346,6 +346,13 @@ impl Client {
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Get the homeserver for a given Pubky public key.
|
||||
/// Looks up the pkarr packet for the given public key and returns the content of the first `_pubky` SVCB record.
|
||||
pub async fn get_homeserver(&self, pubky: &PublicKey) -> Option<String> {
|
||||
let packet = self.pkarr.resolve_most_recent(pubky).await?;
|
||||
Self::extract_host_from_packet(&packet)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -379,6 +386,8 @@ mod tests {
|
||||
use reqwest::StatusCode;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::{native::internal::pkarr::PublishStrategy, Client};
|
||||
|
||||
#[tokio::test]
|
||||
async fn basic_authn() {
|
||||
let testnet = Testnet::run().await.unwrap();
|
||||
@@ -822,4 +831,27 @@ mod tests {
|
||||
"Record was not republished after threshold exceeded"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_homeserver() {
|
||||
let dht = mainline::Testnet::new(3).unwrap();
|
||||
let client = Client::builder()
|
||||
.pkarr(|builder| builder.bootstrap(&dht.bootstrap))
|
||||
.build()
|
||||
.unwrap();
|
||||
let keypair = Keypair::random();
|
||||
let pubky = keypair.public_key();
|
||||
|
||||
let homeserver_key = Keypair::random().public_key().to_z32();
|
||||
client
|
||||
.publish_homeserver(
|
||||
&keypair,
|
||||
Some(homeserver_key.as_str()),
|
||||
PublishStrategy::Force,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let homeserver = client.get_homeserver(&pubky).await;
|
||||
assert_eq!(homeserver, Some(homeserver_key));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ impl Client {
|
||||
|
||||
/// Helper to extract the current homeserver host from a signed PKarr packet.
|
||||
/// Iterates over the records with name "_pubky" and returns the first SVCB target found.
|
||||
fn extract_host_from_packet(packet: &SignedPacket) -> Option<String> {
|
||||
pub(crate) fn extract_host_from_packet(packet: &SignedPacket) -> Option<String> {
|
||||
packet
|
||||
.resource_records("_pubky")
|
||||
.find_map(|rr| match &rr.rdata {
|
||||
|
||||
@@ -106,6 +106,20 @@ impl Client {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the homeserver id for a given Pubky public key.
|
||||
/// Looks up the pkarr packet for the given public key and returns the content of the first `_pubky` SVCB record.
|
||||
/// Throws an error if no homeserver is found.
|
||||
#[wasm_bindgen(js_name = "getHomeserver")]
|
||||
pub async fn get_homeserver(&self, public_key: &PublicKey) -> Result<PublicKey, JsValue> {
|
||||
let val = self.0.get_homeserver(public_key.as_inner()).await;
|
||||
if val.is_none() {
|
||||
return Err(JsValue::from_str("No homeserver found"));
|
||||
}
|
||||
let val = val.unwrap();
|
||||
let js_val = JsValue::from_str(val.as_str());
|
||||
PublicKey::try_from(js_val)
|
||||
}
|
||||
|
||||
/// Republish the user's PKarr record pointing to their homeserver.
|
||||
///
|
||||
/// This method will republish the record if no record exists or if the existing record
|
||||
|
||||
Reference in New Issue
Block a user