1/// Example usage of the atProto identity resolution layer. 2/// 3/// This demonstrates the critical functionality for decentralization: 4/// resolving handles and DIDs to find where user data is actually stored. 5 6import 'package:atproto_oauth_flutter/src/identity/identity.dart'; 7 8Future<void> main() async { 9 print('=== atProto Identity Resolution Examples ===\n'); 10 11 // Create an identity resolver 12 // The handleResolverUrl should point to an XRPC service that implements 13 // com.atproto.identity.resolveHandle (typically bsky.social for public resolution) 14 final resolver = AtprotoIdentityResolver.withDefaults( 15 handleResolverUrl: 'https://bsky.social', 16 ); 17 18 print('Example 1: Resolve a Bluesky handle to find their PDS'); 19 print('--------------------------------------------------'); 20 try { 21 // This is the most common use case: find where a user's data lives 22 final pdsUrl = await resolver.resolveToPds('pfrazee.com'); 23 print('Handle: pfrazee.com'); 24 print('PDS URL: $pdsUrl'); 25 print('✓ This user hosts their data on: $pdsUrl\n'); 26 } catch (e) { 27 print('Error: $e\n'); 28 } 29 30 print('Example 2: Get full identity information'); 31 print('--------------------------------------------------'); 32 try { 33 final info = await resolver.resolve('pfrazee.com'); 34 print('Handle: ${info.handle}'); 35 print('DID: ${info.did}'); 36 print('PDS URL: ${info.pdsUrl}'); 37 print('Has valid handle: ${info.hasValidHandle}'); 38 print('Also known as: ${info.didDoc.alsoKnownAs}'); 39 print('✓ Complete identity information retrieved\n'); 40 } catch (e) { 41 print('Error: $e\n'); 42 } 43 44 print('Example 3: Resolve from a DID'); 45 print('--------------------------------------------------'); 46 try { 47 // You can also start from a DID 48 final info = await resolver.resolveFromDid( 49 'did:plc:ragtjsm2j2vknwkz3zp4oxrd', 50 ); 51 print('DID: ${info.did}'); 52 print('Handle: ${info.handle}'); 53 print('PDS URL: ${info.pdsUrl}'); 54 print('✓ Resolved DID to handle and PDS\n'); 55 } catch (e) { 56 print('Error: $e\n'); 57 } 58 59 print('Example 4: Custom domain handle (CRITICAL for decentralization)'); 60 print('--------------------------------------------------'); 61 try { 62 // This demonstrates why this code is essential: 63 // Users can use their own domains and host on their own PDS 64 final info = await resolver.resolve('jay.bsky.team'); 65 print('Handle: ${info.handle}'); 66 print('DID: ${info.did}'); 67 print('PDS URL: ${info.pdsUrl}'); 68 print('✓ Custom domain resolves to custom PDS (not hardcoded!)\n'); 69 } catch (e) { 70 print('Error: $e\n'); 71 } 72 73 print('Example 5: Validation - Invalid handle'); 74 print('--------------------------------------------------'); 75 try { 76 await resolver.resolve('not-a-valid-handle'); 77 } catch (e) { 78 print('✓ Correctly rejected invalid handle: $e\n'); 79 } 80 81 print('=== Why This Matters ==='); 82 print(''' 83This identity resolution layer is THE CRITICAL PIECE for atProto decentralization: 84 851. **No Hardcoded Servers**: Unlike broken implementations that hardcode bsky.social, 86 this correctly resolves each user's actual PDS location. 87 882. **Custom Domains**: Users can use their own domains (e.g., alice.example.com) 89 and host on any PDS they choose. 90 913. **Portability**: Users can change their PDS without losing their DID or identity. 92 The DID document always points to the current PDS location. 93 944. **Bi-directional Validation**: We verify that: 95 - Handle → DID resolution works 96 - DID document contains the handle 97 - Both directions match (security!) 98 995. **Caching**: Built-in caching prevents redundant lookups while respecting TTLs. 100 101Without this layer, apps are locked to centralized servers. With it, atProto 102achieves true decentralization where users control their data location. 103'''); 104}