upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-12-03 11:38:07 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2025-12-03 11:38:07 +0000
commite30dfd5e5abb96cdc89b80f1d085466e55c347e0 (patch)
treec12c1d54d30f0541c9689acbcb3b64d54cc8b996
parent2eaff5b79fed364d5eba5eb38e4b7bf76326884d (diff)
remove depricated audit mode label ci / production ~> isolated / shared
-rw-r--r--docs/learnings/grasp-audit.md46
-rw-r--r--grasp-audit/QUICK_START.md16
-rw-r--r--grasp-audit/src/audit.rs12
-rw-r--r--grasp-audit/src/bin/grasp-audit.rs12
-rw-r--r--tests/cors.rs2
-rw-r--r--tests/git_clone.rs2
-rw-r--r--tests/nip01_compliance.rs6
-rw-r--r--tests/nip11_document.rs2
-rw-r--r--tests/nip34_announcements.rs2
-rw-r--r--tests/push_authorization.rs2
-rw-r--r--tests/repository_creation.rs2
11 files changed, 60 insertions, 44 deletions
diff --git a/docs/learnings/grasp-audit.md b/docs/learnings/grasp-audit.md
index 531ebda..14e5a2b 100644
--- a/docs/learnings/grasp-audit.md
+++ b/docs/learnings/grasp-audit.md
@@ -18,6 +18,7 @@
18**Decision:** Build `grasp-audit` as a separate crate from `ngit-grasp` 18**Decision:** Build `grasp-audit` as a separate crate from `ngit-grasp`
19 19
20**Why:** 20**Why:**
21
211. **Parallel Development**: Can build tests before implementation 221. **Parallel Development**: Can build tests before implementation
222. **Isolated Testing**: Tests run in isolation (CI/CD safe) 232. **Isolated Testing**: Tests run in isolation (CI/CD safe)
233. **Production Auditing**: Can audit live production services 243. **Production Auditing**: Can audit live production services
@@ -43,6 +44,7 @@
43``` 44```
44 45
45**Benefits:** 46**Benefits:**
47
46- ✅ **Queryable**: Can find all audit events via tag filter 48- ✅ **Queryable**: Can find all audit events via tag filter
47- ✅ **Isolated**: Each test run has unique run ID 49- ✅ **Isolated**: Each test run has unique run ID
48- ✅ **Self-cleaning**: Cleanup timestamp indicates when to delete 50- ✅ **Self-cleaning**: Cleanup timestamp indicates when to delete
@@ -56,10 +58,12 @@
56### Standard "t" Tags vs Custom Tags 58### Standard "t" Tags vs Custom Tags
57 59
58**Evolution:** 60**Evolution:**
61
591. **Original**: Custom single-letter tags (`g`, `r`, `c`) 621. **Original**: Custom single-letter tags (`g`, `r`, `c`)
602. **Current**: Standard NIP-01 "t" tags with prefixed values 632. **Current**: Standard NIP-01 "t" tags with prefixed values
61 64
62**Why we changed:** 65**Why we changed:**
66
63- ❌ Custom tags could conflict with other systems 67- ❌ Custom tags could conflict with other systems
64- ✅ "t" tag is standard for categorization/topics 68- ✅ "t" tag is standard for categorization/topics
65- ✅ Multiple "t" tags are expected and supported 69- ✅ Multiple "t" tags are expected and supported
@@ -78,17 +82,18 @@
78use grasp_audit::audit::AuditConfig; 82use grasp_audit::audit::AuditConfig;
79 83
80// CI mode - isolated test runs 84// CI mode - isolated test runs
81let config = AuditConfig::ci(); 85let config = AuditConfig::isolated();
82// Generates UUID run ID: "ci-{uuid}" 86// Generates UUID run ID: "ci-{uuid}"
83// Cleanup after 1 hour 87// Cleanup after 1 hour
84 88
85// Production mode - persistent run ID 89// Production mode - persistent run ID
86let config = AuditConfig::production("prod-server-1"); 90let config = AuditConfig::shared();
87// Uses provided run ID 91// Uses provided run ID
88// Cleanup after 24 hours 92// Cleanup after 24 hours
89``` 93```
90 94
91**When to use:** 95**When to use:**
96
92- **CI mode**: Automated testing, parallel runs, temporary 97- **CI mode**: Automated testing, parallel runs, temporary
93- **Production mode**: Manual audits, monitoring, persistent 98- **Production mode**: Manual audits, monitoring, persistent
94 99
@@ -100,7 +105,7 @@ let config = AuditConfig::production("prod-server-1");
100use grasp_audit::audit::{AuditConfig, AuditEventBuilder}; 105use grasp_audit::audit::{AuditConfig, AuditEventBuilder};
101use nostr_sdk::prelude::*; 106use nostr_sdk::prelude::*;
102 107
103let config = AuditConfig::ci(); 108let config = AuditConfig::isolated();
104let keys = Keys::generate(); 109let keys = Keys::generate();
105 110
106// Create audit event 111// Create audit event
@@ -121,7 +126,7 @@ let event = AuditEventBuilder::new(&config, Kind::TextNote, "test content")
121use grasp_audit::client::AuditClient; 126use grasp_audit::client::AuditClient;
122use grasp_audit::audit::AuditConfig; 127use grasp_audit::audit::AuditConfig;
123 128
124let config = AuditConfig::ci(); 129let config = AuditConfig::isolated();
125let client = AuditClient::new(config, keys); 130let client = AuditClient::new(config, keys);
126 131
127// Connect to relay 132// Connect to relay
@@ -144,14 +149,15 @@ let events = client.query().await?;
144 149
145```rust 150```rust
146// CI mode generates unique UUID per run 151// CI mode generates unique UUID per run
147let config1 = AuditConfig::ci(); 152let config1 = AuditConfig::isolated();
148let config2 = AuditConfig::ci(); 153let config2 = AuditConfig::isolated();
149 154
150// config1.run_id != config2.run_id 155// config1.run_id != config2.run_id
151// Tests won't interfere with each other 156// Tests won't interfere with each other
152``` 157```
153 158
154**Benefits:** 159**Benefits:**
160
155- ✅ Parallel CI/CD runs don't conflict 161- ✅ Parallel CI/CD runs don't conflict
156- ✅ Can run multiple test suites simultaneously 162- ✅ Can run multiple test suites simultaneously
157- ✅ Easy to identify which run created which events 163- ✅ Easy to identify which run created which events
@@ -194,18 +200,20 @@ grasp-audit/src/specs/
194### Unit vs Integration Tests 200### Unit vs Integration Tests
195 201
196**Unit Tests** (no relay required): 202**Unit Tests** (no relay required):
203
197```rust 204```rust
198#[cfg(test)] 205#[cfg(test)]
199mod tests { 206mod tests {
200 #[test] 207 #[test]
201 fn test_audit_config() { 208 fn test_audit_config() {
202 let config = AuditConfig::ci(); 209 let config = AuditConfig::isolated();
203 assert!(config.run_id.starts_with("ci-")); 210 assert!(config.run_id.starts_with("ci-"));
204 } 211 }
205} 212}
206``` 213```
207 214
208**Integration Tests** (relay required): 215**Integration Tests** (relay required):
216
209```rust 217```rust
210#[cfg(test)] 218#[cfg(test)]
211mod tests { 219mod tests {
@@ -218,6 +226,7 @@ mod tests {
218``` 226```
219 227
220**Running tests:** 228**Running tests:**
229
221```bash 230```bash
222# Unit tests (fast, no dependencies) 231# Unit tests (fast, no dependencies)
223cargo test --lib 232cargo test --lib
@@ -248,7 +257,7 @@ for result in &results {
248// Summary 257// Summary
249let passed = results.iter().filter(|r| r.is_pass()).count(); 258let passed = results.iter().filter(|r| r.is_pass()).count();
250let total = results.len(); 259let total = results.len();
251println!("Results: {}/{} passed ({:.1}%)", 260println!("Results: {}/{} passed ({:.1}%)",
252 passed, total, (passed as f64 / total as f64) * 100.0); 261 passed, total, (passed as f64 / total as f64) * 100.0);
253``` 262```
254 263
@@ -300,6 +309,7 @@ grasp-audit audit --relay ws://localhost:7000
300**Impact:** Events created with old tags won't be found by new queries. 309**Impact:** Events created with old tags won't be found by new queries.
301 310
302**Mitigation:** 311**Mitigation:**
312
303- ✅ Accept breaking changes in alpha stage 313- ✅ Accept breaking changes in alpha stage
304- ✅ Document migration clearly 314- ✅ Document migration clearly
305- ✅ Old events auto-expire via cleanup 315- ✅ Old events auto-expire via cleanup
@@ -316,6 +326,7 @@ grasp-audit audit --relay ws://localhost:7000
316**Solution:** Built-in cleanup strategy from day one. 326**Solution:** Built-in cleanup strategy from day one.
317 327
318**Implementation:** 328**Implementation:**
329
319- Every event has cleanup timestamp 330- Every event has cleanup timestamp
320- Relay can cleanup expired events 331- Relay can cleanup expired events
321- No deletion event pollution (direct DB cleanup) 332- No deletion event pollution (direct DB cleanup)
@@ -329,9 +340,10 @@ grasp-audit audit --relay ws://localhost:7000
329**Benefit:** CI/CD can run multiple test suites simultaneously. 340**Benefit:** CI/CD can run multiple test suites simultaneously.
330 341
331**Pattern:** 342**Pattern:**
343
332```rust 344```rust
333// Each CI run gets unique ID 345// Each CI run gets unique ID
334let config = AuditConfig::ci(); 346let config = AuditConfig::isolated();
335// run_id = "ci-{uuid}" 347// run_id = "ci-{uuid}"
336 348
337// Tests isolated by run ID 349// Tests isolated by run ID
@@ -346,6 +358,7 @@ let events = client.query().await?;
346**Lesson:** Using standard NIP-01 "t" tags instead of custom tags. 358**Lesson:** Using standard NIP-01 "t" tags instead of custom tags.
347 359
348**Benefits:** 360**Benefits:**
361
349- ✅ No conflicts with other systems 362- ✅ No conflicts with other systems
350- ✅ Standard relay filtering works 363- ✅ Standard relay filtering works
351- ✅ Better interoperability 364- ✅ Better interoperability
@@ -382,11 +395,13 @@ let events = client.query().await?;
382**Symptoms:** Tests timeout or fail to connect 395**Symptoms:** Tests timeout or fail to connect
383 396
384**Causes:** 397**Causes:**
398
3851. No relay running 3991. No relay running
3862. Wrong relay URL 4002. Wrong relay URL
3873. Firewall blocking connection 4013. Firewall blocking connection
388 402
389**Solution:** 403**Solution:**
404
390```bash 405```bash
391# Start relay 406# Start relay
392docker run --rm -p 7000:7000 scsibug/nostr-rs-relay 407docker run --rm -p 7000:7000 scsibug/nostr-rs-relay
@@ -405,14 +420,16 @@ cargo test -- --ignored
405**Symptoms:** Query returns empty even though events were sent 420**Symptoms:** Query returns empty even though events were sent
406 421
407**Causes:** 422**Causes:**
423
4081. Wrong run ID (querying different run) 4241. Wrong run ID (querying different run)
4092. Connection timing (query before event propagated) 4252. Connection timing (query before event propagated)
4103. Tag mismatch (uppercase vs lowercase) 4263. Tag mismatch (uppercase vs lowercase)
411 427
412**Solution:** 428**Solution:**
429
413```rust 430```rust
414// Use same config for send and query 431// Use same config for send and query
415let config = AuditConfig::ci(); 432let config = AuditConfig::isolated();
416 433
417// Wait for event to propagate 434// Wait for event to propagate
418tokio::time::sleep(Duration::from_millis(500)).await; 435tokio::time::sleep(Duration::from_millis(500)).await;
@@ -430,6 +447,7 @@ let t_tag = SingleLetterTag::lowercase(Alphabet::T); // Lowercase!
430**Cause:** Not in Nix dev environment 447**Cause:** Not in Nix dev environment
431 448
432**Solution:** 449**Solution:**
450
433```bash 451```bash
434# Enter Nix environment first 452# Enter Nix environment first
435cd grasp-audit 453cd grasp-audit
@@ -447,10 +465,10 @@ cargo build
447 465
448```rust 466```rust
449// CI mode 467// CI mode
450let config = AuditConfig::ci(); 468let config = AuditConfig::isolated();
451 469
452// Production mode 470// Production mode
453let config = AuditConfig::production("run-id"); 471let config = AuditConfig::shared();
454``` 472```
455 473
456### Event Creation 474### Event Creation
@@ -494,5 +512,5 @@ cargo run -- audit --relay ws://localhost:7000
494 512
495--- 513---
496 514
497*Last updated: November 4, 2025* 515_Last updated: November 4, 2025_
498*Status: Living document - update as grasp-audit evolves* 516_Status: Living document - update as grasp-audit evolves_
diff --git a/grasp-audit/QUICK_START.md b/grasp-audit/QUICK_START.md
index d4ee494..cb6d8a7 100644
--- a/grasp-audit/QUICK_START.md
+++ b/grasp-audit/QUICK_START.md
@@ -108,21 +108,21 @@ use grasp_audit::*;
108#[tokio::main] 108#[tokio::main]
109async fn main() -> Result<()> { 109async fn main() -> Result<()> {
110 // Create audit client 110 // Create audit client
111 let config = AuditConfig::ci(); 111 let config = AuditConfig::isolated();
112 let client = AuditClient::new("ws://localhost:7000", config).await?; 112 let client = AuditClient::new("ws://localhost:7000", config).await?;
113 113
114 // Run smoke tests 114 // Run smoke tests
115 let results = specs::Nip01SmokeTests::run_all(&client).await; 115 let results = specs::Nip01SmokeTests::run_all(&client).await;
116 116
117 // Print results 117 // Print results
118 results.print_report(); 118 results.print_report();
119 119
120 // Check if passed 120 // Check if passed
121 if !results.all_passed() { 121 if !results.all_passed() {
122 eprintln!("Some tests failed!"); 122 eprintln!("Some tests failed!");
123 std::process::exit(1); 123 std::process::exit(1);
124 } 124 }
125 125
126 Ok(()) 126 Ok(())
127} 127}
128``` 128```
@@ -134,17 +134,20 @@ async fn main() -> Result<()> {
134**Error:** `linker 'cc' not found` 134**Error:** `linker 'cc' not found`
135 135
136**Solution (NixOS):** 136**Solution (NixOS):**
137
137```bash 138```bash
138nix develop # Use the provided flake.nix 139nix develop # Use the provided flake.nix
139``` 140```
140 141
141**Solution (Other Linux):** 142**Solution (Other Linux):**
143
142```bash 144```bash
143sudo apt-get install build-essential # Debian/Ubuntu 145sudo apt-get install build-essential # Debian/Ubuntu
144sudo yum install gcc # RedHat/CentOS 146sudo yum install gcc # RedHat/CentOS
145``` 147```
146 148
147**Solution (macOS):** 149**Solution (macOS):**
150
148```bash 151```bash
149xcode-select --install 152xcode-select --install
150``` 153```
@@ -154,6 +157,7 @@ xcode-select --install
154**Error:** `Failed to connect to relay` 157**Error:** `Failed to connect to relay`
155 158
156**Solutions:** 159**Solutions:**
160
1571. Make sure a relay is running at the specified URL 1611. Make sure a relay is running at the specified URL
1582. Check firewall settings 1622. Check firewall settings
1593. Try a different relay URL 1633. Try a different relay URL
@@ -164,6 +168,7 @@ xcode-select --install
164**Error:** Tests fail with timeout 168**Error:** Tests fail with timeout
165 169
166**Solutions:** 170**Solutions:**
171
1671. Increase timeout in test code 1721. Increase timeout in test code
1682. Check relay is responding (try with `websocat`) 1732. Check relay is responding (try with `websocat`)
1693. Check network connectivity 1743. Check network connectivity
@@ -216,6 +221,7 @@ xcode-select --install
216## Support 221## Support
217 222
218For issues or questions: 223For issues or questions:
224
2191. Check the documentation in this directory 2251. Check the documentation in this directory
2202. Review the examples 2262. Review the examples
2213. Check the test code for usage patterns 2273. Check the test code for usage patterns
diff --git a/grasp-audit/src/audit.rs b/grasp-audit/src/audit.rs
index 713c948..0a4df42 100644
--- a/grasp-audit/src/audit.rs
+++ b/grasp-audit/src/audit.rs
@@ -68,18 +68,6 @@ impl AuditConfig {
68 } 68 }
69 } 69 }
70 70
71 /// Alias for isolated() - for backwards compatibility
72 #[deprecated(since = "0.2.0", note = "Use isolated() instead")]
73 pub fn ci() -> Self {
74 Self::isolated()
75 }
76
77 /// Alias for shared() - for backwards compatibility
78 #[deprecated(since = "0.2.0", note = "Use shared() instead")]
79 pub fn production() -> Self {
80 Self::shared()
81 }
82
83 /// Create config with custom run ID 71 /// Create config with custom run ID
84 pub fn with_run_id(run_id: String, mode: AuditMode) -> Self { 72 pub fn with_run_id(run_id: String, mode: AuditMode) -> Self {
85 Self { 73 Self {
diff --git a/grasp-audit/src/bin/grasp-audit.rs b/grasp-audit/src/bin/grasp-audit.rs
index 0d88bce..08a92c7 100644
--- a/grasp-audit/src/bin/grasp-audit.rs
+++ b/grasp-audit/src/bin/grasp-audit.rs
@@ -56,14 +56,18 @@ async fn main() -> Result<()> {
56 spec, 56 spec,
57 git_data_dir, 57 git_data_dir,
58 } => { 58 } => {
59 #[allow(deprecated)]
60 let mut config = match mode.as_str() { 59 let mut config = match mode.as_str() {
61 "shared" => AuditConfig::shared(), 60 "shared" => AuditConfig::shared(),
62 "isolated" => AuditConfig::isolated(), 61 "isolated" => AuditConfig::isolated(),
63 // Backwards compatibility aliases 62 // Backwards compatibility aliases
64 "ci" => AuditConfig::ci(), 63 "ci" => AuditConfig::isolated(),
65 "production" => AuditConfig::production(), 64 "production" => AuditConfig::shared(),
66 _ => return Err(anyhow!("Invalid mode: {}. Use 'shared' or 'isolated'", mode)), 65 _ => {
66 return Err(anyhow!(
67 "Invalid mode: {}. Use 'shared' or 'isolated'",
68 mode
69 ))
70 }
67 }; 71 };
68 72
69 // Audit needs to create events to test the relay, so disable read-only mode 73 // Audit needs to create events to test the relay, so disable read-only mode
diff --git a/tests/cors.rs b/tests/cors.rs
index b5a0a87..a4e92bc 100644
--- a/tests/cors.rs
+++ b/tests/cors.rs
@@ -36,7 +36,7 @@ macro_rules! isolated_cors_test {
36 #[tokio::test] 36 #[tokio::test]
37 async fn $test_name() { 37 async fn $test_name() {
38 let relay = TestRelay::start().await; 38 let relay = TestRelay::start().await;
39 let config = AuditConfig::ci(); 39 let config = AuditConfig::isolated();
40 let client = AuditClient::new(relay.url(), config) 40 let client = AuditClient::new(relay.url(), config)
41 .await 41 .await
42 .expect("Failed to create audit client"); 42 .expect("Failed to create audit client");
diff --git a/tests/git_clone.rs b/tests/git_clone.rs
index c8a91a2..a6d810b 100644
--- a/tests/git_clone.rs
+++ b/tests/git_clone.rs
@@ -37,7 +37,7 @@ macro_rules! isolated_test {
37 #[tokio::test] 37 #[tokio::test]
38 async fn $test_name() { 38 async fn $test_name() {
39 let relay = TestRelay::start().await; 39 let relay = TestRelay::start().await;
40 let config = AuditConfig::ci(); 40 let config = AuditConfig::isolated();
41 let client = AuditClient::new(relay.url(), config) 41 let client = AuditClient::new(relay.url(), config)
42 .await 42 .await
43 .expect("Failed to create audit client"); 43 .expect("Failed to create audit client");
diff --git a/tests/nip01_compliance.rs b/tests/nip01_compliance.rs
index 6fb721a..045bddb 100644
--- a/tests/nip01_compliance.rs
+++ b/tests/nip01_compliance.rs
@@ -36,7 +36,7 @@ macro_rules! isolated_test {
36 #[tokio::test] 36 #[tokio::test]
37 async fn $test_name() { 37 async fn $test_name() {
38 let relay = TestRelay::start().await; 38 let relay = TestRelay::start().await;
39 let config = AuditConfig::ci(); 39 let config = AuditConfig::isolated();
40 let client = AuditClient::new(relay.url(), config) 40 let client = AuditClient::new(relay.url(), config)
41 .await 41 .await
42 .expect("Failed to create audit client"); 42 .expect("Failed to create audit client");
@@ -73,7 +73,7 @@ async fn test_relay_lifecycle() {
73 let url = relay.url().to_string(); 73 let url = relay.url().to_string();
74 74
75 // Verify we can connect 75 // Verify we can connect
76 let config = AuditConfig::ci(); 76 let config = AuditConfig::isolated();
77 let client = AuditClient::new(&url, config) 77 let client = AuditClient::new(&url, config)
78 .await 78 .await
79 .expect("Failed to connect to relay"); 79 .expect("Failed to connect to relay");
@@ -101,7 +101,7 @@ async fn test_parallel_relays() {
101 ); 101 );
102 102
103 // Both should be connectable 103 // Both should be connectable
104 let config = AuditConfig::ci(); 104 let config = AuditConfig::isolated();
105 105
106 let client1 = AuditClient::new(relay1.url(), config.clone()) 106 let client1 = AuditClient::new(relay1.url(), config.clone())
107 .await 107 .await
diff --git a/tests/nip11_document.rs b/tests/nip11_document.rs
index 2104ad0..147bb26 100644
--- a/tests/nip11_document.rs
+++ b/tests/nip11_document.rs
@@ -36,7 +36,7 @@ macro_rules! isolated_test {
36 #[tokio::test] 36 #[tokio::test]
37 async fn $test_name() { 37 async fn $test_name() {
38 let relay = TestRelay::start().await; 38 let relay = TestRelay::start().await;
39 let config = AuditConfig::ci(); 39 let config = AuditConfig::isolated();
40 let client = AuditClient::new(relay.url(), config) 40 let client = AuditClient::new(relay.url(), config)
41 .await 41 .await
42 .expect("Failed to create audit client"); 42 .expect("Failed to create audit client");
diff --git a/tests/nip34_announcements.rs b/tests/nip34_announcements.rs
index 2a83886..aa623d3 100644
--- a/tests/nip34_announcements.rs
+++ b/tests/nip34_announcements.rs
@@ -36,7 +36,7 @@ macro_rules! isolated_test {
36 #[tokio::test] 36 #[tokio::test]
37 async fn $test_name() { 37 async fn $test_name() {
38 let relay = TestRelay::start().await; 38 let relay = TestRelay::start().await;
39 let config = AuditConfig::ci(); 39 let config = AuditConfig::isolated();
40 let client = AuditClient::new(relay.url(), config) 40 let client = AuditClient::new(relay.url(), config)
41 .await 41 .await
42 .expect("Failed to create audit client"); 42 .expect("Failed to create audit client");
diff --git a/tests/push_authorization.rs b/tests/push_authorization.rs
index b9e0545..df291d5 100644
--- a/tests/push_authorization.rs
+++ b/tests/push_authorization.rs
@@ -38,7 +38,7 @@ macro_rules! isolated_push_test {
38 #[tokio::test] 38 #[tokio::test]
39 async fn $test_name() { 39 async fn $test_name() {
40 let relay = TestRelay::start().await; 40 let relay = TestRelay::start().await;
41 let config = AuditConfig::ci(); 41 let config = AuditConfig::isolated();
42 let client = AuditClient::new(relay.url(), config) 42 let client = AuditClient::new(relay.url(), config)
43 .await 43 .await
44 .expect("Failed to create audit client"); 44 .expect("Failed to create audit client");
diff --git a/tests/repository_creation.rs b/tests/repository_creation.rs
index 352e2cc..a1cca11 100644
--- a/tests/repository_creation.rs
+++ b/tests/repository_creation.rs
@@ -38,7 +38,7 @@ macro_rules! isolated_test {
38 #[tokio::test] 38 #[tokio::test]
39 async fn $test_name() { 39 async fn $test_name() {
40 let relay = TestRelay::start().await; 40 let relay = TestRelay::start().await;
41 let config = AuditConfig::ci(); 41 let config = AuditConfig::isolated();
42 let client = AuditClient::new(relay.url(), config) 42 let client = AuditClient::new(relay.url(), config)
43 .await 43 .await
44 .expect("Failed to create audit client"); 44 .expect("Failed to create audit client");