Skip to content
Open
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
56 changes: 56 additions & 0 deletions actions/v2/users/address.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package users

import (
"net/http"

"github.com/bitcoin-sv/spv-wallet/api"
"github.com/bitcoin-sv/spv-wallet/engine/spverrors"
"github.com/bitcoin-sv/spv-wallet/engine/v2/addresses/addressesmodels"
"github.com/bitcoin-sv/spv-wallet/server/reqctx"
"github.com/gin-gonic/gin"
)

// CreateAddress creates a new paymail address for the user.
func (s *APIUsers) CreateAddress(c *gin.Context) {
userContext := reqctx.GetUserContext(c)
userID, err := userContext.ShouldGetUserID()
if err != nil {
spverrors.ErrorResponse(c, err, reqctx.Logger(c))
return
}

var req api.RequestsCreatePaymailAddress
if err := c.ShouldBindJSON(&req); err != nil {
spverrors.ErrorResponse(c, err, reqctx.Logger(c))
return
}

fullAddress := req.Paymail.Alias + "@" + req.Paymail.Domain

newAddress := &addressesmodels.NewAddress{
UserID: userID,
Address: fullAddress,
CustomInstructions: nil,
}

err = reqctx.Engine(c).AddressesService().Create(c.Request.Context(), newAddress)
if err != nil {
spverrors.ErrorResponse(c, err, reqctx.Logger(c))
return
}

c.JSON(http.StatusOK, &api.ResponsesPaymailAddress{
Alias: req.Paymail.Alias,
Domain: req.Paymail.Domain,
Paymail: fullAddress,
PublicName: valueOrDefault(req.Paymail.PublicName, req.Paymail.Alias),
Avatar: valueOrDefault(req.Paymail.AvatarURL, ""),
})
}

func valueOrDefault(ptr *string, defaultValue string) string {
if ptr != nil {
return *ptr
}
return defaultValue
}
76 changes: 76 additions & 0 deletions actions/v2/users/address_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package users_test

import (
"testing"

"github.com/bitcoin-sv/spv-wallet/actions/testabilities"
testengine "github.com/bitcoin-sv/spv-wallet/engine/testabilities"
)

func TestCreateAddress(t *testing.T) {
givenForAllTests := testabilities.Given(t)
cleanup := givenForAllTests.StartedSPVWalletWithConfiguration(
testengine.WithV2(),
)
defer cleanup()

t.Run("create paymail address for user", func(t *testing.T) {
// given:
given, then := testabilities.NewOf(givenForAllTests, t)
client := given.HttpClient().ForUser()

res, _ := client.R().
SetBody(`{
"paymail": {
"alias": "test",
"domain": "spv-wallet.com",
"publicName": "Test User",
"avatarURL": "https://example.com/avatar.png"
}
}`).
Post("/api/v2/users/address")

then.Response(res).
IsOK().
WithJSONMatching(`{
"alias": "test",
"domain": "spv-wallet.com",
"paymail": "test@spv-wallet.com",
"publicName": "Test User",
"avatar": "https://example.com/avatar.png",
"id": 0
}`, nil)
})

t.Run("return unauthorized for admin", func(t *testing.T) {
given, then := testabilities.NewOf(givenForAllTests, t)
client := given.HttpClient().ForAdmin()

res, _ := client.R().
SetBody(`{
"paymail": {
"alias": "test",
"domain": "spv-wallet.com"
}
}`).
Post("/api/v2/users/address")

then.Response(res).IsUnauthorizedForAdmin()
})

t.Run("return unauthorized for anonymous user", func(t *testing.T) {
given, then := testabilities.NewOf(givenForAllTests, t)
client := given.HttpClient().ForAnonymous()

res, _ := client.R().
SetBody(`{
"paymail": {
"alias": "test",
"domain": "spv-wallet.com"
}
}`).
Post("/api/v2/users/address")

then.Response(res).IsUnauthorized()
})
}
8 changes: 8 additions & 0 deletions api/components/requests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ components:
- to
- satoshis

CreatePaymailAddress:
type: object
properties:
paymail:
$ref: "#/components/schemas/AddPaymail"
required:
- paymail

parameters:
PageNumber:
in: query
Expand Down
7 changes: 7 additions & 0 deletions api/components/responses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,10 @@ components:
- $ref: "./errors.yaml#/components/schemas/BHSUnhealthy"
- $ref: "./errors.yaml#/components/schemas/BHSBadURL"
- $ref: "./errors.yaml#/components/schemas/BHSParsingResponse"

PaymailAddress:
description: Paymail address created successfully
content:
application/json:
schema:
$ref: "./models.yaml#/components/schemas/Paymail"
25 changes: 25 additions & 0 deletions api/endpoints/user.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,28 @@ paths:
$ref: "../components/responses.yaml#/components/responses/GetMerklerootsConflict"
500:
$ref: "../components/responses.yaml#/components/responses/GetMerklerootsInternalServerError"

/api/v2/users/address:
post:
summary: Create Paymail Address
operationId: createAddress
security:
- XPubAuth:
- user
requestBody:
required: true
content:
application/json:
schema:
$ref: "../components/requests.yaml#/components/schemas/CreatePaymailAddress"
responses:
"200":
$ref: "../components/responses.yaml#/components/responses/PaymailAddress"
"400":
$ref: "../components/responses.yaml#/components/responses/UserBadRequest"
"401":
$ref: "../components/responses.yaml#/components/responses/UserNotAuthorized"
"500":
$ref: "../components/responses.yaml#/components/responses/InternalServerError"
tags:
- User
19 changes: 19 additions & 0 deletions api/gen.api.go

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

37 changes: 37 additions & 0 deletions api/gen.api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,30 @@ paths:
summary: Create transaction outline
tags:
- Transactions
/api/v2/users/address:
post:
operationId: createAddress
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/requests_CreatePaymailAddress'
required: true
responses:
"200":
$ref: '#/components/responses/responses_PaymailAddress'
"400":
$ref: '#/components/responses/responses_UserBadRequest'
"401":
$ref: '#/components/responses/responses_UserNotAuthorized'
"500":
$ref: '#/components/responses/responses_InternalServerError'
security:
- XPubAuth:
- user
summary: Create Paymail Address
tags:
- User
/api/v2/users/current:
get:
description: This endpoint return balance of current authenticated user
Expand Down Expand Up @@ -468,6 +492,12 @@ components:
schema:
$ref: '#/components/schemas/errors_AdminAuthorization'
description: Security requirements failed
responses_PaymailAddress:
content:
application/json:
schema:
$ref: '#/components/schemas/models_Paymail'
description: Paymail address created successfully
responses_RecordTransactionBadRequest:
content:
application/json:
Expand Down Expand Up @@ -1312,6 +1342,13 @@ components:
- alias
- domain
type: object
requests_CreatePaymailAddress:
properties:
paymail:
$ref: '#/components/schemas/requests_AddPaymail'
required:
- paymail
type: object
requests_CreateUser:
properties:
paymail:
Expand Down
11 changes: 11 additions & 0 deletions api/gen.models.go

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

Loading
Loading