geocaches for the atmosphere

Fleshing out the geocache lexicon

+11
Cargo.toml
··· 4 4 edition = "2024" 5 5 6 6 [dependencies] 7 + atproto-client = "0.11.2" 8 + atproto-identity = "0.11.2" 9 + atproto-oauth = "0.11.2" 10 + atproto-oauth-aip = "0.11.2" 11 + atproto-oauth-axum = "0.11.2" 12 + axum = "0.8.4" 13 + axum-htmx = "0.8.1" 14 + axum-template = "3.0.0" 15 + serde = "1.0.219" 16 + serde_json = "1.0.143" 17 + sqlx = "0.8.6"
+153
lexicon/world.geocache.experimental.geocache.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "world.geocache.experimental.geocache", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "A geocache out there in the world", 8 + "key": "tid", 9 + "record": { 10 + "type": "object", 11 + "required": ["name", "location", "cacheType", "status", "attributes", "description", "createdAt"], 12 + "properties": { 13 + "name": { 14 + "type": "string", 15 + "maxLength": 1000, 16 + "maxGraphemes": 100, 17 + "description": "The name for the geocache" 18 + }, 19 + "location": { 20 + "type": "object", 21 + "required": ["address", "geo"], 22 + "properties": { 23 + "geo": { "type": "ref", "ref": "community.lexicon.location.geo" }, 24 + "address": { "type": "ref", "ref": "community.lexicon.location.address" }, 25 + "hthree": { "type": "ref", "ref": "community.lexicon.location.hthree" }, 26 + "ip": { "type": "string", "format": "uri"} 27 + } 28 + }, 29 + "cacheType": { 30 + "type": "union", 31 + /* 32 + there's a few cache types that opencaching has which i'm not sure about 33 + - moving 34 + this is the most interesting one -- this represents a geocache that is moving 35 + between each find (typically the finder moves the cache, updates the coordinates 36 + after finding it). atproto does not currently have shared records, so you can't 37 + do it that way. 38 + 39 + my immediate thought would be: a special subset of the geocache lexicon which 40 + has a parameter for "nextLocation" -- the finder of the cache logs their visit, 41 + not as a traditional "visit" lexicon, but instead as a "movedCache". while this would 42 + introduce friction in that you would need the owner to update the cache, it would 43 + be a pretty simple implementation from then on. the appview would just need to 44 + keep track of successive moves and display them to the user. you'd also get a mostly free 45 + history view, which could be super fun! 46 + 47 + if combined with the idea of pubkey verification, you could even automate the transfer 48 + of a geocache -- the appview listens for a visit that has a linkback, verifies that 49 + the signature is properly decrypted, and then would update the record on the original 50 + owner's PDS to point to the first finder... 51 + - event 52 + the way this is described on opencaching seems to just represent like, 53 + an in person meetup or something like that. not sure we need this one. 54 + it would provide some feature pairity to opencaching, at least? 55 + - webcam 56 + these represent geocaches which use a webcam to log visits. 57 + i don't see why this can't just be an attribute of a cache. 58 + */ 59 + "refs": [ 60 + "world.geocache.type#traditional", 61 + "world.geocache.type#multi", 62 + "world.geocache.type#puzzle", 63 + /* idea: what if a virtual cache type could point to a URI or IP address? 64 + you could create a "virtual geocache" in the spirit of wargames. 65 + 66 + opencaching uses the virtual type to refer to a cache where the location 67 + itself is the reward, and there is not any physical objects. it might 68 + be worth differentiating these two ideas of "virtual geocaches", if such a thing would 69 + be desired. 70 + */ 71 + "world.geocache.type#virtual", 72 + "world.geocache.type#owncache", // this could have a less clunky name, imo 73 + "world.geogache.type#other" 74 + ] 75 + }, 76 + "status": { 77 + "type": "union", 78 + "description": "The status of the geocache", 79 + // other statuses may be useful 80 + "refs": [ 81 + "world.geocache.status#active", // ready to be searched 82 + "world.geocache.status#dead", // no longer accessible, general 83 + "world.geocache.status#done", // no longer accessible, time limited geocaches 84 + "world.geocache.status#moved", // no longer accessible at given location, for moving caches 85 + "world.geocache.status#unknown" // may not be accessible 86 + ] 87 + }, 88 + "attributes": { 89 + /* 90 + opencaching has 35 attributes: https://wiki.opencaching.us/index.php/Cache_parameters#Attributes 91 + 92 + some of these aren't useful to us (OCNA only, for example), but most are 93 + probably worth porting over 1:1. we also could add new ones. 94 + */ 95 + "type": "array", 96 + "description": "Attributes which describe the geocache", 97 + "items": { 98 + "type": "union", 99 + // for now i'm not going to list every single one, but just the general idea 100 + // based off of attributes on opencaching 101 + "refs": [ 102 + "world.geocache.attribute#snakes", 103 + "world.geocache.attribute#garminchirp", 104 + "world.geocache.attribute#woods", 105 + "world.geocache.attribute#byop", 106 + // ... 107 + ] 108 + } 109 + }, 110 + "description": { 111 + "type": "string", 112 + "maxLength": 10000, 113 + "maxGraphemes": 1000, 114 + "description": "A description for the geocache. " 115 + }, 116 + "pubkey": { 117 + /* 118 + the idea here is basically a fancier method of doing password verification 119 + for visits to a geocache: 120 + - the creator generates an ed25519 keypair (chosen for its small key sizes) 121 + - the pubkey gets logged with the record 122 + - the privkey gets deployed with the geocache 123 + - visitors to the cache save the privkey 124 + - visitors can sign a message with the discovered private key 125 + - this message gets logged with their visit record 126 + - the appview can "verify" the cache using the pubkey to decrypt the message 127 + 128 + the exact protocol for this remains to be explored, but i think it's a fun idea. 129 + 130 + there's also a riff on this idea that might work well with the "moving" cache type: 131 + - each geocacher has a keypair 132 + - the original owner plants the geocache, and signs off their visit with their key 133 + - the next finder takes the geocache home, and logs their ownership signing with their key, referring to the last owner 134 + - this then creates a cryptographically signed history of the cache's location history 135 + 136 + yes, that's basically a stupid blockchain. but it's kinda silly in the good way. 137 + 138 + i mean, every record on a user's PDS is able to be proven to originate from the owner, 139 + so maybe you could still share a single private key that moves with the geocache? 140 + much to be thought about... 141 + */ 142 + "type": "bytes", 143 + "maxLength": 57, 144 + "createdAt": { 145 + "type": "string", 146 + "format": "datetime", 147 + "description": "When the geocache was first created" 148 + } 149 + } 150 + } 151 + }, 152 + } 153 + }