Files
ark/server/internal/core/application/admin.go
Louis Singer ff96524f22 Ark Notes (#379)
* ark credits

* rename "ecash" --> "ark credit"

* rework note_test.go

* NewFromString

* create several notes

* note repo: rename "push" to "add"

* RegisterInputsForNextRoundRequest: move "notes" to field #3

* use uint64 as note ID

* rename to voucher

* add nostr notification

* nostr notification test and fixes

* bump badger to 4.3

* allow npub to be registered

* rename poolTxID

* add default relays

* Update server/internal/config/config.go

Co-authored-by: Marco Argentieri <3596602+tiero@users.noreply.github.com>

* fix RedeemVouchers test

* notification = voucher

* WASM wrappers

* fix arkd voucher cmd

* test_utils.go ignore gosec rule G101

* fix permissions

* rename ALL to notes

* add URI prefix

* note.go : fix signature encoding

* fix decode note.Data

* Update server/internal/infrastructure/notifier/nostr/nostr.go

Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>

* Update pkg/client-sdk/wasm/browser/wrappers.go

Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>

* Update server/internal/infrastructure/notifier/nostr/nostr.go

Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>

* rework note and entity db + sqlite implementations

* NOTIFICATION_PREFIX -> NOTE_URI_PREFIX

* validate NOTE_URI_PREFIX

* Update defaults to convenant-less mainnet (#2)

* config: defaults to convenant-less tx builder

* Drop env var for blockchain scanner

---------

Co-authored-by: altafan <18440657+altafan@users.noreply.github.com>

* add // before URI prefix

* add URI prefix in admin CreateNote

* Fixes

* rework nonces encoding (#4)

* rework nonces encoding

* add a check in Musig2Nonce decode function

* musig2_test: increase number of signers to 20

* musig2.json: add a test case with a 35 leaves tree

* GetEventStream REST rework

* fix round phases time intervals

* [SDK] Use server-side streams in rest client

* Fix history

* make the URI optional

* Updates

* Fix settled txs in history

* fix e2e test

* go work sync in sdk unit test

* fix signMessage in btc and liquid sdk wallets

---------

Co-authored-by: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>
2024-11-15 19:07:33 +01:00

205 lines
5.1 KiB
Go

package application
import (
"context"
"github.com/ark-network/ark/common/note"
"github.com/ark-network/ark/server/internal/core/ports"
)
type Balance struct {
Locked uint64
Available uint64
}
type ArkProviderBalance struct {
MainAccountBalance Balance
ConnectorsAccountBalance Balance
}
type SweepableOutput struct {
TxId string
Vout uint32
Amount uint64
ScheduledAt int64
}
type ScheduledSweep struct {
RoundId string
SweepableOutputs []SweepableOutput
}
type RoundDetails struct {
RoundId string
TxId string
ForfeitedAmount uint64
TotalVtxosAmount uint64
TotalExitAmount uint64
FeesAmount uint64
InputsVtxos []string
OutputsVtxos []string
ExitAddresses []string
}
type AdminService interface {
Wallet() ports.WalletService
GetScheduledSweeps(ctx context.Context) ([]ScheduledSweep, error)
GetRoundDetails(ctx context.Context, roundId string) (*RoundDetails, error)
GetRounds(ctx context.Context, after int64, before int64) ([]string, error)
GetWalletAddress(ctx context.Context) (string, error)
GetWalletStatus(ctx context.Context) (*WalletStatus, error)
CreateNotes(ctx context.Context, amount uint32, quantity int) ([]string, error)
}
type adminService struct {
walletSvc ports.WalletService
repoManager ports.RepoManager
txBuilder ports.TxBuilder
sweeperTimeUnit ports.TimeUnit
}
func NewAdminService(walletSvc ports.WalletService, repoManager ports.RepoManager, txBuilder ports.TxBuilder, timeUnit ports.TimeUnit) AdminService {
return &adminService{
walletSvc: walletSvc,
repoManager: repoManager,
txBuilder: txBuilder,
sweeperTimeUnit: timeUnit,
}
}
func (a *adminService) Wallet() ports.WalletService {
return a.walletSvc
}
func (a *adminService) GetRoundDetails(ctx context.Context, roundId string) (*RoundDetails, error) {
round, err := a.repoManager.Rounds().GetRoundWithId(ctx, roundId)
if err != nil {
return nil, err
}
roundDetails := &RoundDetails{
RoundId: round.Id,
TxId: round.Txid,
ForfeitedAmount: 0,
TotalVtxosAmount: 0,
TotalExitAmount: 0,
ExitAddresses: []string{},
FeesAmount: 0,
InputsVtxos: []string{},
OutputsVtxos: []string{},
}
for _, payment := range round.Payments {
// TODO: Add fees amount
roundDetails.ForfeitedAmount += payment.TotalInputAmount()
for _, receiver := range payment.Receivers {
if receiver.IsOnchain() {
roundDetails.TotalExitAmount += receiver.Amount
roundDetails.ExitAddresses = append(roundDetails.ExitAddresses, receiver.OnchainAddress)
continue
}
roundDetails.TotalVtxosAmount += receiver.Amount
}
for _, input := range payment.Inputs {
roundDetails.InputsVtxos = append(roundDetails.InputsVtxos, input.Txid)
}
}
vtxos, err := a.repoManager.Vtxos().GetVtxosForRound(ctx, round.Txid)
if err != nil {
return nil, err
}
for _, vtxo := range vtxos {
roundDetails.OutputsVtxos = append(roundDetails.OutputsVtxos, vtxo.Txid)
}
return roundDetails, nil
}
func (a *adminService) GetRounds(ctx context.Context, after int64, before int64) ([]string, error) {
return a.repoManager.Rounds().GetRoundsIds(ctx, after, before)
}
func (a *adminService) GetScheduledSweeps(ctx context.Context) ([]ScheduledSweep, error) {
sweepableRounds, err := a.repoManager.Rounds().GetSweepableRounds(ctx)
if err != nil {
return nil, err
}
scheduledSweeps := make([]ScheduledSweep, 0, len(sweepableRounds))
for _, round := range sweepableRounds {
sweepable, err := findSweepableOutputs(
ctx, a.walletSvc, a.txBuilder, a.sweeperTimeUnit, round.CongestionTree,
)
if err != nil {
return nil, err
}
sweepableOutputs := make([]SweepableOutput, 0)
for expirationTime, inputs := range sweepable {
for _, input := range inputs {
sweepableOutputs = append(sweepableOutputs, SweepableOutput{
TxId: input.GetHash().String(),
Vout: input.GetIndex(),
Amount: input.GetAmount(),
ScheduledAt: expirationTime,
})
}
}
scheduledSweeps = append(scheduledSweeps, ScheduledSweep{
RoundId: round.Id,
SweepableOutputs: sweepableOutputs,
})
}
return scheduledSweeps, nil
}
func (a *adminService) GetWalletAddress(ctx context.Context) (string, error) {
addresses, err := a.walletSvc.DeriveAddresses(ctx, 1)
if err != nil {
return "", err
}
return addresses[0], nil
}
func (a *adminService) GetWalletStatus(ctx context.Context) (*WalletStatus, error) {
status, err := a.walletSvc.Status(ctx)
if err != nil {
return nil, err
}
return &WalletStatus{
IsInitialized: status.IsInitialized(),
IsUnlocked: status.IsUnlocked(),
IsSynced: status.IsSynced(),
}, nil
}
func (a *adminService) CreateNotes(ctx context.Context, value uint32, quantity int) ([]string, error) {
notes := make([]string, 0, quantity)
for i := 0; i < quantity; i++ {
data, err := note.New(value)
if err != nil {
return nil, err
}
noteHash := data.Hash()
signature, err := a.walletSvc.SignMessage(ctx, noteHash)
if err != nil {
return nil, err
}
note := data.ToNote(signature)
notes = append(notes, note.String())
}
return notes, nil
}