This document describes the implementation of the multi-signature (multi-sig) certificate issuance system for StellarCert, a decentralized certificate management system built on the Stellar blockchain.
The multi-sig system consists of three main components:
- Smart Contract Layer - Soroban-based multi-sig contract
- Backend Service Layer - NestJS service for multi-sig operations
- Frontend Interface - React components for multi-sig management
The multi-sig smart contract provides the following functionality:
// Multi-sig configuration for an issuer
pub struct MultisigConfig {
pub threshold: u32, // Number of signatures required
pub signers: Vec<Address>, // List of authorized signers
pub max_signers: u32, // Maximum number of allowed signers
}
// Pending certificate issuance request
pub struct PendingRequest {
pub id: String,
pub issuer: Address,
pub recipient: Address,
pub metadata: String,
pub proposer: Address, // The address that initiated the request
pub approvals: Vec<Address>, // Addresses that have approved
pub rejections: Vec<Address>, // Addresses that have rejected
pub created_at: u64, // Timestamp when request was created
pub expires_at: u64, // Timestamp when request expires
pub status: RequestStatus,
}
// Status of a pending request
pub enum RequestStatus {
Pending,
Approved,
Rejected,
Expired,
Issued,
}
// Action taken by a signer
pub enum SignatureAction {
Approved,
Rejected,
}init_multisig_config(issuer: Address, threshold: u32, signers: Vec<Address>, max_signers: u32, admin: Address)
- Initializes the multi-sig configuration for an issuer
- Sets up the required number of signatures and authorized signers
update_multisig_config(issuer: Address, new_threshold: Option<u32>, new_signers: Option<Vec<Address>>, new_max_signers: Option<u32>)
- Updates the multi-sig configuration for an issuer
- Allows modification of signers and thresholds
propose_certificate(request_id: String, issuer: Address, recipient: Address, metadata: String, expiration_days: u32) -> PendingRequest
- Creates a new certificate issuance request
- Requires a unique request ID and expiration period
- Adds an approval to a pending certificate request
- Updates the request status when threshold is reached
- Adds a rejection to a pending certificate request
- May change status to Rejected if insufficient approvals remain possible
- Finalizes the certificate issuance after sufficient approvals
- Creates the actual certificate on the blockchain
- Cancels a pending request (only proposer can cancel)
- Checks if a request has exceeded its expiration time
The system implements the following multi-sig workflow:
-
Configuration Phase:
- Admin sets up issuer with threshold and authorized signers
- Threshold determines minimum signatures required
-
Proposal Phase:
- Certificate request is proposed with metadata
- Request has expiration time to prevent indefinite pending states
-
Approval Phase:
- Authorized signers can approve or reject requests
- Once threshold approvals are met, request becomes approved
-
Issuance Phase:
- Approved requests can be issued as certificates
- Rejected requests cannot be issued
- Authorization: Only authorized signers can approve/reject requests
- Threshold Enforcement: Minimum signatures required for approval
- Expiration: Requests automatically expire to prevent indefinite pending states
- Non-repudiation: All actions are recorded on-chain with timestamps
- Immutable History: Approval/rejection records stored permanently
The backend service provides a clean interface to the multi-sig smart contract:
initMultisigConfig(adminPublicKey: string, issuer: string, threshold: number, signers: string[], maxSigners: number)
- Creates and submits initialization transaction to Stellar
- Handles authentication and error management
proposeCertificate(requesterPublicKey: string, requestId: string, issuer: string, recipient: string, metadata: string, expirationDays: number)
- Submits a new certificate proposal to the blockchain
- Returns the pending request details
- Submits an approval for a pending request
- Updates request status based on threshold
- Submits a rejection for a pending request
- Updates request status accordingly
- Finalizes the certificate issuance for approved requests
- Creates the certificate on the blockchain
The service includes comprehensive error handling:
- Transaction failures
- Network connectivity issues
- Invalid parameters
- Authentication failures
- Authorization issues
The multi-sig functionality is integrated into the main dashboard:
- Configuration Panel - Set up multi-sig parameters
- Request Management - View and manage pending requests
- Action Buttons - Approve/reject/cancel requests
- Status Indicators - Visual cues for request status
Enhanced certificate creation with:
- Multi-sig approval requirements
- Request tracking
- Status updates
- Expiration warnings
POST /api/multisig/config/init- Initialize multi-sig config (Admin/Issuer)PUT /api/multisig/config/update/:issuer- Update multi-sig config (Admin/Issuer)POST /api/multisig/propose- Propose certificate (Admin/Issuer)POST /api/multisig/approve/:requestId- Approve request (Admin/Issuer)POST /api/multisig/reject/:requestId- Reject request (Admin/Issuer)POST /api/multisig/issue/:requestId- Issue approved certificate (Admin/Issuer)DELETE /api/multisig/cancel/:requestId- Cancel request (Admin/Issuer)
GET /api/multisig/config/:issuer- Get multi-sig configGET /api/multisig/request/:requestId- Get pending requestGET /api/multisig/requests/issuer/:issuer- Get requests for issuerGET /api/multisig/requests/signer/:signer- Get requests for signerGET /api/multisig/expired/:requestId- Check if request is expiredGET /api/multisig/status/:requestId- Get request status
- Minimum: 1 signature required
- Maximum: Up to number of authorized signers
- Flexible: Can be adjusted per issuer
- Dynamic addition/removal of authorized signers
- Maximum signer limits for governance
- Individual authorization per issuer
- Configurable expiration periods (days)
- Automatic status updates for expired requests
- Cleanup mechanisms for expired requests
- JWT-based authentication
- Role-based access control (Admin/Issuer/User)
- Stellar address verification
- On-chain storage ensures immutability
- Transaction-based operations with proper signing
- Audit trails for all actions
- Only authorized signers can approve/reject
- Only proposers can cancel requests
- Admin controls for configuration
- Efficient data structures for storage
- Minimal computation for approval checks
- Proper indexing for request tracking
- Connection pooling for Stellar RPC
- Asynchronous processing where appropriate
- Caching of frequently accessed configurations
- Loading states and skeleton screens
- Optimistic UI updates
- Efficient request filtering
Located in stellar-contracts/src/multisig_test.rs:
- Configuration initialization tests
- Approval/rejection functionality
- Threshold enforcement verification
- Expiration handling
- Error condition testing
- Authorization checks
- Service method testing
- Integration with Stellar network
- Error handling scenarios
- Authentication verification
// Initialize with 2-of-3 multi-sig
const response = await axios.post('/api/multisig/config/init', {
issuer: 'GB...ABC',
threshold: 2,
signers: ['GA...DEF', 'GC...GHI', 'GD...JKL'],
maxSigners: 5
});
console.log('Config initialized:', response.data.transactionHash);// Propose a certificate with 7-day expiration
const response = await axios.post('/api/multisig/propose', {
requestId: 'req-123',
issuer: 'GB...ABC',
recipient: 'GA...XYZ',
metadata: 'certificate metadata',
expirationDays: 7
});
console.log('Certificate proposed:', response.data);// Approve a pending request
const response = await axios.post('/api/multisig/approve/req-123');
console.log('Approval result:', response.data);// Get request details
const request = await axios.get('/api/multisig/request/req-123');
console.log('Request status:', request.data.status);
// Check if expired
const expired = await axios.get('/api/multisig/expired/req-123');
console.log('Is expired:', expired.data.expired);- Use strong threshold settings (e.g., 2-of-3, 3-of-5)
- Regularly rotate authorized signers
- Monitor pending requests for suspicious activity
- Set appropriate expiration periods
- Maintain backup signers for emergency situations
- Document approval workflows clearly
- Regularly review and update configurations
- Implement notification systems for pending requests
-
Insufficient Approvals
- Verify threshold settings match expectations
- Confirm authorized signers are correct
- Check for expired requests
-
Authorization Failures
- Verify signer addresses are authorized
- Check authentication tokens
- Confirm role permissions
-
Transaction Failures
- Check Stellar network connectivity
- Verify account balances
- Ensure proper transaction signing
- Check request status and approvals
- Verify multi-sig configuration
- Review transaction logs
- Test with sample data
- Validate authentication tokens
- Notification system for pending requests
- Delegation capabilities for signers
- Advanced analytics and reporting
- Integration with certificate expiration
- Automated cleanup of expired requests
- More efficient storage patterns
- Batch operations for multiple requests
- Enhanced caching mechanisms
- Database indexing optimizations
For issues or questions regarding the multi-sig implementation:
- Check the Stellar documentation
- Review the smart contract source code
- Examine backend service logs
- Test with the provided examples