- 2 StellarFlow backend instances running
- Both connected to same database
- Stellar TESTNET accounts set up
# Generate a random token (or use your own)
openssl rand -hex 32
# Output: a3f8e2d4c6b1f9e7a5d3c2b8f0e9d4c6# Price Update Configuration
MULTI_SIG_ENABLED=true
MULTI_SIG_REQUIRED_COUNT=2
REMOTE_ORACLE_SERVERS=http://server2.internal:3000
MULTI_SIG_AUTH_TOKEN=a3f8e2d4c6b1f9e7a5d3c2b8f0e9d4c6
ORACLE_SIGNER_NAME=oracle-primary
MULTI_SIG_POLL_INTERVAL_MS=30000# Price Update Configuration
MULTI_SIG_ENABLED=true
MULTI_SIG_REQUIRED_COUNT=2
REMOTE_ORACLE_SERVERS=http://server1.internal:3000
MULTI_SIG_AUTH_TOKEN=a3f8e2d4c6b1f9e7a5d3c2b8f0e9d4c6
ORACLE_SIGNER_NAME=oracle-secondary
MULTI_SIG_POLL_INTERVAL_MS=30000On each server:
npm run db:migrateThis creates the new tables:
MultiSigPriceMultiSigSignature
# Server 1
npm run start # or: npm run dev
# Server 2 (separate terminal/host)
npm run start # or: npm run devWatch logs for:
[MarketRateService] Multi-Sig mode ENABLED with 1 remote servers
[MultiSigSubmissionService] Started with 30000ms poll interval
🔐 Multi-Sig submission service started
# Request NGN price (will trigger multi-sig flow)
curl http://localhost:3000/api/market-rates/rate/NGN
# Response includes new fields:
{
"success": true,
"data": {
"currency": "NGN",
"rate": 1234.56,
"source": "CoinGecko",
"pendingMultiSig": true,
"multiSigPriceId": 123,
...
}
}curl http://localhost:3000/api/price-updates/multi-sig/pending
# Response:
{
"success": true,
"data": [
{
"id": 123,
"currency": "NGN",
"rate": 1234.56,
"status": "PENDING",
"collectedSignatures": 1, // local sign done
"requiredSignatures": 2,
"expiresAt": "2024-03-27T16:30:00Z"
}
]
}# Check status of price #123
curl http://localhost:3000/api/price-updates/multi-sig/123/status
# Watch for status to change from PENDING → APPROVED
# Should happen within seconds if servers communicate properly# Once APPROVED, check if signatures are ready
curl http://localhost:3000/api/price-updates/multi-sig/123/signatures
# Response shows all signatures
{
"success": true,
"data": {
"multiSigPriceId": 123,
"signatures": [
{
"signerPublicKey": "GXXXXXX1",
"signerName": "oracle-primary",
"signature": "3c5a7d2..."
},
{
"signerPublicKey": "GXXXXXX2",
"signerName": "oracle-secondary",
"signature": "8e1f4b9..."
}
]
}
}# After background job submits to Stellar (check OnChainPrice table)
# Price should appear in market rates with stellarTxHash set
SELECT * FROM "OnChainPrice"
WHERE currency = 'NGN'
ORDER BY "confirmedAt" DESC
LIMIT 1;
# Should see the multi-signed transactionCheck 1: Is multi-sig enabled on both servers?
# Server logs should show:
[MarketRateService] Multi-Sig mode ENABLED with 1 remote serversCheck 2: Can servers reach each other?
# From Server 1, test connectivity to Server 2:
curl http://server2.internal:3000/api/price-updates/multi-sig/signer-info
# Should return server 2's public keyCheck 3: Is auth token correct?
# Check error in logs:
[API] Signature creation failed: Unauthorized - invalid token
# Ensure MULTI_SIG_AUTH_TOKEN matches on both serversCheck database:
SELECT * FROM "MultiSigSignature" WHERE "multiSigPriceId" = 123;
# Should show 2 rows (one per server)
# If only 1 row, remote signature request failedCheck logs for:
[MarketRateService] ⚠️ Signature request failed for http://server2.internal:3000
[MarketRateService] ❌ Error requesting signature from http://server2.internal:3000
Check 1: Is submission service running?
# Logs should show:
[MultiSigSubmissionService] Started with 30000ms poll intervalCheck 2: Are there approved prices?
SELECT * FROM "MultiSigPrice" WHERE status = 'APPROVED';
# If empty, prices haven't been approved yet
# If exists, check if background job has errors in logsCheck 3: Stellar submission failures
[MultiSigSubmissionService] Failed to submit multi-sig price 123: ...
# Check network connectivity and account balance
- Update
.envwithMULTI_SIG_ENABLED=true - Configure
REMOTE_ORACLE_SERVERS - Run
prisma migrate - Restart services
- New prices will use multi-sig flow
- Update
.envwithMULTI_SIG_ENABLED=false - Restart services
- Existing pending multi-sig prices won't be submitted
- New prices will use direct submission
Before deploying to production:
- Use HTTPS for all server-to-server communication
- Implement rate limiting on signature endpoints
- Set up monitoring and alerting for:
- Pending multi-sig prices (should be low)
- Remote signature request failures
- Submission delays
- Test failover scenarios:
- Server down
- Network latency
- Stellar network congestion
- Document runbooks for common issues
- Schedule regular security audits
- Implement logging to centralized aggregation service
For issues, check:
/workspaces/stellarflow-backend/MULTI_SIG_GUIDE.md- Comprehensive guide/workspaces/stellarflow-backend/MULTI_SIG_ARCHITECTURE.md- Technical details- Application logs - Most issues visible in detailed logs
- Database tables - Inspect MultiSigPrice/MultiSigSignature records directly