Skip to content

Commit

Permalink
chore: use sync mutex for concurrency support
Browse files Browse the repository at this point in the history
  • Loading branch information
im-adithya committed Jan 22, 2024
1 parent 3fad688 commit dad7b90
Showing 1 changed file with 51 additions and 38 deletions.
89 changes: 51 additions & 38 deletions alby.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"net/http"
"net/url"
"strconv"
"sync"
"time"

"github.com/labstack/echo-contrib/session"
"github.com/labstack/echo/v4"
Expand All @@ -18,10 +20,11 @@ import (
)

type AlbyOAuthService struct {
cfg *Config
oauthConf *oauth2.Config
db *gorm.DB
Logger *logrus.Logger
cfg *Config
oauthConf *oauth2.Config
db *gorm.DB
Logger *logrus.Logger
tokenMutex sync.Mutex
}

func NewAlbyOauthService(svc *Service, e *echo.Echo) (result *AlbyOAuthService, err error) {
Expand Down Expand Up @@ -52,12 +55,22 @@ func NewAlbyOauthService(svc *Service, e *echo.Echo) (result *AlbyOAuthService,
}

func (svc *AlbyOAuthService) FetchUserToken(ctx context.Context, app App) (token *oauth2.Token, err error) {
user := app.User
tok, err := svc.oauthConf.TokenSource(ctx, &oauth2.Token{
svc.tokenMutex.Lock()
defer svc.tokenMutex.Unlock()

user := User{}
err = svc.db.First(&user, &User{ID: app.UserId}).Error
currentToken := &oauth2.Token{
AccessToken: user.AccessToken,
RefreshToken: user.RefreshToken,
Expiry: user.Expiry,
}).Token()
}

if user.Expiry.After(time.Now()) {
return currentToken, nil
}

tok, err := svc.oauthConf.TokenSource(ctx, currentToken).Token()
if err != nil {
svc.Logger.WithFields(logrus.Fields{
"senderPubkey": app.NostrPubkey,
Expand All @@ -82,7 +95,7 @@ func (svc *AlbyOAuthService) FetchUserToken(ctx context.Context, app App) (token
func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey string, amount int64, description string, descriptionHash string, expiry int64) (transaction *Nip47Transaction, err error) {
// TODO: move to a shared function
app := App{}
err = svc.db.Preload("User").First(&app, &App{
err = svc.db.First(&app, &App{
NostrPubkey: senderPubkey,
}).Error
if err != nil {
Expand Down Expand Up @@ -117,7 +130,7 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin
"descriptionHash": descriptionHash,
"expiry": expiry,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
}).Info("Processing make invoice request")
tok, err := svc.FetchUserToken(ctx, app)
if err != nil {
Expand Down Expand Up @@ -154,7 +167,7 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin
"descriptionHash": descriptionHash,
"expiry": expiry,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
}).Errorf("Failed to make invoice: %v", err)
return nil, err
}
Expand All @@ -172,7 +185,7 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin
"descriptionHash": descriptionHash,
"expiry": expiry,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"paymentRequest": responsePayload.PaymentRequest,
"paymentHash": responsePayload.PaymentHash,
}).Info("Make invoice successful")
Expand All @@ -190,7 +203,7 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin
"descriptionHash": descriptionHash,
"expiry": expiry,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"APIHttpStatus": resp.StatusCode,
}).Errorf("Make invoice failed %s", string(errorPayload.Message))
return nil, errors.New(errorPayload.Message)
Expand All @@ -199,7 +212,7 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin
func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey string, paymentHash string) (transaction *Nip47Transaction, err error) {
// TODO: move to a shared function
app := App{}
err = svc.db.Preload("User").First(&app, &App{
err = svc.db.First(&app, &App{
NostrPubkey: senderPubkey,
}).Error
if err != nil {
Expand All @@ -214,7 +227,7 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str
"senderPubkey": senderPubkey,
"paymentHash": paymentHash,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
}).Info("Processing lookup invoice request")
tok, err := svc.FetchUserToken(ctx, app)
if err != nil {
Expand All @@ -240,7 +253,7 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str
"senderPubkey": senderPubkey,
"paymentHash": paymentHash,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
}).Errorf("Failed to lookup invoice: %v", err)
return nil, err
}
Expand All @@ -255,7 +268,7 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str
"senderPubkey": senderPubkey,
"paymentHash": paymentHash,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"paymentRequest": responsePayload.PaymentRequest,
"settled": responsePayload.Settled,
}).Info("Lookup invoice successful")
Expand All @@ -270,15 +283,15 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str
"senderPubkey": senderPubkey,
"paymentHash": paymentHash,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"APIHttpStatus": resp.StatusCode,
}).Errorf("Lookup invoice failed %s", string(errorPayload.Message))
return nil, errors.New(errorPayload.Message)
}

func (svc *AlbyOAuthService) GetInfo(ctx context.Context, senderPubkey string) (info *NodeInfo, err error) {
app := App{}
err = svc.db.Preload("User").First(&app, &App{
err = svc.db.First(&app, &App{
NostrPubkey: senderPubkey,
}).Error
if err != nil {
Expand All @@ -291,7 +304,7 @@ func (svc *AlbyOAuthService) GetInfo(ctx context.Context, senderPubkey string) (
svc.Logger.WithFields(logrus.Fields{
"senderPubkey": senderPubkey,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
}).Info("Info fetch successful")
return &NodeInfo{
Alias: "getalby.com",
Expand All @@ -305,7 +318,7 @@ func (svc *AlbyOAuthService) GetInfo(ctx context.Context, senderPubkey string) (

func (svc *AlbyOAuthService) GetBalance(ctx context.Context, senderPubkey string) (balance int64, err error) {
app := App{}
err = svc.db.Preload("User").First(&app, &App{
err = svc.db.First(&app, &App{
NostrPubkey: senderPubkey,
}).Error
if err != nil {
Expand Down Expand Up @@ -333,7 +346,7 @@ func (svc *AlbyOAuthService) GetBalance(ctx context.Context, senderPubkey string
svc.Logger.WithFields(logrus.Fields{
"senderPubkey": senderPubkey,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
}).Errorf("Failed to fetch balance: %v", err)
return 0, err
}
Expand All @@ -347,7 +360,7 @@ func (svc *AlbyOAuthService) GetBalance(ctx context.Context, senderPubkey string
svc.Logger.WithFields(logrus.Fields{
"senderPubkey": senderPubkey,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
}).Info("Balance fetch successful")
return int64(responsePayload.Balance), nil
}
Expand All @@ -357,15 +370,15 @@ func (svc *AlbyOAuthService) GetBalance(ctx context.Context, senderPubkey string
svc.Logger.WithFields(logrus.Fields{
"senderPubkey": senderPubkey,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"APIHttpStatus": resp.StatusCode,
}).Errorf("Balance fetch failed %s", string(errorPayload.Message))
return 0, errors.New(errorPayload.Message)
}

func (svc *AlbyOAuthService) ListTransactions(ctx context.Context, senderPubkey string, from, until, limit, offset uint64, unpaid bool, invoiceType string) (transactions []Nip47Transaction, err error) {
app := App{}
err = svc.db.Preload("User").First(&app, &App{
err = svc.db.First(&app, &App{
NostrPubkey: senderPubkey,
}).Error
if err != nil {
Expand Down Expand Up @@ -419,7 +432,7 @@ func (svc *AlbyOAuthService) ListTransactions(ctx context.Context, senderPubkey
svc.Logger.WithFields(logrus.Fields{
"senderPubkey": senderPubkey,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"requestUrl": requestUrl,
}).Errorf("Failed to fetch invoices: %v", err)
return nil, err
Expand All @@ -433,7 +446,7 @@ func (svc *AlbyOAuthService) ListTransactions(ctx context.Context, senderPubkey
svc.Logger.WithFields(logrus.Fields{
"senderPubkey": senderPubkey,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"requestUrl": requestUrl,
}).Errorf("Failed to decode invoices: %v", err)
return nil, err
Expand All @@ -449,7 +462,7 @@ func (svc *AlbyOAuthService) ListTransactions(ctx context.Context, senderPubkey
svc.Logger.WithFields(logrus.Fields{
"senderPubkey": senderPubkey,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"requestUrl": requestUrl,
}).Info("List transactions successful")
return transactions, nil
Expand All @@ -460,7 +473,7 @@ func (svc *AlbyOAuthService) ListTransactions(ctx context.Context, senderPubkey
svc.Logger.WithFields(logrus.Fields{
"senderPubkey": senderPubkey,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"APIHttpStatus": resp.StatusCode,
"requestUrl": requestUrl,
}).Errorf("List transactions failed %s", string(errorPayload.Message))
Expand All @@ -469,7 +482,7 @@ func (svc *AlbyOAuthService) ListTransactions(ctx context.Context, senderPubkey

func (svc *AlbyOAuthService) SendPaymentSync(ctx context.Context, senderPubkey, payReq string) (preimage string, err error) {
app := App{}
err = svc.db.Preload("User").First(&app, &App{
err = svc.db.First(&app, &App{
NostrPubkey: senderPubkey,
}).Error
if err != nil {
Expand All @@ -483,7 +496,7 @@ func (svc *AlbyOAuthService) SendPaymentSync(ctx context.Context, senderPubkey,
"senderPubkey": senderPubkey,
"bolt11": payReq,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
}).Info("Processing payment request")
tok, err := svc.FetchUserToken(ctx, app)
if err != nil {
Expand Down Expand Up @@ -512,7 +525,7 @@ func (svc *AlbyOAuthService) SendPaymentSync(ctx context.Context, senderPubkey,
"senderPubkey": senderPubkey,
"bolt11": payReq,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
}).Errorf("Failed to pay invoice: %v", err)
return "", err
}
Expand All @@ -527,7 +540,7 @@ func (svc *AlbyOAuthService) SendPaymentSync(ctx context.Context, senderPubkey,
"senderPubkey": senderPubkey,
"bolt11": payReq,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"paymentHash": responsePayload.PaymentHash,
}).Info("Payment successful")
return responsePayload.Preimage, nil
Expand All @@ -539,15 +552,15 @@ func (svc *AlbyOAuthService) SendPaymentSync(ctx context.Context, senderPubkey,
"senderPubkey": senderPubkey,
"bolt11": payReq,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"APIHttpStatus": resp.StatusCode,
}).Errorf("Payment failed %s", string(errorPayload.Message))
return "", errors.New(errorPayload.Message)
}

func (svc *AlbyOAuthService) SendKeysend(ctx context.Context, senderPubkey string, amount int64, destination, preimage string, custom_records []TLVRecord) (preImage string, err error) {
app := App{}
err = svc.db.Preload("User").First(&app, &App{
err = svc.db.First(&app, &App{
NostrPubkey: senderPubkey,
}).Error
if err != nil {
Expand All @@ -561,7 +574,7 @@ func (svc *AlbyOAuthService) SendKeysend(ctx context.Context, senderPubkey strin
"senderPubkey": senderPubkey,
"payeePubkey": destination,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
}).Info("Processing keysend request")
tok, err := svc.FetchUserToken(ctx, app)
if err != nil {
Expand Down Expand Up @@ -598,7 +611,7 @@ func (svc *AlbyOAuthService) SendKeysend(ctx context.Context, senderPubkey strin
"senderPubkey": senderPubkey,
"payeePubkey": destination,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
}).Errorf("Failed to pay keysend: %v", err)
return "", err
}
Expand All @@ -613,7 +626,7 @@ func (svc *AlbyOAuthService) SendKeysend(ctx context.Context, senderPubkey strin
"senderPubkey": senderPubkey,
"payeePubkey": destination,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"preimage": responsePayload.Preimage,
"paymentHash": responsePayload.PaymentHash,
}).Info("Keysend payment successful")
Expand All @@ -626,7 +639,7 @@ func (svc *AlbyOAuthService) SendKeysend(ctx context.Context, senderPubkey strin
"senderPubkey": senderPubkey,
"payeePubkey": destination,
"appId": app.ID,
"userId": app.User.ID,
"userId": app.UserId,
"APIHttpStatus": resp.StatusCode,
}).Errorf("Payment failed %s", string(errorPayload.Message))
return "", errors.New(errorPayload.Message)
Expand Down

0 comments on commit dad7b90

Please sign in to comment.