tangled
alpha
login
or
join now
baileytownsend.dev
/
at-advent
forked from
oppi.li/at-advent
1
fork
atom
this repo has no description
1
fork
atom
overview
issues
pulls
pipelines
a car builder that maybe even works!?
bad-example.com
4 weeks ago
8bcf3fee
4ddc5dda
+194
-6
6 changed files
expand all
collapse all
unified
split
.gitignore
Cargo.lock
Cargo.toml
shared
Cargo.toml
src
advent
challenges
day_three
mod.rs
repo.rs
+2
-1
.gitignore
reviewed
···
7
7
at-advent.db-wal
8
8
/web/node_modules
9
9
.DS_Store
10
10
-
node_modules
10
10
+
node_modules
11
11
+
/local
+105
-4
Cargo.lock
reviewed
···
114
114
]
115
115
116
116
[[package]]
117
117
+
name = "async-stream"
118
118
+
version = "0.3.6"
119
119
+
source = "registry+https://github.com/rust-lang/crates.io-index"
120
120
+
checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
121
121
+
dependencies = [
122
122
+
"async-stream-impl",
123
123
+
"futures-core",
124
124
+
"pin-project-lite",
125
125
+
]
126
126
+
127
127
+
[[package]]
128
128
+
name = "async-stream-impl"
129
129
+
version = "0.3.6"
130
130
+
source = "registry+https://github.com/rust-lang/crates.io-index"
131
131
+
checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
132
132
+
dependencies = [
133
133
+
"proc-macro2",
134
134
+
"quote",
135
135
+
"syn",
136
136
+
]
137
137
+
138
138
+
[[package]]
117
139
name = "async-trait"
118
140
version = "0.1.88"
119
141
source = "registry+https://github.com/rust-lang/crates.io-index"
···
170
192
]
171
193
172
194
[[package]]
195
195
+
name = "atrium-crypto"
196
196
+
version = "0.1.3"
197
197
+
source = "registry+https://github.com/rust-lang/crates.io-index"
198
198
+
checksum = "03dd32c12479c334544ff2a0066d591530e9738edafead49a92e137f0d360267"
199
199
+
dependencies = [
200
200
+
"ecdsa",
201
201
+
"generic-array",
202
202
+
"k256",
203
203
+
"multibase",
204
204
+
"p256",
205
205
+
"thiserror 1.0.69",
206
206
+
]
207
207
+
208
208
+
[[package]]
173
209
name = "atrium-identity"
174
210
version = "0.1.8"
175
211
source = "registry+https://github.com/rust-lang/crates.io-index"
···
215
251
]
216
252
217
253
[[package]]
254
254
+
name = "atrium-repo"
255
255
+
version = "0.1.7"
256
256
+
source = "registry+https://github.com/rust-lang/crates.io-index"
257
257
+
checksum = "02714b0216d58f67f2980894c2a8febb589e8f55088ad9c0ac6a1a0fc28cf068"
258
258
+
dependencies = [
259
259
+
"async-stream",
260
260
+
"atrium-api",
261
261
+
"futures",
262
262
+
"ipld-core",
263
263
+
"serde",
264
264
+
"serde_bytes",
265
265
+
"serde_ipld_dagcbor",
266
266
+
"sha2",
267
267
+
"thiserror 1.0.69",
268
268
+
"tokio",
269
269
+
"tokio-util",
270
270
+
"unsigned-varint",
271
271
+
]
272
272
+
273
273
+
[[package]]
218
274
name = "atrium-xrpc"
219
275
version = "0.12.4"
220
276
source = "registry+https://github.com/rust-lang/crates.io-index"
···
448
504
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
449
505
450
506
[[package]]
507
507
+
name = "cbor4ii"
508
508
+
version = "0.2.14"
509
509
+
source = "registry+https://github.com/rust-lang/crates.io-index"
510
510
+
checksum = "b544cf8c89359205f4f990d0e6f3828db42df85b5dac95d09157a250eb0749c4"
511
511
+
dependencies = [
512
512
+
"serde",
513
513
+
]
514
514
+
515
515
+
[[package]]
451
516
name = "cc"
452
517
version = "1.2.30"
453
518
source = "registry+https://github.com/rust-lang/crates.io-index"
···
817
882
"elliptic-curve",
818
883
"rfc6979",
819
884
"signature",
885
885
+
"spki",
820
886
]
821
887
822
888
[[package]]
···
840
906
"ff",
841
907
"generic-array",
842
908
"group",
909
909
+
"pkcs8",
843
910
"rand_core 0.6.4",
844
911
"sec1",
845
912
"subtle",
···
1066
1133
source = "registry+https://github.com/rust-lang/crates.io-index"
1067
1134
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
1068
1135
dependencies = [
1136
1136
+
"futures-channel",
1069
1137
"futures-core",
1070
1138
"futures-io",
1071
1139
"futures-macro",
···
1668
1736
]
1669
1737
1670
1738
[[package]]
1739
1739
+
name = "k256"
1740
1740
+
version = "0.13.4"
1741
1741
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1742
1742
+
checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b"
1743
1743
+
dependencies = [
1744
1744
+
"cfg-if",
1745
1745
+
"ecdsa",
1746
1746
+
"elliptic-curve",
1747
1747
+
"sha2",
1748
1748
+
]
1749
1749
+
1750
1750
+
[[package]]
1671
1751
name = "langtag"
1672
1752
version = "0.3.4"
1673
1753
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2293
2373
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
2294
2374
dependencies = [
2295
2375
"rand_chacha 0.9.0",
2296
2296
-
"rand_core 0.9.3",
2376
2376
+
"rand_core 0.9.5",
2297
2377
]
2298
2378
2299
2379
[[package]]
···
2313
2393
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
2314
2394
dependencies = [
2315
2395
"ppv-lite86",
2316
2316
-
"rand_core 0.9.3",
2396
2396
+
"rand_core 0.9.5",
2317
2397
]
2318
2398
2319
2399
[[package]]
···
2327
2407
2328
2408
[[package]]
2329
2409
name = "rand_core"
2330
2330
-
version = "0.9.3"
2410
2410
+
version = "0.9.5"
2331
2411
source = "registry+https://github.com/rust-lang/crates.io-index"
2332
2332
-
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
2412
2412
+
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
2333
2413
dependencies = [
2334
2414
"getrandom 0.3.3",
2335
2415
]
···
2613
2693
"base16ct",
2614
2694
"der",
2615
2695
"generic-array",
2696
2696
+
"pkcs8",
2616
2697
"subtle",
2617
2698
"zeroize",
2618
2699
]
···
2689
2770
]
2690
2771
2691
2772
[[package]]
2773
2773
+
name = "serde_ipld_dagcbor"
2774
2774
+
version = "0.6.4"
2775
2775
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2776
2776
+
checksum = "46182f4f08349a02b45c998ba3215d3f9de826246ba02bb9dddfe9a2a2100778"
2777
2777
+
dependencies = [
2778
2778
+
"cbor4ii",
2779
2779
+
"ipld-core",
2780
2780
+
"scopeguard",
2781
2781
+
"serde",
2782
2782
+
]
2783
2783
+
2784
2784
+
[[package]]
2692
2785
name = "serde_json"
2693
2786
version = "1.0.141"
2694
2787
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2766
2859
"async-trait",
2767
2860
"atrium-api",
2768
2861
"atrium-common",
2862
2862
+
"atrium-crypto",
2769
2863
"atrium-identity",
2770
2864
"atrium-oauth",
2865
2865
+
"atrium-repo",
2771
2866
"atrium-xrpc-client",
2772
2867
"axum",
2773
2868
"bb8",
···
2782
2877
"serde_json",
2783
2878
"sqlx",
2784
2879
"thiserror 1.0.69",
2880
2880
+
"tokio",
2785
2881
]
2786
2882
2787
2883
[[package]]
···
3299
3395
dependencies = [
3300
3396
"bytes",
3301
3397
"futures-core",
3398
3398
+
"futures-io",
3302
3399
"futures-sink",
3303
3400
"pin-project-lite",
3304
3401
"tokio",
···
3553
3650
version = "0.8.0"
3554
3651
source = "registry+https://github.com/rust-lang/crates.io-index"
3555
3652
checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06"
3653
3653
+
dependencies = [
3654
3654
+
"futures-io",
3655
3655
+
"futures-util",
3656
3656
+
]
3556
3657
3557
3658
[[package]]
3558
3659
name = "url"
+3
-1
Cargo.toml
reviewed
···
6
6
[workspace.dependencies]
7
7
axum = "0.8.4"
8
8
atrium-common = "0.1.3"
9
9
+
atrium-crypto = "0.1.3"
9
10
atrium-api = "0.25.7"
10
11
atrium-identity = "0.1.8"
11
12
atrium-xrpc-client = "0.5.15"
12
13
atrium-oauth = "0.1.6"
14
14
+
atrium-repo = "0.1.7"
13
15
chrono = { version = "0.4", features = ["serde", "now"] }
14
16
hickory-resolver = "0.24.1"
15
17
dotenv = "0.15.0"
···
25
27
redis = "0.32.4"
26
28
tokio = { version = "1.46.1", features = ["full"] }
27
29
markdown = "1.0.0"
28
28
-
rust-embed = { version = "8.7.2", features = ["include-exclude"] }
30
30
+
rust-embed = { version = "8.7.2", features = ["include-exclude"] }
+3
shared/Cargo.toml
reviewed
···
6
6
[dependencies]
7
7
axum.workspace = true
8
8
atrium-common.workspace = true
9
9
+
atrium-crypto.workspace = true
9
10
atrium-api.workspace = true
10
11
atrium-identity.workspace = true
11
12
atrium-oauth.workspace = true
13
13
+
atrium-repo.workspace = true
12
14
bb8.workspace = true
13
15
bb8-redis.workspace = true
14
16
hickory-resolver.workspace = true
···
23
25
handlebars = { version = "6.3.2" }
24
26
async-trait = "0.1.88"
25
27
atrium-xrpc-client.workspace = true
28
28
+
tokio.workspace = true
+4
shared/src/advent/challenges/day_three.rs
shared/src/advent/challenges/day_three/mod.rs
reviewed
···
1
1
+
pub mod repo;
2
2
+
3
3
+
pub use repo::manufacture_car;
4
4
+
1
5
use crate::OAuthAgentType;
2
6
use crate::advent::day::Day;
3
7
use crate::advent::{AdventChallenge, AdventError, ChallengeCheckResponse};
+77
shared/src/advent/challenges/day_three/repo.rs
reviewed
···
1
1
+
use std::io::Cursor;
2
2
+
3
3
+
use atrium_api::types::string::Did;
4
4
+
use atrium_crypto::keypair::P256Keypair;
5
5
+
use atrium_repo::{Repository, blockstore::{CarStore, MemoryBlockStore}};
6
6
+
use serde::Serialize;
7
7
+
8
8
+
/// secret record type
9
9
+
#[derive(Debug, Serialize)]
10
10
+
#[serde(rename_all = "camelCase")]
11
11
+
pub struct ChallengeRecord {
12
12
+
pub created_at: String,
13
13
+
pub verification_code: String,
14
14
+
pub message: String,
15
15
+
}
16
16
+
17
17
+
/// make a single-record atproto car
18
18
+
///
19
19
+
/// returns CAR bytes
20
20
+
pub async fn manufacture_car(
21
21
+
did: Did,
22
22
+
collection: &str,
23
23
+
rkey: &str,
24
24
+
record: ChallengeRecord,
25
25
+
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
26
26
+
27
27
+
// throwaway (fake key hello)
28
28
+
let keypair = P256Keypair::import(&[1u8; 32])?;
29
29
+
30
30
+
let mut mem = MemoryBlockStore::new();
31
31
+
let builder = Repository::create(&mut mem, did).await?;
32
32
+
let sig = keypair.sign(&builder.bytes())?;
33
33
+
let mut repo = builder.finalize(sig).await?;
34
34
+
35
35
+
// add record
36
36
+
let key = format!("{collection}/{rkey}");
37
37
+
let (cb, _cid) = repo.add_raw(&key, record).await?;
38
38
+
let sig = keypair.sign(&cb.bytes())?;
39
39
+
cb.finalize(sig).await?;
40
40
+
41
41
+
// to the car!
42
42
+
let mut car_bytes = Vec::new();
43
43
+
{
44
44
+
let cursor = Cursor::new(&mut car_bytes); // something CarStore can use
45
45
+
let mut car = CarStore::create_with_roots(cursor, [repo.root()]).await?;
46
46
+
repo.export_into(&mut car).await?;
47
47
+
}
48
48
+
49
49
+
Ok(car_bytes)
50
50
+
}
51
51
+
52
52
+
#[cfg(test)]
53
53
+
mod tests {
54
54
+
use super::*;
55
55
+
56
56
+
#[tokio::test]
57
57
+
async fn test_generate_car() {
58
58
+
let car_bytes = manufacture_car(
59
59
+
"did:plc:somebodyyyy".parse().unwrap(),
60
60
+
"codes.advent.supersecret.verification",
61
61
+
"1337",
62
62
+
ChallengeRecord {
63
63
+
created_at: "2026-01-01T12:00:00Z".into(),
64
64
+
verification_code: "ABCDE-FGHIJ".to_string(),
65
65
+
message: "what did the muffin say to the other muffin?".into(),
66
66
+
},
67
67
+
)
68
68
+
.await
69
69
+
.expect("build a car");
70
70
+
71
71
+
assert!(
72
72
+
car_bytes.len() > 100,
73
73
+
"car too small to be real: {} bytes",
74
74
+
car_bytes.len()
75
75
+
);
76
76
+
}
77
77
+
}