#!/bin/bash # Git OpenTimestamp Pre-Commit Backfill Hook (Node.js version) # Requires: @opentimestamps/ots (npm install) # Note: Node version only generates local proofs, no calendar submission set -e OUTPUT_DIR=".ots" STATUS_CACHE="$OUTPUT_DIR/.attestation-cache" mkdir -p "$OUTPUT_DIR" # Initialize cache if [ ! -f "$STATUS_CACHE" ]; then echo "# Format: commit-hash:status:timestamp" > "$STATUS_CACHE" fi get_cached_status() { local commit="$1" local cache_line=$(grep "^$commit:" "$STATUS_CACHE" 2>/dev/null | tail -1) if [ -n "$cache_line" ]; then local status=$(echo "$cache_line" | cut -d: -f2) local timestamp=$(echo "$cache_line" | cut -d: -f3) local now=$(date +%s) if [ "$((now - timestamp))" -lt 3600 ]; then echo "$status" return 0 fi fi return 1 } cache_status() { local commit="$1" local status="$2" echo "$commit:$status:$(date +%s)" >> "$STATUS_CACHE" } generate_proof_node() { local hash="$1" local output="$2" node -e " const ots = require('@opentimestamps/ots'); const fs = require('fs'); const hash = '$hash'; const output = '$output'; const hashBuffer = Buffer.from(hash, 'hex'); ots.Timestamp.hash(hashBuffer).then(timestamp => { const proof = { hash: hash, timestamp: new Date().toISOString(), status: 'pending' }; fs.writeFileSync(output, JSON.stringify(proof, null, 2)); }).catch(err => { console.error('Error:', err); process.exit(1); }); " } echo "[ots-node] Backfilling proofs (local only, no calendar)..." COMMITS=$(git rev-list --reverse HEAD) TOTAL=$(echo "$COMMITS" | wc -l) CURRENT=0 UPDATED=0 for COMMIT in $COMMITS; do CURRENT=$((CURRENT + 1)) PROOF_FILE="$OUTPUT_DIR/${COMMIT}.ots" if [ $CURRENT -le 3 ] || [ $CURRENT -eq $TOTAL ]; then echo "[ots-node] Processing $CURRENT/$TOTAL: ${COMMIT:0:8}" elif [ $CURRENT -eq 4 ]; then echo "[ots-node] ... processing remaining ..." fi if [ -f "$PROOF_FILE" ]; then # Node version doesn't support upgrade, just check cache CACHED_STATUS=$(get_cached_status "$COMMIT" || echo "") [ "$CACHED_STATUS" = "attested" ] && continue # Mark as pending (node can't attest) cache_status "$COMMIT" "pending" else if generate_proof_node "$COMMIT" "$PROOF_FILE"; then cache_status "$COMMIT" "pending" UPDATED=$((UPDATED + 1)) fi fi done # Update latest proof LATEST_COMMIT=$(git rev-parse HEAD) [ -f "$OUTPUT_DIR/${LATEST_COMMIT}.ots" ] && cp "$OUTPUT_DIR/${LATEST_COMMIT}.ots" "$OUTPUT_DIR/proof.ots" # Save commit chain rm -f "$OUTPUT_DIR/commit-chain.txt" git rev-list HEAD | while read COMMIT; do PREV=$(git rev-parse ${COMMIT}^1 2>/dev/null || echo "") [ -n "$PREV" ] && echo "$COMMIT:$PREV" >> "$OUTPUT_DIR/commit-chain.txt" done echo "[ots-node] Backfill complete: $UPDATED generated (local proofs only)"