### Run Affinidi DID Authentication Binary Example (Bash) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-tdk/common/affinidi-did-authentication/README.md Example command to run the Affinidi DID Authentication binary using pre-configured environment profiles. This command assumes you are in the correct directory and have the necessary environment setup. It specifies the authentication mode ('environment') and the profile name ('Alice'). ```bash cargo run -- -a did:web:meetingplace.world environment -n Alice ``` -------------------------------- ### Run Affinidi Messaging SDK Examples (Bash) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-sdk/README.md Executes various example commands for the Affinidi Messaging SDK using Cargo. It requires setting environment variables for logging, mediator DID, endpoint, and TLS certificates. These examples demonstrate functionalities like sending pings, message pickup, and sending messages to different recipients. ```bash # enable logging for examples, export RUST_LOG=none,affinidi_messaging_sdk=debug,ping=debug,demo=debug,send_message_to_me=debug,send_message_to_bob=debug,fetch_message_as_bob=debug,message_pickup=debug # no "did://" prefix for examples export MEDIATOR_DID= # default, local mediator endpoint export MEDIATOR_ENDPOINT=https://localhost:7037/mediator/v1 # relative path to local mediator cert file export MEDIATOR_TLS_CERTIFICATES="../affinidi-messaging-mediator/conf/keys/client.chain" # send a trust ping cargo run --example ping -- \ --network-address $MEDIATOR_ENDPOINT \ --ssl-certificates $MEDIATOR_TLS_CERTIFICATES \ cargo run --example message_pickup -- \ --network-address $MEDIATOR_ENDPOINT \ --ssl-certificates $MEDIATOR_TLS_CERTIFICATES # send a message to the same recipient as sender cargo run --example send_message_to_me -- \ --network-address $MEDIATOR_ENDPOINT \ --ssl-certificates $MEDIATOR_TLS_CERTIFICATES # send a message to another recipient Bob cargo run --example send_message_to_bob -- \ --network-address $MEDIATOR_ENDPOINT \ --ssl-certificates $MEDIATOR_TLS_CERTIFICATES # pickup a message from another sender Alice cargo run --example fetch_message_as_bob -- \ --network-address $MEDIATOR_ENDPOINT \ --ssl-certificates $MEDIATOR_TLS_CERTIFICATES ``` -------------------------------- ### Navigate to Messaging Crate Directory Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/docs/aws-marketplace-setup-guide.md Changes the current directory to the `affinidi-messaging` crate within the cloned repository. This is necessary to run the configuration generation script. ```bash cd affinidi-tdk-rs/crates/affinidi-messaging ``` -------------------------------- ### Setup Mediator Environment with Cargo Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-mediator/README.md Executes the 'setup_environment' cargo binary to configure the mediator service locally. This command generates essential artifacts like Mediator and Administration DIDs and secrets, SSL certificates, and optionally test users. ```bash cargo run --bin setup_environment ``` -------------------------------- ### Run Mediator Administration Example Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-mediator/README.md Executes the mediator administration binary using Cargo. This command is used to manage administration accounts, allowing for easy addition, removal, and listing of administrative users for the mediator. ```bash cargo run --bin mediator_administration ``` -------------------------------- ### Set Affinidi Messaging Profile at Run-time (Bash) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-helpers/README.md Specifies the 'local' profile for Affinidi Messaging examples directly via a command-line argument. This method overrides any previously set environment variables for the profile, providing explicit control over the active configuration for the `mediator_ping` example. Requires the `setup-environment` helper to have created the 'local' profile. ```bash cargo run --example mediator_ping -- -e local ``` -------------------------------- ### Network Mode DID Resolution with Custom Settings in Rust Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-did-resolver/affinidi-did-resolver-cache-sdk/README.md Illustrates the setup for network mode, where DID resolution is primarily handled by a remote server, with local caching for efficiency. This example shows how to configure the network address, cache time-to-live (TTL), and network timeout duration. The function returns the resolved DID document or an error. ```rust use affinidi_did_resolver_cache_sdk::{config::ClientConfigBuilder, errors::DIDCacheError, DIDCacheClient}; // create a network client configuration, set the service address. let network_config = ClientConfigBuilder::default() .with_network_mode("ws://127.0.0.1:8080/did/v1/ws") .with_cache_ttl(60) // Change the cache TTL to 60 seconds .with_network_timeout(20_000) // Change the network timeout to 20 seconds .build(); let network_resolver = DIDCacheClient::new(network_config).await?; match local_resolver.resolve("did:key:...").await { Ok((request) => { println!( "Resolved DID ({}) did_hash({}) Document:\n{:#?}\n", request.did, request.did_hash, request.doc ); } Err(e) => { println!("Error: {:?}", e); } } ``` -------------------------------- ### Clone DIDComm Mediator Repository Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/docs/aws-marketplace-setup-guide.md Clones the Affinidi DIDComm Mediator TDK Rust repository from GitHub. This is a prerequisite for generating DIDs and secrets needed for deployment. ```bash git clone git@github.com:affinidi/affinidi-tdk-rs.git ``` -------------------------------- ### Test Mediator Connection with Ping (Bash) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/docs/aws-marketplace-setup-guide.md Sets the RUST_LOG environment variable for detailed logging and then runs the `mediator_ping` example. This tests the connection to the mediator by sending a ping and expecting a pong response. ```bash export RUST_LOG=none,affinidi_messaging_helpers=debug,affinidi_messaging_sdk=debug cargo run --example mediator_ping ``` -------------------------------- ### Run Integration Tests with Network Feature (Bash) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-did-resolver/affinidi-did-resolver-cache-sdk/README.md This command executes integration tests for the Rust project. The `--features network` flag is crucial for enabling network-related functionalities required during these tests. Ensure you have the Rust toolchain and the project dependencies installed. ```bash cargo test --features network ``` -------------------------------- ### Interact with Mediator REST API using Bash Source: https://context7.com/affinidi/affinidi-tdk-rs/llms.txt This section provides Bash command-line examples for interacting with a Mediator REST API. It covers operations such as retrieving the mediator's DID document, authenticating, sending and fetching messages, and performing health checks. ```bash # Get mediator's DID document curl https://mediator.example.com/mediator/v1/.well-known/did.json # Authenticate - get challenge curl -X POST https://mediator.example.com/mediator/v1/authenticate/challenge \ -H "Content-Type: application/json" \ -d '{"did": "did:example:alice"}' # Authenticate - submit response curl -X POST https://mediator.example.com/mediator/v1/authenticate \ -H "Content-Type: application/json" \ -d '{ "did": "did:example:alice", "response": "" }' # Send inbound message curl -X POST https://mediator.example.com/mediator/v1/inbound \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '' # List inbox messages curl https://mediator.example.com/mediator/v1/list//inbox \ -H "Authorization: Bearer " # Fetch specific messages curl -X POST https://mediator.example.com/mediator/v1/fetch \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "message_ids": ["msg-id-1", "msg-id-2"], "delete": true }' # Delete messages curl -X DELETE https://mediator.example.com/mediator/v1/delete \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "message_ids": ["msg-id-1", "msg-id-2"] }' # WebSocket connection wscat -c wss://mediator.example.com/mediator/v1/ws \ -H "Authorization: Bearer " # Health check curl https://mediator.example.com/mediator/v1/healthchecker ``` -------------------------------- ### Sample Mediator DID Document Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/docs/aws-marketplace-setup-guide.md A sample JSON structure representing the DID document for a DIDComm Mediator. It includes context, assertion methods, authentication, key agreement, service endpoints (DIDComm v2 with HTTP and WebSocket), and verification methods. This document is crucial for establishing trust and communication protocols with the mediator. ```json { "@context": [ "https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/jws-2020/v1" ], "assertionMethod": [ "did:web:mediator.goodcompany.com#key-1", "did:web:mediator.goodcompany.com#key-2" ], "authentication": [ ..... ], "id": "did:web:mediator.goodcompany.com", "keyAgreement": [ ..... ], "service": [ { "id": "did:web:mediator.goodcompany.com#service", "serviceEndpoint": [ { "accept": [ "didcomm/v2" ], "routingKeys": [], "uri": "https://mediator.goodcompany.com" }, { "accept": [ "didcomm/v2" ], "routingKeys": [], "uri": "wss://mediator.goodcompany.com/ws" } ], "type": "DIDCommMessaging" }, { "id": "did:web:mediator.goodcompany.com#auth", "serviceEndpoint": "https://mediator.goodcompany.com/authenticate", "type": "Authentication" } ], "verificationMethod": [ { "controller": "did:web:mediator.goodcompany.com", "id": "did:web:mediator.goodcompany.com#key-1", "publicKeyJwk": { "crv": "P-256", "kty": "EC", "x": "t_urdyvDKJLgYxJMrV6u0...", "y": "DWciV1aBxqHXH2jW..." }, "type": "JsonWebKey2020" }, ..... ] } ``` -------------------------------- ### Start Affinidi Messaging Mediator Service Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-mediator/README.md Initiates the 'affinidi-messaging-mediator' service after setting the Redis connection URL. This command navigates to the mediator's directory, sets the REDIS_URL environment variable, and then runs the service using Cargo. ```bash cd affinidi-messaging-mediator export REDIS_URL=redis://@localhost:6379 cargo run ``` -------------------------------- ### Generate DIDComm Mediator Configuration (Rust) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/docs/aws-marketplace-setup-guide.md Generates the necessary DID and JWT secrets for the DIDComm Mediator instance using the Rust `generate_mediator_config` binary. Requires Rust 1.85.0 or later. The `--host` parameter is mandatory and specifies the domain where the mediator will be hosted. ```rust cargo run --bin generate_mediator_config -- --host ``` -------------------------------- ### Set Affinidi Messaging Profile using Environment Variable (Bash) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-helpers/README.md Sets the TDK_ENVIRONMENT environment variable to 'local', configuring the Affinidi Messaging helper to use the 'local' profile for running examples. This is a convenient way to switch between different mediator configurations without command-line arguments. Assumes the `setup-environment` helper has already generated the necessary profile configurations. ```bash export TDK_ENVIRONMENT=local car go run --example mediator_ping ``` -------------------------------- ### Run Redis Docker Container Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-mediator/README.md Starts a Redis Docker container for the mediator service. This container is named 'redis-local', publishes port 6379, restarts on failure, and runs the latest Redis image. It is essential for storing mediator data. ```bash docker run --name=redis-local --publish=6379:6379 --hostname=redis --restart=on-failure --detach redis:latest ``` -------------------------------- ### Manage Cryptographic Secrets for DIDComm in Rust Source: https://context7.com/affinidi/affinidi-tdk-rs/llms.txt Illustrates how to securely store and retrieve cryptographic keys (Ed25519 and X25519) for DIDComm operations using the `affinidi_secrets_resolver` library. This example shows creating a `ThreadedSecretsResolver`, generating secrets from multibase strings, inserting them individually and in batches, and retrieving them by their key ID. The resolver itself implements the `SecretsResolver` trait. ```rust use affinidi_secrets_resolver::{ ThreadedSecretsResolver, secrets::{Secret, SecretType} }; async fn secrets_example() -> Result<(), Box> { // Create resolver let (secrets_resolver, handle) = ThreadedSecretsResolver::new(None).await; // Create Ed25519 secret let ed25519_secret = Secret::from_multibase( "z3u2en7t5LR2WtQH5PfFqMqwVHBeXouLzo6haApm8XHqvjxq", Some("did:example:alice#key-1") )?; // Create X25519 secret let x25519_secret = Secret::from_multibase( "z3zDmBFkYNJGgWY4zNZ4RvGpf9qrHQ3vRBq7rBbQMwPx6CfF", Some("did:example:alice#key-2") )?; // Insert secrets secrets_resolver.insert(ed25519_secret.clone()).await; secrets_resolver.insert(x25519_secret.clone()).await; // Batch insert let secrets = vec![ed25519_secret.clone(), x25519_secret.clone()]; secrets_resolver.insert_vec(&secrets).await; // Retrieve secret by key ID if let Some(secret) = secrets_resolver .find_secret("did:example:alice#key-1") .await { println!("Found secret: {}", secret.id); println!("Type: {:?}", secret.type_); println!("Public key bytes: {} bytes", secret.get_public_bytes().len()); println!("Private key bytes: {} bytes", secret.get_private_bytes().len()); } // Secret implements SecretsResolver trait let secret = secrets_resolver.find_secret("did:example:alice#key-1").await; Ok(()) } ``` -------------------------------- ### Benchmark CLI Arguments Help Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-did-resolver/affinidi-did-resolver-cache-sdk/README.md Displays the help message for the benchmark command-line interface (CLI). It outlines the available options, including the network address, generate count for keys, resolve count for DIDs, and standard help/version flags. ```bash Affinidi DID Cache SDK Usage: benchmark [OPTIONS] --generate-count --resolve-count Options: -n, --network-address network address if running in network mode (ws://127.0.0.1:8080/did/v1/ws) -g, --generate-count Number of keys to generate -r, --resolve-count Number of DIDs to resolve -h, --help Print help -V, --version Print version ``` -------------------------------- ### Mediator JWT Secret Configuration (Bash) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/docs/aws-marketplace-setup-guide.md The mediator's JWT secret, generated in a previous step, should be copied as the value for 'mediator/atn/atm/mediator/global/jwt_secret/dev'. This secret is used for authentication purposes. ```text MFECAQEwBQYDK2VwBCIEIN_YPGCcfxWJAJ1bKp91GsQbfZuDr737ARJ65lmyAbMDgSEA1n9cHIy4Ivu55FVfph4t0... ``` -------------------------------- ### Benchmark Suite Execution Command Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-did-resolver/affinidi-did-resolver-cache-sdk/README.md Provides the command to run the benchmark suite for performance testing. This command enables the 'network' feature and specifies the network address, number of keys to generate, and number of DIDs to resolve. It's intended to be run from the SDK's directory. ```bash cargo run --features network --example benchmark -- -g 1000 -r 10000 -n ws://127.0.0.1:8080/did/v1/ws ``` -------------------------------- ### Mediator DID Secret Configuration (JSON) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/docs/aws-marketplace-setup-guide.md Provides the structure for the mediator's DID secret, which includes private key information necessary for decrypting and verifying messages addressed to the mediator. This JSON should be used as the value for 'mediator/atn/atm/mediator/global/secrets/dev'. ```json [ { "id": "did:web:mediator.goodcompany.com#key-1", "privateKeyJwk": { "crv": "P-256", "d": "soi0RdleEYyzCX...", "kty": "EC", "x": "t_urdyvDKJLgYxJM...", "y": "DWciV1aBxqHXH2..." }, "type": "JsonWebKey2020" }, { "id": "did:web:mediator.goodcompany.com#key-2", "privateKeyJwk": { "crv": "Ed25519", "d": "qjRq7akRjv22RSus...", "kty": "OKP", "x": "tuJadwaoBEb7vTD..." }, "type": "JsonWebKey2020" }, { "id": "did:web:mediator.goodcompany.com#key-3", "privateKeyJwk": { "crv": "secp256k1", "d": "5GIxIbn03X_...", "kty": "EC", "x": "mrR3O-sqRKsuJ9q...", "y": "CJy9Ss70LW2..." }, "type": "JsonWebKey2020" }, { "id": "did:web:mediator.goodcompany.com#key-4", "privateKeyJwk": { "crv": "P-256", "d": "rT2pIZMaOIF2HebA...", "kty": "EC", "x": "DlDk3EALp_kZl-...", "y": "AH9aYsXlTJ8Qi2..." }, "type": "JsonWebKey2020" } ] ``` -------------------------------- ### TDK Configuration and Initialization Source: https://context7.com/affinidi/affinidi-tdk-rs/llms.txt This section details how to configure and initialize the complete TDK stack with custom settings and environment profiles using Rust. ```APIDOC ## TDK Configuration and Initialization ### Description Configure the complete TDK stack with custom settings and environment profiles. ### Method N/A (Illustrative Rust code) ### Endpoint N/A (Illustrative Rust code) ### Parameters N/A (Illustrative Rust code) ### Request Example ```rust // See the provided Rust code for a detailed example of TDK configuration and initialization. // This includes setting up DID resolver, secrets resolver, ATM configuration, // and loading/adding profiles. ``` ### Response N/A (Illustrative Rust code) #### Success Response (Illustrative) N/A (Illustrative Rust code) #### Response Example ```rust // The Rust code demonstrates successful initialization and usage of TDK components. // A verification result is printed to the console. ``` ``` -------------------------------- ### Initialize ATM SDK with Custom WebSocket Configuration (Rust) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-sdk/README.md Initializes the Affinidi Messaging SDK (ATM) with custom configurations, including disabling the WebSocket and specifying SSL certificates and DIDs. This snippet demonstrates how to build a configuration object and create a new ATM instance. It requires the `ConfigBuilder` and `ATM` types, and returns a `Result` which can be an `ATMError` on failure. ```rust let my_did = "did:example:alice"; let bob_did = "did:example:bob"; let atm_did = "did:example:atm"; let config = Config::builder() .with_ssl_certificates(&mut vec![ "../affinidi-messaging-mediator/conf/keys/client.chain".into() ]) .with_my_did(my_did) .with_atm_did(atm_did) .with_websocket_disabled() .build()?; let mut atm = ATM::new(config, vec![Box::new(DIDPeer)]).await?; // Send a ping via REST atm.send_ping(bob_did, true, true).await?; // Start the Websocket atm.start_websocket().await?; // Send a ping via WebSocket atm.send_ping(bob_did, true, true).await?; // Close the websocket (optional) atm.close_websocket().await?; ``` -------------------------------- ### Configure and Initialize TDK Stack in Rust Source: https://context7.com/affinidi/affinidi-tdk-rs/llms.txt This Rust code demonstrates how to configure and initialize the Affinidi TDK stack with custom settings. It involves setting up the DID resolver, secrets resolver, and ATM configurations, then building the TDK instance. Finally, it shows how to access TDK components and verify data integrity. ```rust use affinidi_tdk::{TDK, common::config::TDKConfig}; use affinidi_did_resolver_cache_sdk::config::DIDCacheConfigBuilder; use affinidi_secrets_resolver::ThreadedSecretsResolver; use affinidi_messaging_sdk::config::ATMConfig; async fn tdk_config_example() -> Result<(), Box> { // Configure DID resolver let did_resolver_config = DIDCacheConfigBuilder::default() .with_cache_capacity(20000) .with_cache_ttl(7200) .build(); // Configure secrets resolver let (secrets_resolver, _) = ThreadedSecretsResolver::new(None).await; // Build TDK configuration let tdk_config = TDKConfig::builder() .with_environment_path("environments.json".into()) .with_environment_name("production".into()) .with_did_resolver_config(did_resolver_config) .with_secrets_resolver(secrets_resolver) .with_authentication_cache_limit(5000) .with_use_atm(true) .build()?; // Initialize TDK with ATM configuration let atm_config = ATMConfig::builder() .with_ssl_certificates(&mut vec!["certs/client.pem".into()]) .with_fetch_cache_limit_count(200) .with_fetch_cache_limit_bytes(10_485_760) .with_inbound_message_channel(1000) .build()?; let tdk = TDK::new(tdk_config, Some(atm_config)).await?; // Access components let did_resolver = tdk.did_resolver(); let atm = tdk.atm.as_ref().unwrap(); let shared_state = tdk.get_shared_state(); // Load profile from environment let profile = shared_state.environment .profiles .get("Alice") .ok_or("Profile not found")?; tdk.add_profile(profile).await; // Verify data integrity let document = serde_json::json!({{"data": "value"}}); let proof = serde_json::json!({ "type": "DataIntegrityProof", "cryptosuite": "EddsaJcs2022", "verificationMethod": "did:key:z6Mk...#z6Mk...", "proofValue": "z..." }); let proof: affinidi_data_integrity::DataIntegrityProof = serde_json::from_value(proof)?; let verification = tdk.verify_data( &document, Some(vec!["https://www.w3.org/ns/did/v1".into()]), &proof ).await?; println!("Verification result: {}", verification.verified); Ok(()) } ``` -------------------------------- ### Unpack DIDComm Message Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-sdk/README.md A wrapper around DIDComm `Message::unpack()` that simplifies message unpacking by pre-configuring resolvers and other necessary setups within the ATM context. It takes a plain string and returns a DIDComm `Message` object and associated `UnpackMetadata`. ```APIDOC ## Unpack DIDComm Message ### Description Unpacks a DIDComm message from a string representation into `Message` and `UnpackMetadata` objects. This method simplifies the unpacking process by leveraging the ATM's pre-configured resolvers. ### Method `unpack(message: &str) -> Result<(Message, UnpackMetadata), ATMError>` ### Endpoint N/A (This is a function call within the ATM context) ### Parameters #### Request Body - **message** (String) - Required - The DIDComm message as a plain string. ### Request Example ```rust // Example: Unpack a DIDComm message let didcomm_message_string = atm.get_messages(&vec!["msg_id".to_string()], true).await?; let (message, meta_data) = atm.unpack(&didcomm_message_string).await?; println!("Message body = {}", message.body); ``` ### Response #### Success Response - **Result->Ok** (`Message`, `UnpackMetadata`): Returns the unpacked DIDComm `Message` object and `UnpackMetadata` upon successful unpacking. #### Error Response - **Result->Err** (`ATMError`): An `ATMError` object describing the reason for failure during unpacking. ``` -------------------------------- ### Enable Debug Logging for Affinidi Messaging SDK (Bash) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-sdk/README.md Enables debug-level logging specifically for the `affinidi_messaging_sdk` crate. This helps in diagnosing issues by providing detailed logs during development or troubleshooting. No specific inputs or outputs are required, it modifies the environment for subsequent commands. ```bash export RUST_LOG=none,affinidi_messaging_sdk=debug ``` -------------------------------- ### Local Mode DID Resolution in Rust Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-did-resolver/affinidi-did-resolver-cache-sdk/README.md Demonstrates how to initialize and use the DIDCacheClient in local mode. This configuration resolves DIDs locally, fetching from network services only when necessary for specific DID methods. It takes a configuration object and returns a resolved DID document or an error. ```rust use affinidi_did_resolver_cache_sdk::{config::ClientConfigBuilder, errors::DIDCacheError, DIDCacheClient}; // Create a new local client configuration, use default values let local_config = ClientConfigBuilder::default().build(); let local_resolver = DIDCacheClient::new(local_config).await?; let doc = local_resolver.resolve("did:key:...").await?; match local_resolver.resolve(peer_did).await { Ok(request) => { println!( "Resolved DID ({}) did_hash({}) Document:\n{:#?}\n", request.did, request.did_hash, request.doc ); } Err(e) => { println!("Error: {:?}", e); } } ``` -------------------------------- ### Get DIDComm Messages Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-sdk/README.md Retrieves one or more DIDComm messages from ATM using their message IDs. It allows specifying whether to delete the messages after retrieval. The function returns a GetMessagesResponse containing successfully retrieved messages and any errors encountered during retrieval or deletion, or an ATMError. ```rust async fn get_messages(messages: &GetMessagesRequest) -> Result // Gets one or more messages from ATM // Example: Get one message, and don't delete it get_messages(&vec!["message_id".into()], false).await?; ``` -------------------------------- ### Enable Debug Logging for Affinidi Messaging Helpers (Bash) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-helpers/README.md Configures the RUST_LOG environment variable to enable debug-level logging specifically for the `affinidi_messaging_helpers` crate. This helps in diagnosing issues within the messaging helper functionalities. The output will be filtered to show only debug messages from this crate, while other crates like `affinidi_messaging_sdk` will log at info level. ```bash export RUST_LOG=none,affinidi_messaging_helpers=debug,affinidi_messaging_sdk=info ``` -------------------------------- ### Unpack DIDComm Message (Rust) Source: https://github.com/affinidi/affinidi-tdk-rs/blob/main/crates/affinidi-messaging/affinidi-messaging-sdk/README.md A wrapper function around DIDComm's `Message::unpack()` that simplifies message unpacking within the ATM context. It takes a raw message string and returns a structured `Message` object along with `UnpackMetadata`. This function handles the necessary resolver setup. ```rust async fn unpack(message: &str) -> Result<(Message, UnpackMetadata), ATMError> // Unpacks any DIDComm message into a Message and UnpackMetadata response // Example: let didcomm_message = atm.get_messages(&vec!["msg_id".to_string()], true).await?; let (message, meta_data) = atm.unpack(&didcomm_message).await?; println!("Message body = {}", message.body); ``` -------------------------------- ### Rust: Complete Alice-to-Bob Encrypted Messaging Flow Source: https://context7.com/affinidi/affinidi-tdk-rs/llms.txt Implements a full encrypted messaging scenario between Alice and Bob using DIDComm. It initializes the TDK, sets up profiles, creates, encrypts, signs, and sends a message, then receives and decrypts it. Requires the Affinidi TDK, messaging SDK, DIDComm library, serde_json, uuid, and tokio. ```rust use affinidi_tdk::{TDK, common::config::TDKConfig}; use affinidi_messaging_sdk::{ATM, profiles::ATMProfile, protocols::Protocols}; use affinidi_messaging_didcomm::Message; use serde_json::json; use uuid::Uuid; use std::time::{Duration, SystemTime}; #[tokio::main] async fn main() -> Result<(), Box> { // Initialize TDK with environment configuration let tdk = TDK::new( TDKConfig::builder() .with_environment_name("default".into()) .with_authentication_cache_limit(1000) .build()?, None ).await?; let atm = tdk.atm.clone().unwrap(); let protocols = Protocols::new(); let environment = &tdk.get_shared_state().environment; // Setup Alice profile with WebSocket enabled let alice_tdk = environment.profiles.get("Alice").unwrap(); tdk.add_profile(alice_tdk).await; let alice = atm.profile_add( &ATMProfile::from_tdk_profile(&atm, alice_tdk).await?, true // enable WebSocket live delivery ).await?; // Setup Bob profile let bob_tdk = environment.profiles.get("Bob").unwrap(); tdk.add_profile(bob_tdk).await; let bob = atm.profile_add( &ATMProfile::from_tdk_profile(&atm, bob_tdk).await?, true ).await?; // Create DIDComm message let now = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH)? .as_secs(); let msg = Message::build( Uuid::new_v4().into(), "https://example.com/chat/1.0/message".into(), json!({"text": "Hello Bob!", "timestamp": now}) ) .to(bob.inner.did.clone()) .from(alice.inner.did.clone()) .created_time(now) .expires_time(now + 300) .finalize(); let msg_id = msg.id.clone(); // Pack message with encryption and signature let (packed_msg, metadata) = atm.pack_encrypted( &msg, &bob.inner.did, Some(&alice.inner.did), Some(&alice.inner.did), None ).await?; println!("Message encrypted for: {:?}", metadata.encrypted_to); println!("Message signed by: {:?}", metadata.sign_by_kid); // Forward through Bob's mediator let (_, forward_msg) = protocols.routing.forward_message( &atm, &alice, false, // not anonymous &packed_msg, bob_tdk.mediator.as_ref().unwrap(), &bob.inner.did, None, // no expiry None // no created time ).await?; // Send the message atm.send_message(&alice, &forward_msg, &msg_id, false, false).await?; println!("Alice sent message: {}", msg_id); // Bob receives via live stream if let Some((received_msg, unpack_meta)) = protocols.message_pickup .live_stream_get(&atm, &bob, &msg_id, Duration::from_secs(10), true) .await? { println!("Bob received: {:?}", received_msg.body); println!("From: {:?}", unpack_meta.from_kid); println!("Encrypted: {}", unpack_meta.encrypted); println!("Authenticated: {}", unpack_meta.authenticated); println!("Sign from: {:?}", unpack_meta.sign_from); } Ok(()) } ``` -------------------------------- ### DID Authentication with JWT in Rust Source: https://context7.com/affinidi/affinidi-tdk-rs/llms.txt This Rust function demonstrates how to authenticate with a service using Decentralized Identifiers (DIDs) and JWT tokens for challenge-response authentication. It utilizes 'affinidi_did_authentication', 'affinidi_did_resolver_cache_sdk', and 'affinidi_secrets_resolver'. The function sets up resolvers, an HTTP client, performs authentication, and then uses the obtained access token to make a request to a protected API. Input is a DID, and output includes access and refresh tokens. ```rust use affinidi_did_authentication::DIDAuthentication; use affinidi_did_resolver_cache_sdk::DIDCacheClient; use affinidi_secrets_resolver::ThreadedSecretsResolver; async fn did_auth_example() -> Result<(), Box> { let did_resolver = DIDCacheClient::new( DIDCacheConfigBuilder::default().build() ).await?; let (secrets_resolver, _handle) = ThreadedSecretsResolver::new(None).await; let client = reqwest::Client::builder() .danger_accept_invalid_certs(true) .build()?; let mut did_auth = DIDAuthentication::new(); // Authenticate with service did_auth.authenticate( "did:example:alice", "did:example:service", &did_resolver, &secrets_resolver, &client, 3 // retry limit ).await?; // Access tokens let tokens = did_auth.tokens.as_ref().unwrap(); println!("Access token: {}", tokens.access_token); println!("Refresh token: {}", tokens.refresh_token); println!("Access expires at: {}", tokens.access_expires_at); println!("Refresh expires at: {}", tokens.refresh_expires_at); // Use token in requests let response = client .get("https://service.example.com/api/data") .bearer_auth(&tokens.access_token) .send() .await?; println!("Response status: {}", response.status()); Ok(()) } ``` -------------------------------- ### Rust: Message Pickup Protocol - Status and Delivery Source: https://context7.com/affinidi/affinidi-tdk-rs/llms.txt Demonstrates how to query message status, toggle live delivery, receive messages via live stream, and perform batch delivery with the Message Pickup Protocol. It utilizes the `Protocols` struct from `affinidi_messaging_sdk` and handles message retrieval and marking as received. ```rust use affinidi_messaging_sdk::protocols::Protocols; use std::time::Duration; async fn message_pickup_example( atm: &ATM, profile: &Arc ) -> Result<(), Box> { let protocols = Protocols::new(); // Check message status let status = protocols.message_pickup .send_status_request(atm, profile, true, Some(Duration::from_secs(5))) .await?; if let Some(status) = status { println!("Message count: {}", status.message_count); println!("Total bytes: {}", status.total_bytes); println!("Live delivery: {}", status.live_delivery); println!("Oldest message: {:?}", status.oldest_received_time); println!("Newest message: {:?}", status.newest_received_time); } // Toggle live delivery on protocols.message_pickup .toggle_live_delivery(atm, profile, true) .await?; // Wait for next message with auto-delete if let Some((msg, metadata)) = protocols.message_pickup .live_stream_next(atm, profile, Some(Duration::from_secs(30)), true) .await? { println!("Received: {:?}", msg.body); } // Batch delivery - get up to 10 messages let messages = protocols.message_pickup .send_delivery_request(atm, profile, Some(10), true) .await?; let msg_ids: Vec = messages.iter() .map(|(msg, _)| msg.id.clone()) .collect(); println!("Retrieved {} messages", messages.len()); // Mark messages as received (deletes them) let status = protocols.message_pickup .send_messages_received(atm, profile, &msg_ids, true) .await?; if let Some(status) = status { println!("Remaining messages: {}", status.message_count); } Ok(()) } ``` -------------------------------- ### Sign and Verify W3C Data Integrity Documents with Ed25519 in Rust Source: https://context7.com/affinidi/affinidi-tdk-rs/llms.txt Demonstrates how to cryptographically sign JSON documents using Ed25519 and W3C Data Integrity proofs, and subsequently verify these signatures. It utilizes `affinidi_data_integrity` for signing/verification and `affinidi_secrets_resolver` for key management. The function takes a JSON document and a secret (private key) as input, and outputs the generated proof and verification status. ```rust use affinidi_data_integrity::{ DataIntegrityProof, verification_proof::verify_data_with_public_key }; use affinidi_secrets_resolver::secrets::Secret; use serde_json::json; fn sign_and_verify_example() -> Result<(), Box> { // Document to sign let credential = json!({ "@context": ["https://www.w3.org/2018/credentials/v1"], "id": "https://example.com/credentials/3732", "type": ["VerifiableCredential"], "issuer": "did:example:issuer123", "issuanceDate": "2024-01-01T00:00:00Z", "credentialSubject": { "id": "did:example:subject456", "degree": { "type": "BachelorDegree", "name": "Bachelor of Science in Computer Science" } } }); // Create secret from multibase-encoded private key let pub_key = "z6MktDNePDZTvVcF5t6u362SsonU7HkuVFSMVCjSspQLDaBm"; let pri_key = "z3u2UQyiY96d7VQaua8yiaSyQxq5Z5W5Qkpz7o2H2pc9BkEa"; let secret = Secret::from_multibase( pri_key, Some(&format!("did:key:{pub_key}#{pub_key}")) )?; // Sign document let proof = DataIntegrityProof::sign_jcs_data( &credential, Some(vec!["https://www.w3.org/2018/credentials/v1".into()]) , &secret, None // auto-generate timestamp )?; println!("Proof type: {}", proof.type_); println!("Cryptosuite: {:?}", proof.cryptosuite); println!("Verification method: {}", proof.verification_method); println!("Proof purpose: {}", proof.proof_purpose); println!("Proof value: {:?}", proof.proof_value); println!("Created: {:?}", proof.created); // Verify signature let verification = verify_data_with_public_key( &credential, Some(vec!["https://www.w3.org/2018/credentials/v1".into()]) , &proof, secret.get_public_bytes() )?; println!("Verification successful: {}", verification.verified); // Create complete signed document let mut signed_credential = credential.clone(); signed_credential["proof"] = serde_json::to_value(&proof)?; println!("Signed credential:\n{}", serde_json::to_string_pretty(&signed_credential)?); Ok(()) } ```