Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
f0185fa
feat: implement multi-provider rate fetching system with test
sundayonah Feb 13, 2025
469f49f
feat(rates): enhance rate fetching with detailed metadata
sundayonah Feb 13, 2025
9d00340
test: modify test and move external_market file to utils
sundayonah Feb 14, 2025
7f72384
refactor(config): move API URLs to environment variables
sundayonah Feb 14, 2025
bd3c348
refactor(utils): overhaul external market rate fetching implementation
sundayonah Feb 14, 2025
31e3a32
refactor: (utils) replace FetchBitgetRate endpoint, remove /api/v1 fr…
sundayonah Mar 11, 2025
59e047c
fix: resolve rebase issues and reset branch to stable state
sundayonah Mar 20, 2025
fe0cdce
refactor(config): remove Bitget API keys from AuthConfiguration
sundayonah Mar 20, 2025
4864dea
Merge branch 'main' into biget-rates-market-refactor
sundayonah Mar 20, 2025
65c7c58
fix: update function name for fetching Quidax rates
sundayonah Mar 20, 2025
0a46c74
Merge branch 'main' into biget-rates-market-refactor
sundayonah Apr 3, 2025
b9116be
Merge branch 'main' into biget-rates-market-refactor
sundayonah Apr 20, 2025
984efba
Merge branch 'main' into biget-rates-market-refactor
chibie Apr 22, 2025
88f601e
feat: add HTTPS URL validation for host identifier in UpdateProviderP…
sundayonah Apr 10, 2025
4cba6d3
test: add vtest cases for HostIdentifier HTTPS validation
sundayonah Apr 10, 2025
3412c04
fix(tests): update HostIdentifier to use HTTPS and improve assertions…
sundayonah Apr 21, 2025
a0108f6
fix: setup repo
Atanda1 Mar 27, 2025
7959afd
docs: update README to specify Sender API usage with sandbox API Key …
chibie Mar 27, 2025
fda12a3
fix: update SQL dump and user operation logic
chibie Mar 28, 2025
ae9148b
fix: update SQL dump for provider profile host identifier
chibie Mar 28, 2025
3fabc7f
chore: remove unnecessary print statements
chibie Apr 22, 2025
cd9feb2
fix: Handle amounts below minimum bucket
sundayonah Mar 15, 2025
bf6c876
test: Add unit tests for minimum bucket handling
sundayonah Mar 15, 2025
a0896a6
fix: remove duplicate token import
sundayonah Mar 15, 2025
dd14d9b
feat: modify provision bucket call to capture unused isLessThanMin an…
sundayonah Mar 18, 2025
d0ba090
fix(indexer): improve error handling in CreateLockPaymentOrder and en…
chibie Apr 21, 2025
b87ad09
fix(indexer): enhance error message in CreateLockPaymentOrder to incl…
chibie Apr 24, 2025
f0e4e88
fix(indexer): change error handling for token fetch in CreateLockPaym…
chibie Apr 24, 2025
61beac8
Provider Token Rate Slippage Configuration (#415)
sundayonah Apr 25, 2025
7161a65
feat: enhance logging with contextual information across services (#459)
onahprosper Apr 25, 2025
4823053
refactor(logging): standardize error logging format and enhance conte…
chibie Apr 28, 2025
6893643
refactor(profile): update provider rate calculation logic in profile …
chibie Apr 29, 2025
c966593
refactor(logging): standardize error logging format across indexer an…
chibie Apr 30, 2025
c5bdb59
refactor(indexer, priority_queue, order): enforce settlement address …
chibie May 3, 2025
2007b52
fix(profile): handle rate slippage assignment in provider profile upd…
chibie May 3, 2025
f4a9137
fix(priority_queue): change error handling in matchRate to continue o…
chibie May 3, 2025
eed9fb0
refactor(provider): improve stats calculation and error handling in P…
chibie May 4, 2025
4f8bcb3
refactor(provider): streamline stats calculation for USD and local st…
chibie May 4, 2025
8a2baff
refactor(provider): update stats query to filter by USD token for acc…
chibie May 4, 2025
aa985f7
refactor(provider): simplify total fiat volume calculation in Stats m…
chibie May 4, 2025
e0aa4c8
refactor(sender, indexer): enhance institution retrieval logic and im…
chibie May 4, 2025
eae210f
refactor(provider): enhance Stats method to filter out USD token and …
chibie May 4, 2025
eca9a66
refactor(sender): remove debug print statements from Stats method for…
chibie May 4, 2025
861a467
feat(migrations): add TZS and UGX bank institutions
sundayonah Apr 25, 2025
e5702f9
fix: remove provision buckets from UGX and TZS bank institution migra…
sundayonah May 2, 2025
21525d6
refactor(profile): update profile test and API response messages for …
chibie May 5, 2025
0a8b789
refactor(indexer): commented out the split lock payment order functio…
chibie May 5, 2025
e198963
chore(migrations): updated versioning of TZS and UGX bank institution…
chibie May 5, 2025
94ee460
fix: timezone error in Slack notifications with additional test cases
sundayonah May 5, 2025
4a7dd78
feat: support ~all countries in KYC verification (#457)
sundayonah May 9, 2025
5659d9c
refactor: update KYC verification structure and remove deprecated files
chibie May 10, 2025
0166b0a
feat: add metadata field to payment order and recipient models (#467)
chibie May 11, 2025
d3f80fd
feat(ci): add Atlas database migrations workflow (#468)
chibie May 11, 2025
674b9e2
refactor: enhance error logging in FulfillOrder and CancelOrder contr…
onahprosper May 11, 2025
99575f2
refactor(utils): overhaul external market rate fetching implementation
sundayonah Feb 14, 2025
ba44653
fix: resolve rebase issues and reset branch to stable state
sundayonah Mar 20, 2025
5257afa
fix: remove duplicate type definitions
sundayonah May 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ DEBUG=True
ALLOWED_HOSTS=0.0.0.0
SERVER_HOST=0.0.0.0
SERVER_PORT=8000
SERVER_URL=http://localhost:8000
JWT_ACCESS_LIFESPAN=15
JWT_REFRESH_LIFESPAN=10080
HMAC_TIMESTAMP_AGE=5
ENVIRONMENT=local # local, staging, production
SENTRY_DSN=
HOST_DOMAIN=http://localhost:8000

# Database Config
DB_NAME=paycrest
Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/atlas-migrate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Atlas Database Migrations

on:
push:
branches:
- main
- stable

jobs:
migrate:
runs-on: ubuntu-latest
environment: ${{ github.ref == 'refs/heads/main' && 'staging' || 'production' }}
steps:
- uses: actions/checkout@v4

- name: Install Atlas
run: |
curl -sSf https://atlasgo.sh | sh
echo "$HOME/.atlas/bin" >> $GITHUB_PATH

- name: Run Migrations
run: |
atlas migrate apply \
--dir "file://ent/migrate/migrations" \
--url "${{ secrets.DB_URL }}"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ docker-compose up -d
chmod +x scripts/import_db.sh

# run the script to seed db with sample configured sender & provider profile
./scripts/import_db.sh
./scripts/import_db.sh -h localhost
```

3. Run our sandbox provision node and connect it to your local aggregator by following the [instructions here](https://paycrest.notion.site/run-sandbox-provision-node)

Here, we’d make use of a demo provision node and connect it to our local aggregator

That's it! The server will now be running at http://localhost:8000. You can use an API testing tool like Postman or cURL to interact with the API.
That's it! The server will now be running at http://localhost:8000. You can use an API testing tool like Postman or cURL to interact with the Sender API using the sandbox API Key `11f93de0-d304-4498-8b7b-6cecbc5b2dd8`.


## Usage
Expand Down
Binary file added aggregator
Binary file not shown.
2 changes: 2 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ type Configuration struct {
func SetupConfig() error {
var configuration *Configuration

viper.AddConfigPath("../../../..")
viper.AddConfigPath("../../..")
viper.AddConfigPath("../..")
viper.AddConfigPath("..")
viper.AddConfigPath(".")
Expand Down
5 changes: 3 additions & 2 deletions config/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type ServerConfiguration struct {
AllowedHosts string
Environment string
SentryDSN string
HostDomain string
ServerURL string
RateLimitUnauthenticated int
RateLimitAuthenticated int
SlackWebhookURL string
Expand All @@ -33,6 +33,7 @@ func ServerConfig() *ServerConfiguration {
viper.SetDefault("RATE_LIMIT_UNAUTHENTICATED", 5)
viper.SetDefault("RATE_LIMIT_AUTHENTICATED", 100)
viper.SetDefault("SLACK_WEBHOOK_URL", "")
viper.SetDefault("SERVER_URL", "")

return &ServerConfiguration{
Debug: viper.GetBool("DEBUG"),
Expand All @@ -42,7 +43,7 @@ func ServerConfig() *ServerConfiguration {
AllowedHosts: viper.GetString("ALLOWED_HOSTS"),
Environment: viper.GetString("ENVIRONMENT"),
SentryDSN: viper.GetString("SENTRY_DSN"),
HostDomain: viper.GetString("HOST_DOMAIN"),
ServerURL: viper.GetString("SERVER_URL"),
RateLimitUnauthenticated: viper.GetInt("RATE_LIMIT_UNAUTHENTICATED"),
RateLimitAuthenticated: viper.GetInt("RATE_LIMIT_AUTHENTICATED"),
SlackWebhookURL: viper.GetString("SLACK_WEBHOOK_URL"),
Expand Down
39 changes: 28 additions & 11 deletions controllers/accounts/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (ctrl *AuthController) Register(ctx *gin.Context) {

tx, err := db.Client.Tx(ctx)
if err != nil {
logger.Errorf("error: %v", err)
logger.Errorf("Error: Failed to create new user: %v", err)
u.APIResponse(ctx, http.StatusInternalServerError, "error",
"Failed to create new user", nil)
return
Expand Down Expand Up @@ -99,7 +99,7 @@ func (ctrl *AuthController) Register(ctx *gin.Context) {
user, err := userCreate.Save(ctx)
if err != nil {
_ = tx.Rollback()
logger.Errorf("error: %v", err)
logger.Errorf("Error: Failed to save new user: %v", err)
u.APIResponse(ctx, http.StatusInternalServerError, "error",
"Failed to create new user", nil)
return
Expand All @@ -113,13 +113,16 @@ func (ctrl *AuthController) Register(ctx *gin.Context) {
SetExpiryAt(time.Now().Add(authConf.PasswordResetLifespan)).
Save(ctx)
if err != nil {
logger.Errorf("error: %v", err)
logger.Errorf("Error: Failed to create verification token: %v", err)
}

if serverConf.Environment == "production" {
if verificationToken != nil {
if _, err := ctrl.emailService.SendVerificationEmail(ctx, verificationToken.Token, user.Email, user.FirstName); err != nil {
logger.Errorf("error: %v", err)
logger.WithFields(logger.Fields{
"Error": fmt.Sprintf("%v", err),
"UserID": user.ID,
}).Errorf("Failed to send verification email")
}
}
}
Expand Down Expand Up @@ -180,7 +183,10 @@ func (ctrl *AuthController) Register(ctx *gin.Context) {
Save(ctx)
if err != nil {
_ = tx.Rollback()
logger.Errorf("error: %v", err)
logger.WithFields(logger.Fields{
"Error": fmt.Sprintf("%v", err),
"UserID": user.ID,
}).Errorf("Failed to create provider profile")
u.APIResponse(ctx, http.StatusInternalServerError, "error",
"Failed to create new user", nil)
return
Expand All @@ -190,7 +196,11 @@ func (ctrl *AuthController) Register(ctx *gin.Context) {
_, _, err = ctrl.apiKeyService.GenerateAPIKey(ctx, tx, nil, provider)
if err != nil {
_ = tx.Rollback()
logger.Errorf("error: %v", err)
logger.WithFields(logger.Fields{
"Error": fmt.Sprintf("%v", err),
"UserID": user.ID,
"ProviderID": provider.ID,
}).Errorf("Failed to create API key for provider")
u.APIResponse(ctx, http.StatusInternalServerError, "error",
"Failed to create new user", nil)
return
Expand All @@ -205,7 +215,10 @@ func (ctrl *AuthController) Register(ctx *gin.Context) {
Save(ctx)
if err != nil {
_ = tx.Rollback()
logger.Errorf("error: %v", err)
logger.WithFields(logger.Fields{
"Error": fmt.Sprintf("%v", err),
"UserID": user.ID,
}).Errorf("Failed to create sender profile")
u.APIResponse(ctx, http.StatusInternalServerError, "error",
"Failed to create new user", nil)
return
Expand All @@ -215,15 +228,19 @@ func (ctrl *AuthController) Register(ctx *gin.Context) {
_, _, err = ctrl.apiKeyService.GenerateAPIKey(ctx, tx, sender, nil)
if err != nil {
_ = tx.Rollback()
logger.Errorf("error: %v", err)
logger.WithFields(logger.Fields{
"Error": fmt.Sprintf("%v", err),
"UserID": user.ID,
"SenderID": sender.ID,
}).Errorf("Failed to create API key for sender")
u.APIResponse(ctx, http.StatusInternalServerError, "error",
"Failed to create new user", nil)
return
}
}

if err := tx.Commit(); err != nil {
logger.Errorf("error: %v", err)
logger.Errorf("Error: Failed to commit transaction: %v", err)
u.APIResponse(ctx, http.StatusInternalServerError, "error",
"Failed to create new user", nil)
return
Expand All @@ -246,7 +263,7 @@ func (ctrl *AuthController) Register(ctx *gin.Context) {
// Send Slack notification
if serverConf.Environment == "production" {
if err := ctrl.slackService.SendUserSignupNotification(user, scopes, providerCurrencies); err != nil {
logger.Errorf("failed to send Slack notification: %v", err)
logger.Errorf("Failed to send Slack notification: %v", err)
}
}
}
Expand Down Expand Up @@ -296,7 +313,7 @@ func (ctrl *AuthController) Login(ctx *gin.Context) {
accessToken, refreshToken, err := token.GeneratePairJWT(user.ID.String(), user.Scope)

if err != nil {
logger.Errorf("error: %v", err)
logger.Errorf("Error : Failed to create token pair during login: %v", err)
u.APIResponse(ctx, http.StatusInternalServerError, "error",
"Failed to create token pair", nil,
)
Expand Down
Loading
Loading