notifications/
linked_devices.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use hdk::prelude::*;
use serde::de::DeserializeOwned;

pub fn call_local_zome<P, R>(
	zome_name: ZomeName,
	fn_name: FunctionName,
	payload: P,
) -> ExternResult<Option<R>>
where
	P: serde::Serialize + std::fmt::Debug,
	R: DeserializeOwned + std::fmt::Debug,
{
	let call_result = call(
		CallTargetCell::Local,
		zome_name.clone(),
		fn_name.clone(),
		None,
		payload,
	);

	match call_result {
		Ok(response) => match response {
			ZomeCallResponse::Ok(result) => {
				let result: R = result.decode().map_err(|err| wasm_error!(err))?;
				Ok(Some(result))
			}
			_ => Err(wasm_error!(WasmErrorInner::Guest(format!(
				"Failed to call {zome_name}/{fn_name}: {response:?}"
			)))),
		},
		Err(err) => {
			if format!("{err:?}").contains("Zome not found") {
				return Ok(None);
			}
			return Err(err);
		}
	}
}

pub fn linked_devices_zome_name() -> Option<ZomeName> {
	match std::option_env!("LINKED_DEVICES_COORDINATOR_ZOME_NAME") {
		Some(zome_name) => Some(zome_name.into()),
		None => None,
	}
}

pub fn get_linked_devices(agent: AgentPubKey) -> ExternResult<Vec<AgentPubKey>> {
	let Some(zome_name) = linked_devices_zome_name() else {
		return Ok(vec![]);
	};
	let Some(links): Option<Vec<Link>> =
		call_local_zome(zome_name, "get_linked_devices_for_agent".into(), agent)?
	else {
		return Ok(vec![]);
	};
	let agents: Vec<AgentPubKey> = links
		.into_iter()
		.filter_map(|link| link.target.into_agent_pub_key())
		.collect();
	Ok(agents)
}

pub fn get_all_agents_for(agent: AgentPubKey) -> ExternResult<Vec<AgentPubKey>> {
	let mut agents = get_linked_devices(agent.clone())?;
	agents.push(agent);
	Ok(agents)
}

pub fn query_my_linked_devices() -> ExternResult<Vec<AgentPubKey>> {
	let Some(zome_name) = linked_devices_zome_name() else {
		return Ok(vec![]);
	};
	let Some(links): Option<Vec<Link>> =
		call_local_zome(zome_name, "query_my_linked_devices".into(), ())?
	else {
		return Ok(vec![]);
	};
	let agents: Vec<AgentPubKey> = links
		.into_iter()
		.filter_map(|link| link.target.into_agent_pub_key())
		.collect();
	Ok(agents)
}