1mod util;
8mod wasm_agent;
9
10use js_sys::{Array, Object, Reflect};
11use std::collections::HashMap;
12use std::fmt;
13use tap_agent::did::KeyType as TapKeyType;
14use wasm_bindgen::prelude::*;
15use web_sys::console;
16
17pub use wasm_agent::WasmTapAgent;
18
19#[wasm_bindgen(start)]
21pub fn start() -> Result<(), JsValue> {
22 #[cfg(feature = "console_error_panic_hook")]
23 console_error_panic_hook::set_once();
24 Ok(())
25}
26
27#[derive(Debug, Clone, Copy, PartialEq)]
29#[wasm_bindgen]
30pub enum MessageType {
31 Transfer,
33 Payment,
35 Presentation,
37 Authorize,
39 Reject,
41 Settle,
43 Cancel,
45 Revert,
47 AddAgents,
49 ReplaceAgent,
51 RemoveAgent,
53 UpdatePolicies,
55 UpdateParty,
57 ConfirmRelationship,
59 Connect,
61 AuthorizationRequired,
63 Complete,
65 Error,
67 Unknown,
69}
70
71impl fmt::Display for MessageType {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 match self {
74 MessageType::Transfer => write!(f, "https://tap.rsvp/schema/1.0#Transfer"),
75 MessageType::Payment => write!(f, "https://tap.rsvp/schema/1.0#Payment"),
76 MessageType::Presentation => write!(f, "https://tap.rsvp/schema/1.0#Presentation"),
77 MessageType::Authorize => write!(f, "https://tap.rsvp/schema/1.0#Authorize"),
78 MessageType::Reject => write!(f, "https://tap.rsvp/schema/1.0#Reject"),
79 MessageType::Settle => write!(f, "https://tap.rsvp/schema/1.0#Settle"),
80 MessageType::Cancel => write!(f, "https://tap.rsvp/schema/1.0#Cancel"),
81 MessageType::Revert => write!(f, "https://tap.rsvp/schema/1.0#Revert"),
82 MessageType::AddAgents => write!(f, "https://tap.rsvp/schema/1.0#AddAgents"),
83 MessageType::ReplaceAgent => write!(f, "https://tap.rsvp/schema/1.0#ReplaceAgent"),
84 MessageType::RemoveAgent => write!(f, "https://tap.rsvp/schema/1.0#RemoveAgent"),
85 MessageType::UpdatePolicies => write!(f, "https://tap.rsvp/schema/1.0#UpdatePolicies"),
86 MessageType::UpdateParty => write!(f, "https://tap.rsvp/schema/1.0#UpdateParty"),
87 MessageType::ConfirmRelationship => {
88 write!(f, "https://tap.rsvp/schema/1.0#ConfirmRelationship")
89 }
90 MessageType::Connect => write!(f, "https://tap.rsvp/schema/1.0#Connect"),
91 MessageType::AuthorizationRequired => {
92 write!(f, "https://tap.rsvp/schema/1.0#AuthorizationRequired")
93 }
94 MessageType::Complete => write!(f, "https://tap.rsvp/schema/1.0#Complete"),
95 MessageType::Error => write!(f, "https://tap.rsvp/schema/1.0#Error"),
96 MessageType::Unknown => write!(f, "UNKNOWN"),
97 }
98 }
99}
100
101impl From<&str> for MessageType {
102 fn from(s: &str) -> Self {
103 match s {
104 "https://tap.rsvp/schema/1.0#Transfer" => MessageType::Transfer,
105 "https://tap.rsvp/schema/1.0#Payment" => MessageType::Payment,
106 "https://tap.rsvp/schema/1.0#Presentation" => MessageType::Presentation,
107 "https://tap.rsvp/schema/1.0#Authorize" => MessageType::Authorize,
108 "https://tap.rsvp/schema/1.0#Reject" => MessageType::Reject,
109 "https://tap.rsvp/schema/1.0#Settle" => MessageType::Settle,
110 "https://tap.rsvp/schema/1.0#Cancel" => MessageType::Cancel,
111 "https://tap.rsvp/schema/1.0#Revert" => MessageType::Revert,
112 "https://tap.rsvp/schema/1.0#AddAgents" => MessageType::AddAgents,
113 "https://tap.rsvp/schema/1.0#ReplaceAgent" => MessageType::ReplaceAgent,
114 "https://tap.rsvp/schema/1.0#RemoveAgent" => MessageType::RemoveAgent,
115 "https://tap.rsvp/schema/1.0#UpdatePolicies" => MessageType::UpdatePolicies,
116 "https://tap.rsvp/schema/1.0#UpdateParty" => MessageType::UpdateParty,
117 "https://tap.rsvp/schema/1.0#ConfirmRelationship" => MessageType::ConfirmRelationship,
118 "https://tap.rsvp/schema/1.0#Connect" => MessageType::Connect,
119 "https://tap.rsvp/schema/1.0#AuthorizationRequired" => {
120 MessageType::AuthorizationRequired
121 }
122 "https://tap.rsvp/schema/1.0#Complete" => MessageType::Complete,
123 "https://tap.rsvp/schema/1.0#Error" => MessageType::Error,
124 _ => MessageType::Unknown,
125 }
126 }
127}
128
129#[wasm_bindgen]
131pub enum WasmKeyType {
132 Ed25519,
134 P256,
136 Secp256k1,
138}
139
140impl From<WasmKeyType> for TapKeyType {
141 fn from(key_type: WasmKeyType) -> Self {
142 match key_type {
143 WasmKeyType::Ed25519 => TapKeyType::Ed25519,
144 WasmKeyType::P256 => TapKeyType::P256,
145 WasmKeyType::Secp256k1 => TapKeyType::Secp256k1,
146 }
147 }
148}
149
150#[wasm_bindgen]
152#[derive(Clone)]
153pub struct TapNode {
154 agents: HashMap<String, WasmTapAgent>,
155 debug: bool,
156}
157
158#[wasm_bindgen]
159impl TapNode {
160 #[wasm_bindgen(constructor)]
162 pub fn new(config: JsValue) -> Self {
163 console_error_panic_hook::set_once();
164
165 let debug = if let Ok(debug_prop) = Reflect::get(&config, &JsValue::from_str("debug")) {
166 debug_prop.is_truthy()
167 } else {
168 false
169 };
170
171 TapNode {
172 agents: HashMap::new(),
173 debug,
174 }
175 }
176
177 pub fn add_agent(&mut self, agent: WasmTapAgent) -> Result<(), JsValue> {
179 let did = agent.get_did();
180 self.agents.insert(did.clone(), agent);
181
182 if self.debug {
183 console::log_1(&JsValue::from_str(&format!("Added agent {} to node", did)));
184 }
185
186 Ok(())
187 }
188
189 pub fn get_agent(&self, did: &str) -> Option<WasmTapAgent> {
191 self.agents.get(did).cloned()
192 }
193
194 pub fn list_agents(&self) -> JsValue {
196 let result = Array::new();
197
198 for (did, agent) in &self.agents {
199 let agent_obj = Object::new();
200 Reflect::set(
201 &agent_obj,
202 &JsValue::from_str("did"),
203 &JsValue::from_str(did),
204 )
205 .unwrap();
206
207 if let Some(nickname) = agent.nickname() {
208 Reflect::set(
209 &agent_obj,
210 &JsValue::from_str("nickname"),
211 &JsValue::from_str(&nickname),
212 )
213 .unwrap();
214 }
215
216 result.push(&agent_obj);
217 }
218
219 result.into()
220 }
221
222 pub fn remove_agent(&mut self, did: &str) -> bool {
224 let removed = self.agents.remove(did).is_some();
225
226 if removed && self.debug {
227 console::log_1(&JsValue::from_str(&format!(
228 "Removed agent {} from node",
229 did
230 )));
231 }
232
233 removed
234 }
235}
236
237#[wasm_bindgen]
239pub fn generate_uuid_v4() -> String {
240 uuid::Uuid::new_v4().to_string()
241}