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

Track terms of use #88

Merged
merged 3 commits into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,46 @@ const docTemplate = `{
}
}
},
"/terms-acceptance": {
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved
"post": {
"description": "Accept terms by the staker's BTC address (Taproot or Native Segwit)",
"produces": [
"application/json"
],
"parameters": [
{
"type": "string",
"description": "Staker BTC address in Taproot/Native Segwit format",
"name": "address",
"in": "query",
"required": true
},
{
"description": "Terms acceptance request",
"name": "terms_accepted",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.TermsAcceptanceRequest"
}
}
],
"responses": {
"200": {
"description": "Terms acceptance result",
"schema": {
"$ref": "#/definitions/handlers.TermsAcceptancePublic"
}
},
"400": {
"description": "Error: Bad Request",
"schema": {
"$ref": "#/definitions/github_com_babylonlabs-io_staking-api-service_internal_types.Error"
}
}
}
}
},
"/v1/delegation": {
"get": {
"description": "Retrieves a delegation by a given transaction hash",
Expand Down Expand Up @@ -474,6 +514,22 @@ const docTemplate = `{
}
}
},
"handlers.TermsAcceptancePublic": {
"type": "object",
"properties": {
"status": {
"type": "boolean"
}
}
},
"handlers.TermsAcceptanceRequest": {
"type": "object",
"properties": {
"terms_accepted": {
"type": "boolean"
}
}
},
"handlers.UnbondDelegationRequestPayload": {
"type": "object",
"properties": {
Expand Down
56 changes: 56 additions & 0 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,46 @@
}
}
},
"/terms-acceptance": {
"post": {
"description": "Accept terms by the staker's BTC address (Taproot or Native Segwit)",
"produces": [
"application/json"
],
"parameters": [
{
"type": "string",
"description": "Staker BTC address in Taproot/Native Segwit format",
"name": "address",
"in": "query",
"required": true
},
{
"description": "Terms acceptance request",
"name": "terms_accepted",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.TermsAcceptanceRequest"
}
}
],
"responses": {
"200": {
"description": "Terms acceptance result",
"schema": {
"$ref": "#/definitions/handlers.TermsAcceptancePublic"
}
},
"400": {
"description": "Error: Bad Request",
"schema": {
"$ref": "#/definitions/github_com_babylonlabs-io_staking-api-service_internal_types.Error"
}
}
}
}
},
"/v1/delegation": {
"get": {
"description": "Retrieves a delegation by a given transaction hash",
Expand Down Expand Up @@ -466,6 +506,22 @@
}
}
},
"handlers.TermsAcceptancePublic": {
"type": "object",
"properties": {
"status": {
"type": "boolean"
}
}
},
"handlers.TermsAcceptanceRequest": {
"type": "object",
"properties": {
"terms_accepted": {
"type": "boolean"
}
}
},
"handlers.UnbondDelegationRequestPayload": {
"type": "object",
"properties": {
Expand Down
36 changes: 36 additions & 0 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ definitions:
status:
type: integer
type: object
handlers.TermsAcceptancePublic:
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved
properties:
status:
type: boolean
type: object
handlers.TermsAcceptanceRequest:
properties:
terms_accepted:
type: boolean
type: object
handlers.UnbondDelegationRequestPayload:
properties:
staker_signed_signature_hex:
Expand Down Expand Up @@ -257,6 +267,32 @@ paths:
schema:
type: string
summary: Health check endpoint
/terms-acceptance:
post:
description: Accept terms by the staker's BTC address (Taproot or Native Segwit)
parameters:
- description: Staker BTC address in Taproot/Native Segwit format
in: query
name: address
required: true
type: string
- description: Terms acceptance request
in: body
name: terms_accepted
required: true
schema:
$ref: '#/definitions/handlers.TermsAcceptanceRequest'
produces:
- application/json
responses:
"200":
description: Terms acceptance result
schema:
$ref: '#/definitions/handlers.TermsAcceptancePublic'
"400":
description: 'Error: Bad Request'
schema:
$ref: '#/definitions/github_com_babylonlabs-io_staking-api-service_internal_types.Error'
/v1/delegation:
get:
description: Retrieves a delegation by a given transaction hash
Expand Down
47 changes: 47 additions & 0 deletions internal/api/handlers/terms.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package handlers

import (
"encoding/json"
"net/http"

"github.com/babylonlabs-io/staking-api-service/internal/types"
)

type TermsAcceptanceRequest struct {
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved
TermsAccepted bool `json:"terms_accepted"`
}

type TermsAcceptancePublic struct {
Status bool `json:"status"`
}

// AcceptTerms @Summary Accept terms
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved
// @Description Track terms acceptance by the staker's BTC address (Taproot or Native Segwit)
// @Produce json
// @Param address query string true "Staker BTC address in Taproot/Native Segwit format"
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved
// @Param terms_accepted body TermsAcceptanceRequest true "Terms acceptance request"
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved
// @Success 200 {object} TermsAcceptancePublic "Terms acceptance result"
// @Failure 400 {object} types.Error "Error: Bad Request"
// @Router /terms-acceptance [post]
func (h *Handler) AcceptTerms(request *http.Request) (*Result, *types.Error) {
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved
address, err := parseBtcAddressQuery(request, "address", h.config.Server.BTCNetParam)
if err != nil {
return nil, err
}

publicKey, err := parsePublicKeyQuery(request, "public_key", false)
if err != nil {
return nil, err
}

var req TermsAcceptanceRequest
if err := json.NewDecoder(request.Body).Decode(&req); err != nil {
return nil, types.NewErrorWithMsg(http.StatusBadRequest, types.BadRequest, "Invalid request payload")
}
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved

if err := h.services.AcceptTerms(request.Context(), address, publicKey, req.TermsAccepted); err != nil {
return nil, err
}

return NewResult(TermsAcceptancePublic{Status: true}), nil
}
1 change: 1 addition & 0 deletions internal/api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
func (a *Server) SetupRoutes(r *chi.Mux) {
handlers := a.handlers
r.Get("/healthcheck", registerHandler(handlers.HealthCheck))
r.Post("/terms-acceptance", registerHandler(handlers.AcceptTerms))
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved

r.Get("/v1/staker/delegations", registerHandler(handlers.GetStakerDelegations))
r.Post("/v1/unbonding", registerHandler(handlers.UnbondDelegation))
Expand Down
2 changes: 2 additions & 0 deletions internal/db/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ type DBClient interface {
ctx context.Context,
paginationToken string,
) (*DbResultMap[model.DelegationDocument], error)
// Accept terms saves the acceptance of the terms of service of the public key
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved
SaveTermsAcceptance(ctx context.Context, termsAcceptance *model.TermsAcceptance) error
}

type DelegationFilter struct {
Expand Down
2 changes: 2 additions & 0 deletions internal/db/model/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (
BtcInfoCollection = "btc_info"
UnprocessableMsgCollection = "unprocessable_messages"
PkAddressMappingsCollection = "pk_address_mappings"
TermsAcceptanceCollection = "terms_acceptance"
)

type index struct {
Expand All @@ -48,6 +49,7 @@ var collections = map[string][]index{
{Indexes: map[string]int{"native_segwit_odd": 1}, Unique: true},
{Indexes: map[string]int{"native_segwit_even": 1}, Unique: true},
},
TermsAcceptanceCollection: {{Indexes: map[string]int{"address": 1, "public_key": 1}, Unique: true}},
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved
}

func Setup(ctx context.Context, cfg *config.Config) error {
Expand Down
10 changes: 10 additions & 0 deletions internal/db/model/terms.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package model

import "time"

type TermsAcceptance struct {
Address string `bson:"address"`
PublicKey string `bson:"public_key"`
TermsAccepted bool `bson:"terms_accepted"`
UpdatedAt time.Time `bson:"updated_at"`
}
28 changes: 28 additions & 0 deletions internal/db/terms.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package db

import (
"context"

"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"

"github.com/babylonlabs-io/staking-api-service/internal/db/model"
)

func (db *Database) SaveTermsAcceptance(ctx context.Context, termsAcceptance *model.TermsAcceptance) error {
collection := db.Client.Database(db.DbName).Collection(model.TermsAcceptanceCollection)

filter := bson.M{
"address": termsAcceptance.Address,
"public_key": termsAcceptance.PublicKey,
}

update := bson.M{
"$setOnInsert": termsAcceptance,
}

opts := options.Update().SetUpsert(true)

_, err := collection.UpdateOne(ctx, filter, update, opts)
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved
return err
}
27 changes: 27 additions & 0 deletions internal/services/terms.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package services

import (
"context"
"net/http"

"github.com/babylonlabs-io/staking-api-service/internal/db/model"
"github.com/babylonlabs-io/staking-api-service/internal/types"
)

func (s *Services) AcceptTerms(ctx context.Context, address, publicKey string, termsAccepted bool) *types.Error {
if address == "" || publicKey == "" {
jeremy-babylonlabs marked this conversation as resolved.
Show resolved Hide resolved
return types.NewErrorWithMsg(http.StatusBadRequest, types.BadRequest, "Address and public key are required")
}

termsAcceptance := &model.TermsAcceptance{
Address: address,
PublicKey: publicKey,
TermsAccepted: termsAccepted,
}

if err := s.DbClient.SaveTermsAcceptance(ctx, termsAcceptance); err != nil {
return types.NewInternalServiceError(err)
}

return nil
}
Loading