Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
d5bcb7d
Drafted endpoints for API
esuwu Nov 11, 2025
4be1b1e
Updated protobuf structures
esuwu Nov 19, 2025
52af168
Merge branch 'add-network-messages' into node-api-finality
esuwu Nov 19, 2025
d033dc9
Added finalization storage
esuwu Nov 24, 2025
402ef6f
Fixed errors
esuwu Nov 24, 2025
1caf2a1
Fixed old code
esuwu Nov 24, 2025
82a7a2e
SignCommitGeneration draft
esuwu Nov 24, 2025
aac66f8
Merged from finality network messages
esuwu Nov 24, 2025
350e93d
Finished signCommitToGeneration
esuwu Nov 24, 2025
9b96f0f
Merged from add network messages
esuwu Nov 26, 2025
20bf1d8
Added validation of finalization
esuwu Nov 27, 2025
282bf9f
Added finalization validation
esuwu Dec 3, 2025
cd82ba3
Added a finalization processor for tx appender
esuwu Dec 3, 2025
51f714d
Merged from add-network-messages
esuwu Dec 3, 2025
44ad778
Merged from add-network-messages
esuwu Dec 5, 2025
40c3d02
Merged again
esuwu Dec 5, 2025
5dce8da
Added clients methods
esuwu Dec 9, 2025
b77abc1
Added http client itests
esuwu Dec 10, 2025
6e83e89
Fixed an error
esuwu Dec 10, 2025
2bfd983
Updated protobuf version
esuwu Dec 17, 2025
d17d321
Merge branch 'add-network-messages' into node-api-finality
esuwu Dec 17, 2025
a504094
Merge branch 'add-network-messages' into node-api-finality
esuwu Dec 18, 2025
1258e13
Implemented nickeskov's suggestions
esuwu Dec 22, 2025
8b80e20
Implemented some AI suggestions
esuwu Dec 22, 2025
57f2cf6
Made the tx signing handle all tx types
esuwu Dec 23, 2025
475f2cd
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 12, 2026
a8b563f
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 12, 2026
9bbf167
Merged from add-network-messages
esuwu Jan 14, 2026
1a9ba80
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 14, 2026
3ff25c5
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 14, 2026
5b92751
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 14, 2026
458f4b3
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 14, 2026
6a3355f
Merged from add-network-messages
esuwu Jan 15, 2026
3c38c2a
Fixed an fmt error
esuwu Jan 16, 2026
eec3dca
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 20, 2026
ef98afe
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 21, 2026
80c59d1
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 21, 2026
9302d0d
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 21, 2026
8b84ccc
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 21, 2026
2426b31
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 21, 2026
e4ce47b
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 21, 2026
cd3b937
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 21, 2026
3df7ae6
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 21, 2026
270f398
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 23, 2026
ae48b55
Added a test for transactionSign
esuwu Jan 23, 2026
bfb4ac9
Fixed linter erors
esuwu Jan 23, 2026
f815e96
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 25, 2026
c7f964d
Added a specific error
esuwu Jan 25, 2026
67f82e3
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 26, 2026
0057141
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 26, 2026
0f7a7b1
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 26, 2026
e057365
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 26, 2026
34bdf95
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 26, 2026
426e67a
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 26, 2026
3134453
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 26, 2026
37b3522
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 27, 2026
bb0c09e
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 27, 2026
57ad53a
merged from add-network-messages
esuwu Jan 27, 2026
d513e1a
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 27, 2026
743846e
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 27, 2026
8c4cb9b
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 27, 2026
022ac5f
Added logs
esuwu Jan 27, 2026
160416f
merged from add-network-messages
esuwu Jan 27, 2026
7b1e186
Fixed a linter error
esuwu Jan 27, 2026
46cabb3
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 28, 2026
a2ac998
Changed commitment transaction fee
esuwu Jan 28, 2026
ac0eab9
Merge branch 'add-network-messages' into node-api-finality
esuwu Jan 28, 2026
32413f5
Allowed for custom transaction fee in commitment tx sign api
esuwu Jan 28, 2026
bff2a60
Fix modernize.
nickeskov Feb 3, 2026
e227184
Merge branch 'add-network-messages' into node-api-finality
esuwu Feb 3, 2026
c623adc
Changed fmt to errors wrap
esuwu Feb 3, 2026
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 cmd/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ func runNode(ctx context.Context, nc *config) (_ io.Closer, retErr error) {
return nil, errors.Wrap(err, "failed to create services")
}

app, err := api.NewApp(nc.apiKey, minerScheduler, svs)
app, err := api.NewApp(nc.apiKey, minerScheduler, svs, cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to initialize application")
}
Expand Down
10 changes: 5 additions & 5 deletions cmd/wallet/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,11 +449,11 @@ func createWallet(
return errors.Wrap(err, "failed to write the wallet's data to the wallet")

}
fmt.Printf("New account has been added to wallet successfully %s\n", walletPath) //nolint:forbidigo // As intended
fmt.Printf("Account Seed: %s\n", walletCredentials.accountSeed.String())
fmt.Printf("Public Key: %s\n", walletCredentials.pk.String())
fmt.Printf("Secret Key: %s\n", walletCredentials.sk.String())
fmt.Printf("Address: %s\n", walletCredentials.address.String())
fmt.Fprintf(os.Stdout, "New account has been added to wallet successfully %s\n", walletPath)
fmt.Fprintf(os.Stdout, "Account Seed: %s\n", walletCredentials.accountSeed.String())
fmt.Fprintf(os.Stdout, "Public Key: %s\n", walletCredentials.pk.String())
fmt.Fprintf(os.Stdout, "Secret Key: %s\n", walletCredentials.sk.String())
fmt.Fprintf(os.Stdout, "Address: %s\n", walletCredentials.address.String())
return nil
}

Expand Down
45 changes: 45 additions & 0 deletions itests/clients/http_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,48 @@ func (c *HTTPClient) RollbackToHeight(t testing.TB, height uint64, returnTxToUtx
require.NoErrorf(t, err, "failed to rollback to height on %s node", c.impl.String())
return blockID
}

func (c *HTTPClient) HeightFinalized(t testing.TB) proto.Height {
ctx, cancel := context.WithTimeout(context.Background(), c.timeout)
defer cancel()

h, _, err := c.cli.Blocks.HeightFinalized(ctx)
require.NoErrorf(t, err, "failed to get finalized height from %s node", c.impl.String())

return h
}

func (c *HTTPClient) BlockFinalized(t testing.TB) *proto.BlockHeader {
ctx, cancel := context.WithTimeout(context.Background(), c.timeout)
defer cancel()

header, _, err := c.cli.Blocks.BlockFinalized(ctx)
require.NoErrorf(t, err, "failed to get finalized header from %s node", c.impl.String())
require.NotNil(t, header, "finalized header is nil from %s node", c.impl.String())

return header
}

func (c *HTTPClient) CommitmentGeneratorsAt(t testing.TB, height proto.Height) []client.GeneratorInfoResponse {
ctx, cancel := context.WithTimeout(context.Background(), c.timeout)
defer cancel()

gens, _, err := c.cli.Generators.CommitmentGeneratorsAt(ctx, height)
require.NoErrorf(t, err, "failed to get generators at height %d from %s node", height, c.impl.String())

return gens
}

func (c *HTTPClient) SignCommit(
t testing.TB,
req *client.SignCommitRequest,
) *proto.CommitToGenerationWithProofs {
ctx, cancel := context.WithTimeout(context.Background(), c.timeout)
defer cancel()

out, _, err := c.cli.Transactions.SignCommit(ctx, req)
require.NoErrorf(t, err, "failed to sign commit transaction on %s node", c.impl.String())

require.NotNil(t, out, "empty response from /transactions/sign on %s node", c.impl.String())
return out
}
27 changes: 17 additions & 10 deletions pkg/api/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import (

"github.com/pkg/errors"

apiErr "github.com/wavesplatform/gowaves/pkg/api/errors"
"github.com/wavesplatform/gowaves/pkg/crypto"
"github.com/wavesplatform/gowaves/pkg/miner/scheduler"
"github.com/wavesplatform/gowaves/pkg/node/messages"
"github.com/wavesplatform/gowaves/pkg/node/peers"
"github.com/wavesplatform/gowaves/pkg/proto"
"github.com/wavesplatform/gowaves/pkg/services"
"github.com/wavesplatform/gowaves/pkg/settings"
"github.com/wavesplatform/gowaves/pkg/state"
"github.com/wavesplatform/gowaves/pkg/types"
)
Expand All @@ -35,6 +37,7 @@ const (
type appSettings struct {
BlockRequestLimit uint64
AssetDetailsLimit int
GenerationPeriod uint64
}

func defaultAppSettings() *appSettings {
Expand All @@ -56,19 +59,23 @@ type App struct {
settings *appSettings
}

func NewApp(apiKey string, scheduler SchedulerEmits, services services.Services) (*App, error) {
return newApp(apiKey, scheduler, services, nil)
func NewApp(apiKey string, scheduler SchedulerEmits, services services.Services,
cfg *settings.BlockchainSettings) (*App, error) {
return newApp(apiKey, scheduler, services, nil, cfg)
}

func newApp(apiKey string, scheduler SchedulerEmits, services services.Services, settings *appSettings) (*App, error) {
if settings == nil {
settings = defaultAppSettings()
func newApp(apiKey string, scheduler SchedulerEmits, services services.Services, appSettings *appSettings,
cfg *settings.BlockchainSettings) (*App, error) {
if appSettings == nil {
appSettings = defaultAppSettings()
}
digest, err := crypto.SecureHash([]byte(apiKey))
if err != nil {
return nil, err
}

if cfg != nil {
appSettings.GenerationPeriod = cfg.GenerationPeriod
}
return &App{
hashedApiKey: digest,
apiKeyEnabled: len(apiKey) > 0,
Expand All @@ -77,25 +84,25 @@ func newApp(apiKey string, scheduler SchedulerEmits, services services.Services,
utx: services.UtxPool,
peers: services.Peers,
services: services,
settings: settings,
settings: appSettings,
}, nil
}

func (a *App) TransactionsBroadcast(ctx context.Context, b []byte) (proto.Transaction, error) {
tt := proto.TransactionTypeVersion{}
err := json.Unmarshal(b, &tt)
if err != nil {
return nil, wrapToBadRequestError(err)
return nil, apiErr.NewBadRequestError(err)
}

realType, err := proto.GuessTransactionType(&tt)
if err != nil {
return nil, wrapToBadRequestError(err)
return nil, apiErr.NewBadRequestError(err)
}

err = proto.UnmarshalTransactionFromJSON(b, a.services.Scheme, realType)
if err != nil {
return nil, wrapToBadRequestError(err)
return nil, apiErr.NewBadRequestError(err)
}

respCh := make(chan error, 1)
Expand Down
8 changes: 7 additions & 1 deletion pkg/api/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@ import (

"github.com/stretchr/testify/require"
"github.com/wavesplatform/gowaves/pkg/services"
"github.com/wavesplatform/gowaves/pkg/settings"
)

func TestAppAuth(t *testing.T) {
app, _ := NewApp("apiKey", nil, services.Services{})
cfg := &settings.BlockchainSettings{
FunctionalitySettings: settings.FunctionalitySettings{
GenerationPeriod: 0,
},
}
app, _ := NewApp("apiKey", nil, services.Services{}, cfg)
require.Error(t, app.checkAuth("bla"))
require.NoError(t, app.checkAuth("apiKey"))
}
15 changes: 13 additions & 2 deletions pkg/api/blocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/wavesplatform/gowaves/pkg/mock"
"github.com/wavesplatform/gowaves/pkg/proto"
"github.com/wavesplatform/gowaves/pkg/services"
"github.com/wavesplatform/gowaves/pkg/settings"
)

func TestApp_BlocksFirst(t *testing.T) {
Expand All @@ -26,7 +27,12 @@ func TestApp_BlocksFirst(t *testing.T) {
s := mock.NewMockState(ctrl)
s.EXPECT().BlockByHeight(proto.Height(1)).Return(g, nil)

app, err := NewApp("api-key", nil, services.Services{State: s})
cfg := &settings.BlockchainSettings{
FunctionalitySettings: settings.FunctionalitySettings{
GenerationPeriod: 0,
},
}
app, err := NewApp("api-key", nil, services.Services{State: s}, cfg)
require.NoError(t, err)
first, err := app.BlocksFirst()
require.NoError(t, err)
Expand All @@ -42,7 +48,12 @@ func TestApp_BlocksLast(t *testing.T) {
s.EXPECT().Height().Return(proto.Height(1), nil)
s.EXPECT().BlockByHeight(proto.Height(1)).Return(g, nil)

app, err := NewApp("api-key", nil, services.Services{State: s})
cfg := &settings.BlockchainSettings{
FunctionalitySettings: settings.FunctionalitySettings{
GenerationPeriod: 0,
},
}
app, err := NewApp("api-key", nil, services.Services{State: s}, cfg)
require.NoError(t, err)
first, err := app.BlocksLast()
require.NoError(t, err)
Expand Down
31 changes: 10 additions & 21 deletions pkg/api/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,6 @@ var (
notFound = errors.New("not found")
)

// BadRequestError represents a bad request error.
// Deprecated: don't use this error type in new code. Create a new error type or value in 'pkg/api/errors' package.
type BadRequestError struct {
inner error
}

func wrapToBadRequestError(err error) *BadRequestError {
return &BadRequestError{inner: err}
}

func (e *BadRequestError) Error() string {
return e.inner.Error()
}

// AuthError represents an authentication error or problem.
// Deprecated: don't use this error type in new code. Create a new error type or value in 'pkg/api/errors' package.
type AuthError struct {
Expand Down Expand Up @@ -62,17 +48,18 @@ func (eh *ErrorHandler) Handle(w http.ResponseWriter, r *http.Request, err error
}
// target errors
var (
badRequestError *BadRequestError
authError *AuthError
unknownError *apiErrs.UnknownError
apiError apiErrs.ApiError
badRequestError *apiErrs.BadRequestError
authError *AuthError
unknownError *apiErrs.UnknownError
apiError apiErrs.ApiError
unavailableError *apiErrs.UnavailableError
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New error should implement ApiError interface.

Copy link
Contributor Author

@esuwu esuwu Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They already do

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then you can remove specific cases. One case errors.As(err, &apiError) is enough for handling if no specific is used.

// check that all targets implement the error interface
_, _, _, _ = error(badRequestError), error(authError), error(unknownError), error(apiError)
_, _, _, _, _ = error(badRequestError), error(authError), error(unknownError),
error(apiError), error(unavailableError)
)
switch {
case errors.As(err, &badRequestError):
// nickeskov: this error type will be removed in future
http.Error(w, fmt.Sprintf("Failed to complete request: %s", badRequestError.Error()), http.StatusBadRequest)
eh.sendApiErrJSON(w, r, badRequestError)
case errors.As(err, &authError):
// nickeskov: this error type will be removed in future
http.Error(w, fmt.Sprintf("Failed to complete request: %s", authError.Error()), http.StatusForbidden)
Expand All @@ -86,6 +73,8 @@ func (eh *ErrorHandler) Handle(w http.ResponseWriter, r *http.Request, err error
eh.sendApiErrJSON(w, r, unknownError)
case errors.As(err, &apiError):
eh.sendApiErrJSON(w, r, apiError)
case errors.As(err, &unavailableError):
eh.sendApiErrJSON(w, r, unavailableError)
Comment on lines +76 to +77
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If apiErrs.UnavailableError implements ApiError, so this case would be never used.

default:
eh.logger.Error("InternalServerError",
slog.String("proto", r.Proto),
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/errors/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type (
var (
ApiKeyNotValid = &ApiKeyNotValidError{
genericError: genericError{
ID: ApiKeyNotValidErrorID,
ID: APIKeyNotValidErrorID,
HttpCode: http.StatusBadRequest,
Message: "Provided API key is not correct",
},
Expand Down
110 changes: 109 additions & 1 deletion pkg/api/errors/basics.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,119 @@ type WrongJsonError struct {
func NewWrongJsonError(cause string, validationErrors []error) *WrongJsonError {
return &WrongJsonError{
genericError: genericError{
ID: WrongJsonErrorID,
ID: WrongJSONErrorID,
HttpCode: http.StatusBadRequest,
Message: "failed to parse json message",
},
Cause: cause,
ValidationErrors: validationErrors,
}
}

// UnavailableError UnknownError is a wrapper for any error related to service unavailability.
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment incorrectly identifies this as "UnknownError" when it should describe "UnavailableError".

Suggested change
// UnavailableError UnknownError is a wrapper for any error related to service unavailability.
// UnavailableError is a wrapper for any error related to service unavailability.

Copilot uses AI. Check for mistakes.
type UnavailableError struct {
genericError
inner error
}

func (u *UnavailableError) Unwrap() error {
return u.inner
}

func (u *UnavailableError) Error() string {
if u.Unwrap() != nil {
return fmt.Sprintf(
"%s; inner error (%T): %s",
u.genericError.Error(),
u.Unwrap(), u.Unwrap().Error(),
)
}
return u.genericError.Error()
}

func NewUnavailableError(inner error) *UnavailableError {
return NewUnavailableErrorWithMsg("Service is unavailable", inner)
}

func NewUnavailableErrorWithMsg(message string, inner error) *UnavailableError {
return &UnavailableError{
genericError: genericError{
ID: ServiceUnavailableErrorID,
HttpCode: http.StatusServiceUnavailable,
Message: message,
},
inner: inner,
}
}

// BadRequestError is a wrapper for any bad request error.
type BadRequestError struct {
genericError
inner error
}

func (u *BadRequestError) Unwrap() error {
return u.inner
}

func (u *BadRequestError) Error() string {
if u.Unwrap() != nil {
return fmt.Sprintf(
"%s; inner error (%T): %s",
u.genericError.Error(),
u.Unwrap(), u.Unwrap().Error(),
)
}
return u.genericError.Error()
}

func NewBadRequestError(inner error) *BadRequestError {
return NewBadRequestErrorWithMsg("Bad request", inner)
}

func NewBadRequestErrorWithMsg(message string, inner error) *BadRequestError {
return &BadRequestError{
genericError: genericError{
ID: BadRequestErrorID,
HttpCode: http.StatusBadRequest,
Message: message,
},
inner: inner,
}
}

// NotImplementedError is a wrapper for any not implemented error.
type NotImplementedError struct {
genericError
inner error
}

func (u *NotImplementedError) Unwrap() error {
return u.inner
}

func (u *NotImplementedError) Error() string {
if u.Unwrap() != nil {
return fmt.Sprintf(
"%s; inner error (%T): %s",
u.genericError.Error(),
u.Unwrap(), u.Unwrap().Error(),
)
}
return u.genericError.Error()
}

func NewNotImplementedError(inner error) *NotImplementedError {
return NewNotImplementedErrorWithMsg("Not implemented", inner)
}

func NewNotImplementedErrorWithMsg(message string, inner error) *NotImplementedError {
return &NotImplementedError{
genericError: genericError{
ID: NotImplementedErrorID,
HttpCode: http.StatusNotImplemented,
Message: message,
},
inner: inner,
}
}
Comment on lines +162 to +232
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable naming uses 'u' as the receiver for BadRequestError and NotImplementedError, but this is inconsistent. The letter 'u' suggests 'unavailable' which was used for UnavailableError. Consider using 'b' for BadRequestError and 'n' for NotImplementedError for clarity.

Copilot uses AI. Check for mistakes.
Loading
Loading