Skip to content

Commit

Permalink
fix CmAccount instancing in BuyBookingToken function (#63)
Browse files Browse the repository at this point in the history
* Fixes using the bot address ( `transportOpts.From`) instead of cmAccount address.
* Skips the `checkAndApproveAllowance` before minting (the approving the allowance is done during the buy operation that is triggered by the `cmAccount.buyBookingToken()` function call).
* Uses `CAM` instead of `EURSH` in `mintnbuy.go` example  
* Add example for Test Token  in `mintnbuy.go` example (with comments)
  • Loading branch information
VjeraTurk authored Oct 28, 2024
1 parent 4fe2ca6 commit b0a7839
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 75 deletions.
31 changes: 24 additions & 7 deletions examples/booking/mintnbuy.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"github.com/chain4travel/camino-messenger-bot/pkg/booking"
cmaccounts "github.com/chain4travel/camino-messenger-bot/pkg/cm_accounts"
erc20 "github.com/chain4travel/camino-messenger-bot/pkg/erc20"
"github.com/chain4travel/camino-messenger-contracts/go/contracts/bookingtoken"
"github.com/chain4travel/camino-messenger-contracts/go/contracts/bookingtokenv2"
)

// Simple usage example for the BookingService
Expand Down Expand Up @@ -77,7 +77,7 @@ func main() {
sugar.Fatalf("Failed to create Booking Service: %v", err)
}

bt, err := bookingtoken.NewBookingtoken(common.HexToAddress("0xe55E387F5474a012D1b048155E25ea78C7DBfBBC"), client)
bt, err := bookingtokenv2.NewBookingtokenv2(common.HexToAddress("0xe55E387F5474a012D1b048155E25ea78C7DBfBBC"), client)
if err != nil {
sugar.Fatalf("Failed to create BookingToken contract binding: %v", err)
}
Expand All @@ -90,8 +90,8 @@ func main() {

nativeTokenAddress := common.HexToAddress("0x0000000000000000000000000000000000000000")
// https://columbus.caminoscan.com/token/0x5b1c852dad36854B0dFFF61d2C13F108D8E01975
eurshToken := common.HexToAddress("0x5b1c852dad36854B0dFFF61d2C13F108D8E01975")
// testToken := common.HexToAddress("0x53A0b6A344C8068B211d47f177F0245F5A99eb2d")
eurshToken := common.HexToAddress("0x5b1c852dad36854B0dFFF61d2C13F108D8E01975") // You can't use EURSH if you are not registered in their system
testToken := common.HexToAddress("0x53A0b6A344C8068B211d47f177F0245F5A99eb2d") // Requires having Test Token in your CM- account

var paymentToken common.Address = nativeTokenAddress
var priceBigInt *big.Int
Expand Down Expand Up @@ -121,6 +121,19 @@ func main() {
},
}

// Example prices for Test Token Currency
priceTestToken := &typesv2.Price{
Value: "100",
Decimals: 2,
Currency: &typesv2.Currency{
Currency: &typesv2.Currency_TokenCurrency{
TokenCurrency: &typesv2.TokenCurrency{
ContractAddress: testToken.Hex(),
},
},
},
}

// Example prices for Native Token
priceCAM := &typesv2.Price{
Value: "1",
Expand All @@ -132,13 +145,17 @@ func main() {
},
}

sugar.Infof("%v %v %v %v", priceEUR, priceEURSH, priceCAM)
sugar.Infof("%v %v %v %v", priceEUR, priceEURSH, priceTestToken, priceCAM)
sugar.Infof("%v", price)

paymentToken = nativeTokenAddress
priceBigInt = big.NewInt(0)
// price = priceEURSH
price = priceEURSH

// price = priceEUR
// price = priceEURSH // You can't use EURSH if you are not registered in their system
// price = priceTestToken // Requires having Test Token in your CM- account

price = priceCAM

switch currency := price.Currency.Currency.(type) {
case *typesv2.Currency_NativeToken:
Expand Down
6 changes: 3 additions & 3 deletions examples/events/listen.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"syscall"

"github.com/chain4travel/camino-messenger-bot/pkg/events"
"github.com/chain4travel/camino-messenger-contracts/go/contracts/bookingtoken"
"github.com/chain4travel/camino-messenger-contracts/go/contracts/bookingtokenv2"
"github.com/chain4travel/camino-messenger-contracts/go/contracts/cmaccount"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
Expand Down Expand Up @@ -69,15 +69,15 @@ func main() {
}

_, err = el.RegisterTokenBoughtHandler(bookingTokenAddr, nil, nil, func(event interface{}) {
e := event.(*bookingtoken.BookingtokenTokenBought)
e := event.(*bookingtokenv2.Bookingtokenv2TokenBought)
sugar.Infof("Received TokenBought event: \n BookingToken: %s \n TokenID: %s \n Buyer: %s", bookingTokenAddr, e.TokenId, e.Buyer)
})
if err != nil {
log.Fatalf("Failed to register handler: %v", err)
}

_, err = el.RegisterTokenReservedHandler(bookingTokenAddr, nil, nil, nil, func(event interface{}) {
e := event.(*bookingtoken.BookingtokenTokenReserved)
e := event.(*bookingtokenv2.Bookingtokenv2TokenReserved)
sugar.Infof("Received TokenReserved event: \n BookingToken: %s \n TokenID: %s \n ReservedFor: %s \n Supplier: %s \n Price: %s \n PaymentToken: %s \n Expiration: %s", bookingTokenAddr, e.TokenId, e.ReservedFor, e.Supplier, e.Price, e.PaymentToken, e.ExpirationTimestamp)
})
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.23.1
require (
buf.build/gen/go/chain4travel/camino-messenger-protocol/grpc/go v1.5.1-20240924170438-a97744087df6.1
buf.build/gen/go/chain4travel/camino-messenger-protocol/protocolbuffers/go v1.34.2-20240924170438-a97744087df6.2
github.com/chain4travel/camino-messenger-contracts/go/contracts v0.0.0-20241011074135-9f5c573d3e25
github.com/chain4travel/camino-messenger-contracts/go/contracts v0.0.0-20241024152339-d7c3c6e5c377
github.com/ethereum/go-ethereum v1.14.9
github.com/go-viper/mapstructure/v2 v2.2.1
github.com/golang-migrate/migrate/v4 v4.18.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chain4travel/camino-messenger-contracts/go/contracts v0.0.0-20241011074135-9f5c573d3e25 h1:eWYYHBmdeqitPsX18W1yczfDFGaiY+6VRxaovf1PDtM=
github.com/chain4travel/camino-messenger-contracts/go/contracts v0.0.0-20241011074135-9f5c573d3e25/go.mod h1:omB9wucNB40bnXBQY9YXkgCT4wtCG9/PagvYntX9bDM=
github.com/chain4travel/camino-messenger-contracts/go/contracts v0.0.0-20241024152339-d7c3c6e5c377 h1:dq5m3mXGlokTIvr4Mt4P9j606fAlqJPaI4dV4qpqZFQ=
github.com/chain4travel/camino-messenger-contracts/go/contracts v0.0.0-20241024152339-d7c3c6e5c377/go.mod h1:omB9wucNB40bnXBQY9YXkgCT4wtCG9/PagvYntX9bDM=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
Expand Down
4 changes: 2 additions & 2 deletions internal/messaging/mint.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

notificationv1 "buf.build/gen/go/chain4travel/camino-messenger-protocol/protocolbuffers/go/cmp/services/notification/v1"
typesv1 "buf.build/gen/go/chain4travel/camino-messenger-protocol/protocolbuffers/go/cmp/types/v1"
"github.com/chain4travel/camino-messenger-contracts/go/contracts/bookingtoken"
"github.com/chain4travel/camino-messenger-contracts/go/contracts/bookingtokenv2"
"github.com/ethereum/go-ethereum/common"
"google.golang.org/grpc"
grpc_metadata "google.golang.org/grpc/metadata"
Expand Down Expand Up @@ -63,7 +63,7 @@ func (h *evmResponseHandler) onBookingTokenMint(tokenID *big.Int, mintID *typesv
func(e any) {
expirationTimer.Stop()
h.logger.Infof("Token bought event received for token %s", tokenID.String())
event := e.(*bookingtoken.BookingtokenTokenBought)
event := e.(*bookingtokenv2.Bookingtokenv2TokenBought)

if _, err := notificationClient.TokenBoughtNotification(
context.Background(),
Expand Down
6 changes: 3 additions & 3 deletions internal/messaging/response_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
cmaccounts "github.com/chain4travel/camino-messenger-bot/pkg/cm_accounts"
"github.com/chain4travel/camino-messenger-bot/pkg/erc20"
"github.com/chain4travel/camino-messenger-bot/pkg/events"
"github.com/chain4travel/camino-messenger-contracts/go/contracts/bookingtoken"
"github.com/chain4travel/camino-messenger-contracts/go/contracts/bookingtokenv2"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
Expand Down Expand Up @@ -67,7 +67,7 @@ func NewResponseHandler(
return nil, err
}

bookingToken, err := bookingtoken.NewBookingtoken(bookingTokenAddress, ethClient)
bookingToken, err := bookingtokenv2.NewBookingtokenv2(bookingTokenAddress, ethClient)
if err != nil {
log.Printf("%v", err)
return nil, err
Expand All @@ -92,7 +92,7 @@ type evmResponseHandler struct {
cmAccountAddress common.Address
bookingTokenAddress common.Address
bookingService booking.Service
bookingToken bookingtoken.Bookingtoken
bookingToken bookingtokenv2.Bookingtokenv2
serviceRegistry ServiceRegistry
evmEventListener *events.EventListener
erc20 erc20.Service
Expand Down
42 changes: 1 addition & 41 deletions pkg/booking/booking.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ type Service struct {
cmAccounts cmaccounts.Service
}

var zeroAddress = common.HexToAddress("0x0000000000000000000000000000000000000000")

// NewService initializes a new Service. It sets up the transactor with the provided
// private key and creates the CMAccount contract.
func NewService(
Expand Down Expand Up @@ -91,12 +89,6 @@ func (bs *Service) MintBookingToken(
if strings.TrimSpace(uri) == "" {
return nil, fmt.Errorf("uri cannot be empty")
}
// if paymentToken is zeroAddress, then it is either native token or iso currency payment
if paymentToken != zeroAddress {
if err := bs.checkAndApproveAllowance(ctx, paymentToken, reservedFor, bs.cmAccountAddress, price); err != nil {
return nil, fmt.Errorf("error during token approval process: %w", err)
}
}
// Call the MintBookingToken function from the contract

receipt, err := bs.cmAccounts.MintBookingToken(
Expand Down Expand Up @@ -132,7 +124,7 @@ func (bs *Service) BuyBookingToken(
}

// Call the BuyBookingToken function from the contract
receipt, err := bs.cmAccounts.BuyBookingToken(ctx, bs.transactOpts, tokenID)
receipt, err := bs.cmAccounts.BuyBookingToken(ctx, bs.transactOpts, bs.cmAccountAddress, tokenID)
if err != nil {
return nil, fmt.Errorf("failed to buy booking token: %w", err)
}
Expand All @@ -158,35 +150,3 @@ func (bs *Service) ConvertPriceToBigInt(value string, decimals int32, totalDecim

return result, nil
}

// checkAndApproveAllowance checks if the allowance is sufficient and approves tokens if necessary
func (bs *Service) checkAndApproveAllowance(
ctx context.Context,
paymentToken common.Address,
owner, spender common.Address,
price *big.Int,
) error {
// Check allowance
allowance, err := bs.erc20.Allowance(ctx, paymentToken, owner, spender)
if err != nil {
return fmt.Errorf("failed to get allowance: %w", err)
}
bs.logger.Infof("current allowance: %s", allowance.String())

// If allowance is less than the price, approve more tokens
if allowance.Cmp(price) < 0 {
bs.logger.Infof("Allowance insufficient. Initiating approval for the required amount...")

// Approve the required amount

if err := bs.erc20.Approve(ctx, bs.transactOpts, paymentToken, spender, price); err != nil {
return fmt.Errorf("failed to approve token spending: %w", err)
}

bs.logger.Info("Approval transaction mined successfully.")
} else {
bs.logger.Infof("Sufficient allowance available. Proceeding with the transaction...")
}

return nil
}
6 changes: 5 additions & 1 deletion pkg/cm_accounts/cm_accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type Service interface {
BuyBookingToken(
ctx context.Context,
transactOpts *bind.TransactOpts,
cmAccountAddr common.Address,
tokenID *big.Int,
) (*types.Receipt, error)
}
Expand Down Expand Up @@ -267,13 +268,15 @@ func (s *service) MintBookingToken(
return nil, fmt.Errorf("failed to get cmAccount contract instance: %w", err)
}

// TODO: @VjeraTurk enable setting isCancellable flag from mintv3 on.
tx, err := cmAccount.MintBookingToken(
transactOpts,
reservedFor,
uri,
expirationTimestamp,
price,
paymentToken,
false, // In mintv1 and mintv2 isCancellable is always false - as tokens are not cancellable.
)
if err != nil {
return nil, fmt.Errorf("failed to mint booking token: %w", err)
Expand All @@ -294,9 +297,10 @@ func (s *service) MintBookingToken(
func (s *service) BuyBookingToken(
ctx context.Context,
transactOpts *bind.TransactOpts,
cmAccountAddress common.Address,
tokenID *big.Int,
) (*types.Receipt, error) {
cmAccount, err := s.cmAccount(transactOpts.From)
cmAccount, err := s.cmAccount(cmAccountAddress)
if err != nil {
return nil, fmt.Errorf("failed to get cmAccount contract instance: %w", err)
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/cm_accounts/mock_cm_accounts.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 11 additions & 11 deletions pkg/events/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"sync"
"time"

"github.com/chain4travel/camino-messenger-contracts/go/contracts/bookingtoken"
"github.com/chain4travel/camino-messenger-contracts/go/contracts/bookingtokenv2"
"github.com/chain4travel/camino-messenger-contracts/go/contracts/cmaccount"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -36,7 +36,7 @@ type EventListener struct {
logger *zap.SugaredLogger
mu sync.RWMutex
cmAccounts map[common.Address]*cmaccount.Cmaccount
btContracts map[common.Address]*bookingtoken.Bookingtoken
btContracts map[common.Address]*bookingtokenv2.Bookingtokenv2
subscriptions map[string]*subscriptionInfo // Keyed by unique IDs
}

Expand All @@ -46,7 +46,7 @@ func NewEventListener(client *ethclient.Client, logger *zap.SugaredLogger) *Even
client: client,
logger: logger,
cmAccounts: make(map[common.Address]*cmaccount.Cmaccount),
btContracts: make(map[common.Address]*bookingtoken.Bookingtoken),
btContracts: make(map[common.Address]*bookingtokenv2.Bookingtokenv2),
subscriptions: make(map[string]*subscriptionInfo),
}
}
Expand All @@ -72,15 +72,15 @@ func (el *EventListener) getOrCreateCMAccount(addr common.Address) (*cmaccount.C
}

// getOrCreateBookingToken gets or creates a BookingToken instance
func (el *EventListener) getOrCreateBookingToken(addr common.Address) (*bookingtoken.Bookingtoken, error) {
func (el *EventListener) getOrCreateBookingToken(addr common.Address) (*bookingtokenv2.Bookingtokenv2, error) {
el.mu.RLock()
bt, exists := el.btContracts[addr]
el.mu.RUnlock()
if exists {
return bt, nil
}

bt, err := bookingtoken.NewBookingtoken(addr, el.client)
bt, err := bookingtokenv2.NewBookingtokenv2(addr, el.client)
if err != nil {
return nil, fmt.Errorf("failed to create BookingToken instance: %w", err)
}
Expand Down Expand Up @@ -494,15 +494,15 @@ func (el *EventListener) RegisterTokenBoughtHandler(bookingTokenAddress common.A
}

// resubscribeTokenBought handles resubscription for TokenBought events
func (el *EventListener) resubscribeTokenBought(ctx context.Context, subID string, btContract *bookingtoken.Bookingtoken, tokenID []*big.Int, buyer []common.Address) {
func (el *EventListener) resubscribeTokenBought(ctx context.Context, subID string, btContract *bookingtokenv2.Bookingtokenv2, tokenID []*big.Int, buyer []common.Address) {
backoffMax := 2 * time.Minute

resubscribeFn := func(ctx context.Context, lastError error) (event.Subscription, error) {
if lastError != nil {
el.logger.Errorf("Resubscribe attempt after error: %v", lastError)
}

eventChan := make(chan *bookingtoken.BookingtokenTokenBought)
eventChan := make(chan *bookingtokenv2.Bookingtokenv2TokenBought)

subInfo, exists := el.getSubscriptionInfo(subID)
if !exists {
Expand Down Expand Up @@ -534,7 +534,7 @@ func (el *EventListener) resubscribeTokenBought(ctx context.Context, subID strin
}

// listenForTokenBoughtEvents listens for TokenBought events
func (el *EventListener) listenForTokenBoughtEvents(subID string, eventChan chan *bookingtoken.BookingtokenTokenBought) {
func (el *EventListener) listenForTokenBoughtEvents(subID string, eventChan chan *bookingtokenv2.Bookingtokenv2TokenBought) {
subInfo, exists := el.getSubscriptionInfo(subID)
if !exists {
return
Expand Down Expand Up @@ -575,15 +575,15 @@ func (el *EventListener) RegisterTokenReservedHandler(bookingTokenAddress common
}

// resubscribeTokenReserved handles resubscription for TokenReserved events
func (el *EventListener) resubscribeTokenReserved(ctx context.Context, subID string, btContract *bookingtoken.Bookingtoken, tokenID []*big.Int, reservedFor []common.Address, supplier []common.Address) {
func (el *EventListener) resubscribeTokenReserved(ctx context.Context, subID string, btContract *bookingtokenv2.Bookingtokenv2, tokenID []*big.Int, reservedFor []common.Address, supplier []common.Address) {
backoffMax := 2 * time.Minute

resubscribeFn := func(ctx context.Context, lastError error) (event.Subscription, error) {
if lastError != nil {
el.logger.Errorf("Resubscribe attempt after error: %v", lastError)
}

eventChan := make(chan *bookingtoken.BookingtokenTokenReserved)
eventChan := make(chan *bookingtokenv2.Bookingtokenv2TokenReserved)

subInfo, exists := el.getSubscriptionInfo(subID)
if !exists {
Expand Down Expand Up @@ -615,7 +615,7 @@ func (el *EventListener) resubscribeTokenReserved(ctx context.Context, subID str
}

// listenForTokenReservedEvents listens for TokenReserved events
func (el *EventListener) listenForTokenReservedEvents(subID string, eventChan chan *bookingtoken.BookingtokenTokenReserved) {
func (el *EventListener) listenForTokenReservedEvents(subID string, eventChan chan *bookingtokenv2.Bookingtokenv2TokenReserved) {
subInfo, exists := el.getSubscriptionInfo(subID)
if !exists {
return
Expand Down

0 comments on commit b0a7839

Please sign in to comment.