This guide outlines the key changes and migration steps for upgrading to the latest version of the SwiftRemit contract, focusing on deterministic settlement hashes and batch settlement features.
The contract now utilizes a deterministic hashing mechanism for all settlements. This allows off-chain systems to pre-calculate settlement IDs and verify on-chain state with cryptographic certainty.
- Internal Logic: Uses SHA-256 over canonicalized fields (sender, agent, amount, fee, expiry).
- Public API:
compute_settlement_hash(env, remittance_id)allows external callers to retrieve the expected hash for any pending remittance.
To optimize gas costs and reduce token transfer overhead, the contract now supports batch settlement of multiple remittances with netting logic.
- Net Settlement: Offsets opposing flows between the same two parties within a single batch.
- Max Batch Size: 50 remittances per transaction.
- Function:
batch_settle_with_netting(env, entries).
The create_remittance method has been simplified. The default_currency and default_country arguments have been removed in favor of a simpler 4-argument signature (plus Env).
Old Signature:
pub fn create_remittance(
env: Env,
sender: Address,
agent: Address,
amount: i128,
currency: String,
country: String,
expiry: Option<u64>,
) -> Result<u64, ContractError>New Signature:
pub fn create_remittance(
env: Env,
sender: Address,
agent: Address,
amount: i128,
expiry: Option<u64>,
) -> Result<u64, ContractError>The authorize_remittance function has been removed. Payout confirmation is now handled directly via confirm_payout, which requires require_auth from the agent and the Settler role.
- Update Clients: Update all off-chain clients to use the new
create_remittancesignature. - Assign Roles: Ensure all authorized agents are assigned the
Role::Settlerusing theassign_rolefunction. - Verify Hashes: Use
compute_settlement_hashto reconcile existing pending transactions if necessary.
This guide helps existing developers migrate to the new environment-based configuration system.
The SwiftRemit codebase has been refactored to eliminate hardcoded configuration values and use environment variables instead. This improves:
- Maintainability: Configuration is centralized in one place
- Flexibility: Easy to configure for different environments
- Security: Secrets are no longer in code
- Deployment: Simplified deployment to multiple environments
Copy the example environment file to create your local configuration:
cp .env.example .envEdit the .env file and provide values for required variables:
# Required for client operations
SWIFTREMIT_CONTRACT_ID=your_contract_id_here
USDC_TOKEN_ID=your_usdc_token_id_hereIf you were previously using hardcoded values in examples/client-example.js, copy those values to your .env file.
Most optional settings have sensible defaults, but you can customize them:
# Network configuration
NETWORK=testnet
RPC_URL=https://soroban-testnet.stellar.org:443
# Fee configuration
DEFAULT_FEE_BPS=250
# Transaction configuration
TRANSACTION_FEE=100000
TRANSACTION_TIMEOUT=30
POLL_INTERVAL_MS=1000
# Token configuration
USDC_DECIMALS=7
# Deployment configuration
DEPLOYER_IDENTITY=deployer
INITIAL_FEE_BPS=250
# Feature flags
ENABLE_DEBUG_LOG=trueTest that your configuration loads correctly:
cd examples
node config.jsIf there are no errors, your configuration is valid.
No changes needed! The client code now automatically loads configuration from .env:
cd examples
node client-example.jsDeployment scripts now read from environment variables. You can either:
Option A: Use environment variables
export NETWORK=testnet
export INITIAL_FEE_BPS=250
./deploy.shOption B: Use CLI overrides
./deploy.sh testnetOption C: Set in .env file
# In .env
NETWORK=testnet
INITIAL_FEE_BPS=250
# Then run
./deploy.shBefore:
const CONFIG = {
network: 'testnet',
rpcUrl: 'https://soroban-testnet.stellar.org:443',
contractId: 'CAAAA...',
// ... hardcoded values
};After:
const config = require('./config');
// Use config.network, config.rpcUrl, config.contractId, etc.Before (deploy.sh):
NETWORK="testnet"
DEPLOYER="deployer"
# ... hardcoded valuesAfter (deploy.sh):
NETWORK=${NETWORK:-testnet}
DEPLOYER=${DEPLOYER_IDENTITY:-deployer}
INITIAL_FEE_BPS=${INITIAL_FEE_BPS:-250}
# ... reads from environment with defaultsThe Rust contract code remains largely unchanged. Constants like MAX_FEE_BPS and FEE_DIVISOR are still hardcoded in the contract for on-chain consistency, but they are now documented with comments explaining their purpose.
If you were using the system normally, there are no breaking changes. The refactoring maintains backward compatibility:
- All existing functionality works the same way
- Default values match previous hardcoded values
- Tests continue to pass
If you previously modified hardcoded values in the code, you now need to set them via environment variables instead:
- Identify the values you changed
- Add them to your
.envfile - Remove your code modifications
Problem: You're missing a required configuration value
Solution: Add the variable to your .env file. Check .env.example for the complete list of variables.
Problem: A configuration value is invalid (wrong type, out of range, etc.)
Solution: Check the error message for details. Common issues:
- Fee values must be 0-10000
- URLs must be HTTPS
- Network must be 'testnet' or 'mainnet'
- Numeric values must be valid numbers
Problem: Client code can't load configuration
Solution:
- Ensure
.envfile exists in project root - Ensure you're running from the correct directory
- Check that
dotenvpackage is installed:npm install
Problem: Deployment script uses defaults instead of your values
Solution:
- Export variables before running script:
export NETWORK=testnet - Or set them in
.envfile - Or use CLI overrides:
./deploy.sh testnet
If you encounter issues during migration:
- Check the Configuration Guide for detailed documentation
- Review error messages carefully - they indicate which variable is problematic
- Verify your
.envfile against.env.example - Ensure all required variables are set
- Check that values are within valid ranges
After migration, you'll benefit from:
- Easier Environment Management: Switch between testnet and mainnet by changing one variable
- Better Security: Secrets are in
.env(gitignored) instead of code - Simplified Deployment: Deploy to multiple environments without code changes
- Centralized Configuration: All settings in one place
- Validation: Configuration errors caught at startup, not runtime
- Documentation: Clear documentation of all configuration options
After completing migration:
- Delete any local modifications to hardcoded values
- Commit your updated code (but not
.env!) - Share
.env.examplewith your team - Update your deployment documentation
- Consider setting up environment-specific
.envfiles (.env.testnet,.env.mainnet)