Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

740-4 use new wallet package #778

Merged
merged 9 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ jobs:
- uses: actions/checkout@v3
- uses: ./.github/actions/install
- name: build
run: go build -tags desktop,production -ldflags "-w -s" -o tests/test_wallet main.go
run: go build -tags desktop,production -ldflags "-w -s" -o build/test_wallet main.go
- name: Run app
run: WALLET_PASSWORD=bonjour STANDALONE=1 xvfb-run ./tests/test_wallet &
run: WALLET_PASSWORD=bonjour STANDALONE=1 xvfb-run ./build/test_wallet &
- name: Move account file
run: |
mkdir -p ~/.config/massa-station-wallet
Expand Down
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,10 @@ Wails is a native GUI library for Go. It allows us to build a native GUI app wit
Folder: `wails-frontend`.

This folder contains the source code of the wails frontend app. It is a React app.

### Error handling

* Use sentinel error
* Functions don't return a middleware responder, but an error
* for http error response, use as much as possible `internal/handler/wallet/newErrorResponse`
* for wails error code: use `pkg/utils/WailsErrorCode`
2 changes: 1 addition & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ tasks:
test:
cmds:
- task: clean
- cmd: go test -v -timeout 60s ./...
- cmd: go test -v -timeout 20s ./...

fmt:
cmds:
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ require (
github.com/stretchr/testify v1.8.4
github.com/wailsapp/wails/v2 v2.6.0
golang.org/x/crypto v0.14.0
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
gopkg.in/yaml.v2 v2.4.0
)

Expand Down Expand Up @@ -47,6 +46,7 @@ require (
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
howett.net/plist v1.0.0 // indirect
)

Expand All @@ -73,6 +73,6 @@ require (
golang.org/x/net v0.17.0
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
gopkg.in/yaml.v3 v3.0.1
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.1.7
)
10 changes: 5 additions & 5 deletions internal/handler/wallet/add_asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type addAsset struct {
massaClient network.NodeFetcherInterface
}

func (h *addAsset) Handle(params operations.AddAssetParams) middleware.Responder {
func (a *addAsset) Handle(params operations.AddAssetParams) middleware.Responder {
// Check if the address is valid
if !address.IsValidAddress(params.AssetAddress) {
// Return an error indicating the address is not valid
Expand All @@ -34,29 +34,29 @@ func (h *addAsset) Handle(params operations.AddAssetParams) middleware.Responder
}

// First, check if the asset exists in the network
if !h.massaClient.AssetExistInNetwork(params.AssetAddress) {
if !a.massaClient.AssetExistInNetwork(params.AssetAddress) {
// If the asset does not exist in the network, return a 404 response
errorMsg := "Asset with the provided address not found in the network."
return operations.NewAddAssetNotFound().WithPayload(&models.Error{Code: errorAssetNotFound, Message: errorMsg})
}

// Check if the address exists in the loaded JSON
if h.AssetsStore.AssetExists(params.Nickname, params.AssetAddress) {
if a.AssetsStore.AssetExists(params.Nickname, params.AssetAddress) {
// Return that the asset already exists
errorMsg := "Asset with the provided address already exists."
return operations.NewAddAssetBadRequest().WithPayload(&models.Error{Code: errorAssetExists, Message: errorMsg})
}

// Fetch the asset information from the SC
assetInfoFromSC, err := assets.AssetInfo(params.AssetAddress, h.massaClient)
assetInfoFromSC, err := assets.AssetInfo(params.AssetAddress, a.massaClient)
if err != nil {
// Return error occurred during SC fetch
errorMsg := "Failed to fetch asset information from the smart contract."
return operations.NewAddAssetInternalServerError().WithPayload(&models.Error{Code: errorFetchAssetSC, Message: errorMsg})
}

// Add Asset and persist in JSON file.
if err := h.AssetsStore.AddAsset(params.Nickname, params.AssetAddress, *assetInfoFromSC); err != nil {
if err := a.AssetsStore.AddAsset(params.Nickname, params.AssetAddress, *assetInfoFromSC); err != nil {
// Return error occurred while persisting the asset
errorMsg := "Failed to add the asset to the JSON file."
return operations.NewAddAssetInternalServerError().WithPayload(&models.Error{Code: errorAddAssetJSON, Message: errorMsg})
Expand Down
12 changes: 5 additions & 7 deletions internal/handler/wallet/add_assets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import (
"os"
"testing"

"github.com/awnumar/memguard"
"github.com/massalabs/station-massa-wallet/api/server/models"
"github.com/massalabs/station-massa-wallet/api/server/restapi/operations"
utils "github.com/massalabs/station-massa-wallet/pkg/assets"
"github.com/massalabs/station-massa-wallet/pkg/wallet"
"github.com/massalabs/station-massa-wallet/pkg/wallet/account"
"github.com/massalabs/station/pkg/logger"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
Expand All @@ -28,8 +29,8 @@ func TestAddAssetHandler(t *testing.T) {
nickname := "GoodNickname"
password := "zePassword"

_, errGenerate := wallet.Generate(nickname, password)
assert.Nil(t, errGenerate)
_, err = account.Generate(memguard.NewBufferFromBytes([]byte(password)), nickname)
assert.Nil(t, err)

type testCase struct {
Name string
Expand Down Expand Up @@ -104,9 +105,6 @@ func TestAddAssetHandler(t *testing.T) {
// Remove the json file created
err = RemoveJSONFile()
assert.NoError(t, err)

err = cleanupTestData([]string{nickname})
assert.NoError(t, err)
})

// Remove the json file created
Expand All @@ -124,7 +122,7 @@ func addAssetTest(t *testing.T, api *operations.MassaWalletAPI, nickname, assetA
resp, err := handleHTTPRequest(handler, "POST", fmt.Sprintf("/api/accounts/%s/assets?assetAddress=%s", nickname, assetAddress), "")
assert.NoError(t, err)

assert.Equal(t, http.StatusCreated, resp.Result().StatusCode)
assert.Equal(t, http.StatusCreated, resp.Result().StatusCode, "response is %s", resp.Body.String())

// Parse the response body to get the added asset
var addedAsset models.AssetInfo
Expand Down
42 changes: 28 additions & 14 deletions internal/handler/wallet/api.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package wallet

import (
"errors"
"net/http"

"github.com/bluele/gcache"
"github.com/go-openapi/runtime/middleware"
"github.com/massalabs/station-massa-wallet/api/server/models"
"github.com/massalabs/station-massa-wallet/api/server/restapi/operations"
"github.com/massalabs/station-massa-wallet/pkg/assets"
"github.com/massalabs/station-massa-wallet/pkg/network"
"github.com/massalabs/station-massa-wallet/pkg/openapi"
"github.com/massalabs/station-massa-wallet/pkg/prompt"
"github.com/massalabs/station-massa-wallet/pkg/wallet"
walletpkg "github.com/massalabs/station-massa-wallet/pkg/wallet"
"github.com/massalabs/station-massa-wallet/pkg/wallet/account"
"github.com/massalabs/station/pkg/logger"
)

// AppendEndpoints appends wallet endpoints to the API
Expand All @@ -17,35 +24,42 @@
api.CreateAccountHandler = NewCreateAccount(prompterApp, massaClient)
api.DeleteAccountHandler = NewDelete(prompterApp, massaClient)
api.ImportAccountHandler = NewImport(prompterApp, massaClient)
api.AccountListHandler = NewGetAll(massaClient)
api.AccountListHandler = NewGetAll(prompterApp.App().Wallet, massaClient)
api.SignHandler = NewSign(prompterApp, gc)
api.SignMessageHandler = NewSignMessage(prompterApp, gc)
api.GetAccountHandler = NewGet(prompterApp, massaClient)
api.ExportAccountFileHandler = operations.ExportAccountFileHandlerFunc(HandleExportFile)
api.ExportAccountFileHandler = NewWalletExportFile(prompterApp.App().Wallet)
api.TransferCoinHandler = NewTransferCoin(prompterApp, massaClient)
api.TradeRollsHandler = NewTradeRolls(prompterApp, massaClient)
api.BackupAccountHandler = NewBackupAccount(prompterApp)
api.UpdateAccountHandler = NewUpdateAccount(prompterApp, massaClient)
api.AddAssetHandler = NewAddAsset(AssetsStore, massaClient)
api.GetAllAssetsHandler = NewGetAllAssets(AssetsStore, massaClient)
api.GetAllAssetsHandler = NewGetAllAssets(prompterApp.App().Wallet, AssetsStore, massaClient)
api.DeleteAssetHandler = NewDeleteAsset(AssetsStore)
}

// loadWallet loads a wallet from the file system or returns an error.
func loadWallet(nickname string) (*wallet.Wallet, middleware.Responder) {
w, err := wallet.Load(nickname)
// loadAccount loads a wallet from the file system or returns an error.
// Here it is acceptable to return a middleware.Responder to simplify the code.
func loadAccount(wallet *wallet.Wallet, nickname string) (*account.Account, middleware.Responder) {
acc, err := wallet.GetAccount(nickname)
if err == nil {
return w, nil
return acc, nil
}

errorObj := models.Error{
Code: errorGetWallets,
Message: err.Error(),
if errors.Is(err, walletpkg.AccountNotFoundError) {
return nil, newErrorResponse(err.Error(), errorGetAccount, http.StatusNotFound)
} else {
return nil, newErrorResponse(err.Error(), errorGetAccount, http.StatusBadRequest)

Check warning on line 52 in internal/handler/wallet/api.go

View check run for this annotation

Codecov / codecov/patch

internal/handler/wallet/api.go#L52

Added line #L52 was not covered by tests
}
}

if err.Error() == wallet.ErrorAccountNotFound(nickname).Error() {
return nil, operations.NewGetAccountNotFound().WithPayload(&errorObj)
} else {
return nil, operations.NewGetAccountBadRequest().WithPayload(&errorObj)
func newErrorResponse(message, code string, statusCode int) middleware.Responder {
logger.Error(message)

payload := &models.Error{
Code: code,
Message: message,
}

return openapi.NewPayloadResponder(statusCode, payload)
}
14 changes: 13 additions & 1 deletion internal/handler/wallet/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
walletapp "github.com/massalabs/station-massa-wallet/pkg/app"
"github.com/massalabs/station-massa-wallet/pkg/assets"
"github.com/massalabs/station-massa-wallet/pkg/prompt"
"github.com/massalabs/station-massa-wallet/pkg/wallet"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -49,7 +50,17 @@ func MockAPI() (*operations.MassaWalletAPI, prompt.WalletPrompterInterface, *ass

resultChannel := make(chan walletapp.EventData)

prompterApp := NewWalletPrompterMock(walletapp.NewWalletApp(), resultChannel)
walletPath, err := os.MkdirTemp(os.TempDir(), "*-wallet-dir")
if err != nil {
log.Fatalf("while creating temporary wallet directory: %s", err.Error())
}

wallet, err := wallet.New(walletPath)
if err != nil {
return nil, nil, nil, nil, err
}

prompterApp := NewWalletPrompterMock(walletapp.NewWalletApp(wallet), resultChannel)

assetsJSONPath, err := assets.GetAssetsJSONPath()
if err != nil {
Expand All @@ -62,6 +73,7 @@ func MockAPI() (*operations.MassaWalletAPI, prompt.WalletPrompterInterface, *ass
}

massaNodeMock := NewNodeFetcherMock()

// Set wallet API endpoints
AppendEndpoints(massaWalletAPI, prompterApp, massaNodeMock, AssetsStore, gcache.New(20).LRU().Build())

Expand Down
Loading
Loading