#!/bin/bash # Source the environment with DIDs if [ ! -f .generated/test-env.sh ]; then echo "Error: No test environment found. Run run-deeplink-tests.sh first" exit 1 fi source .generated/test-env.sh # Verify we have the required DIDs if [ -z "$CONTACT1_DID" ] || [ -z "$CONTACT1_KEY" ]; then echo "Error: Contact1 DID info not found in environment" exit 1 fi # Use CONTACT1 as the issuer since we know it's registered REGISTERED_DID="$CONTACT1_DID" REGISTERED_KEY="$CONTACT1_KEY" # Default API URL (can be overridden by environment) API_URL=${ENDORSER_API_URL:-"https://test-api.endorser.ch/api/v2/claim"} # Function to sign a message using ES256K sign_message() { local message="$1" local private_key="$2" local tmpdir # Create temporary directory tmpdir=$(mktemp -d) trap 'rm -rf "$tmpdir"' EXIT # Debug output echo "Signing message: $message" >&2 echo "Using private key: $private_key" >&2 # Hash the message with SHA-256 echo -n "$message" | openssl dgst -sha256 -binary > "$tmpdir/message.hash" # Sign the hash directly using the private key # This avoids OpenSSL's PEM format issues with secp256k1 python3 -c " import sys from eth_keys import keys import hashlib # Read message hash with open('$tmpdir/message.hash', 'rb') as f: message_hash = f.read() # Create private key object private_key_bytes = bytes.fromhex('$private_key') private_key = keys.PrivateKey(private_key_bytes) # Sign the message hash signature = private_key.sign_msg_hash(message_hash) # Output R and S values as hex print(f'{hex(signature.r)[2:]:0>64}') print(f'{hex(signature.s)[2:]:0>64}') " > "$tmpdir/signature.txt" # Read R and S values { read -r r_val; read -r s_val; } < "$tmpdir/signature.txt" # Debug R and S values echo "R value: $r_val" >&2 echo "S value: $s_val" >&2 # Concatenate R+S and convert to base64url echo -n "${r_val}${s_val}" | xxd -r -p | base64 -w 0 | tr '/+' '_-' | tr -d '=' } # Create a test claim payload create_claim_payload() { local issuer_did="$1" # Create a test claim matching the app's structure cat << EOF { "@context": "https://schema.org", "@type": "TestClaim", "identifier": "test-claim-$(date +%s)", "name": "Test Claim", "description": "Generated test claim", "agent": { "did": "$issuer_did" } } EOF } # Create and sign JWT create_jwt() { local claim="$1" local issuer_did="$2" local private_key="$3" # Create header and payload matching the app's structure local header='{"typ":"JWT","alg":"ES256K"}' local payload="{\"iat\":$(date +%s),\"exp\":$(($(date +%s) + 300)),\"iss\":\"$issuer_did\",\"vc\":{\"@context\":[\"https://www.w3.org/2018/credentials/v1\"],\"type\":[\"VerifiableCredential\"],\"credentialSubject\":$claim}}" # Base64url encode header and payload local header_b64=$(echo -n "$header" | base64 -w 0 | tr '/+' '_-' | tr -d '=') local payload_b64=$(echo -n "$payload" | base64 -w 0 | tr '/+' '_-' | tr -d '=') # Create message to sign local message="$header_b64.$payload_b64" # Sign message using eth_keys (same as did-jwt library) local signature=$(python3 -c " from eth_keys import keys import hashlib # Create private key object private_key_bytes = bytes.fromhex('$private_key') private_key = keys.PrivateKey(private_key_bytes) # Hash the message message_hash = hashlib.sha256('$message'.encode()).digest() # Sign using ES256K signature = private_key.sign_msg_hash(message_hash) # Format as R+S concatenated and base64url encoded import base64 signature_bytes = signature.r.to_bytes(32, 'big') + signature.s.to_bytes(32, 'big') print(base64.urlsafe_b64encode(signature_bytes).decode().rstrip('=')) ") # Return complete JWT echo "$message.$signature" } # Function to register claim with API register_claim() { local jwt="$1" echo "Registering claim with API..." response=$(curl -s -X POST "$API_URL" \ -H "Content-Type: application/json" \ -d "{\"jwtEncoded\":\"$jwt\"}") # Check response if echo "$response" | jq -e '.success' >/dev/null 2>&1; then echo "Registration successful!" echo "Response:" echo "$response" | jq '.' return 0 else echo "Registration failed!" echo "Error: $(echo "$response" | jq -r '.error.message // empty')" echo "Full response:" echo "$response" | jq '.' || echo "$response" return 1 fi } # Main execution echo "Generating test claim..." # Create claim payload claim=$(create_claim_payload "$REGISTERED_DID") echo "Claim payload:" echo "$claim" | jq '.' # Create and sign JWT echo "Generating signed JWT..." jwt=$(create_jwt "$claim" "$REGISTERED_DID" "$REGISTERED_KEY") # Output just the JWT for piping echo "$jwt" # Register the claim register_claim "$jwt"