dev-api-aliases #5

Merged
lash merged 6 commits from dev-api-aliases into master 2025-01-21 07:17:09 +01:00
3 changed files with 170 additions and 110 deletions

View File

@ -12,65 +12,67 @@ import (
"strings" "strings"
"time" "time"
"github.com/gofrs/uuid"
"git.defalsify.org/vise.git/logging"
"git.defalsify.org/vise.git/db" "git.defalsify.org/vise.git/db"
"git.grassecon.net/grassrootseconomics/sarafu-api/models" "git.defalsify.org/vise.git/logging"
"git.grassecon.net/grassrootseconomics/sarafu-api/event"
"git.grassecon.net/grassrootseconomics/common/phone" "git.grassecon.net/grassrootseconomics/common/phone"
"git.grassecon.net/grassrootseconomics/sarafu-api/event"
"git.grassecon.net/grassrootseconomics/sarafu-api/models"
"git.grassecon.net/grassrootseconomics/visedriver/storage" "git.grassecon.net/grassrootseconomics/visedriver/storage"
"github.com/gofrs/uuid"
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
) )
var ( var (
logg = logging.NewVanilla().WithDomain("sarafu-api.devapi") logg = logging.NewVanilla().WithDomain("sarafu-api.devapi")
aliasRegex = regexp.MustCompile("^\\+?[a-zA-Z0-9\\-_]+$") aliasRegex = regexp.MustCompile("^\\+?[a-zA-Z0-9\\-_]+$")
searchDomain = ".sarafu.local"
Outdated
Review

Export please

Export please
@lash Should be moved to: https://git.grassecon.net/grassrootseconomics/common?
Outdated
Review

no its fine here, it's for dev only anyway.

no its fine here, it's for dev only anyway.
) )
const ( const (
pubKeyLen int = 20 pubKeyLen int = 20
hashLen int = 32 hashLen int = 32
defaultDecimals = 6 defaultDecimals = 6
zeroAddress string = "0x0000000000000000000000000000000000000000" zeroAddress string = "0x0000000000000000000000000000000000000000"
defaultVoucherBalance float64 = 500.00
) )
type Tx struct { type Tx struct {
Track string `json: "track"` Track string `json: "track"`
Hsh string `json:"hash"` Hsh string `json:"hash"`
To string `json:"to"` To string `json:"to"`
From string `json: "from"` From string `json: "from"`
Voucher string `json: "voucher"` Voucher string `json: "voucher"`
Value int `json: "value"` Value int `json: "value"`
When time.Time `json: "when"` When time.Time `json: "when"`
} }
func (t *Tx) ToTransferEvent() event.EventTokenTransfer { func (t *Tx) ToTransferEvent() event.EventTokenTransfer {
return event.EventTokenTransfer{ return event.EventTokenTransfer{
To: t.To, To: t.To,
Value: t.Value, Value: t.Value,
VoucherAddress: t.Voucher, VoucherAddress: t.Voucher,
TxHash: t.Hsh, TxHash: t.Hsh,
From: t.From, From: t.From,
} }
} }
func (t *Tx) ToMintEvent() event.EventTokenMint { func (t *Tx) ToMintEvent() event.EventTokenMint {
return event.EventTokenMint{ return event.EventTokenMint{
To: t.To, To: t.To,
Value: t.Value, Value: t.Value,
VoucherAddress: t.Voucher, VoucherAddress: t.Voucher,
TxHash: t.Hsh, TxHash: t.Hsh,
} }
} }
type Account struct { type Account struct {
Track string `json: "track"` Track string `json: "track"`
Address string `json: "address"` Address string `json: "address"`
Nonce int `json: "nonce"` Nonce int `json: "nonce"`
DefaultVoucher string `json: "defaultVoucher"` DefaultVoucher string `json: "defaultVoucher"`
Balances map[string]int `json: "balances"` Balances map[string]int `json: "balances"`
Alias string Alias string
Txs []string `json: "txs"` Txs []string `json: "txs"`
} }
func (a *Account) ToRegistrationEvent() event.EventCustodialRegistration { func (a *Account) ToRegistrationEvent() event.EventCustodialRegistration {
@ -80,45 +82,44 @@ func (a *Account) ToRegistrationEvent() event.EventCustodialRegistration {
} }
type Voucher struct { type Voucher struct {
Name string `json: "name"` Name string `json: "name"`
Address string `json: "address"` Address string `json: "address"`
Symbol string `json: "symbol"` Symbol string `json: "symbol"`
Decimals int `json: "decimals"` Decimals int `json: "decimals"`
Sink string `json: "sink"` Sink string `json: "sink"`
Commodity string `json: "commodity"` Commodity string `json: "commodity"`
Location string `json: "location"` Location string `json: "location"`
} }
type DevAccountService struct { type DevAccountService struct {
db db.Db db db.Db
accounts map[string]Account accounts map[string]Account
accountsTrack map[string]string accountsTrack map[string]string
accountsAlias map[string]string accountsAlias map[string]string
vouchers map[string]Voucher vouchers map[string]Voucher
vouchersAddress map[string]string vouchersAddress map[string]string
txs map[string]Tx txs map[string]Tx
txsTrack map[string]string txsTrack map[string]string
toAutoCreate bool toAutoCreate bool
autoVouchers []string autoVouchers []string
autoVoucherValue map[string]int autoVoucherValue map[string]int
defaultAccount string defaultAccount string
emitterFunc event.EmitterFunc emitterFunc event.EmitterFunc
pfx []byte pfx []byte
Review

remove commentedp lease

remove commentedp lease
// accountsSession map[string]string
} }
func NewDevAccountService(ctx context.Context, ss storage.StorageService) *DevAccountService { func NewDevAccountService(ctx context.Context, ss storage.StorageService) *DevAccountService {
svc := &DevAccountService{ svc := &DevAccountService{
accounts: make(map[string]Account), accounts: make(map[string]Account),
accountsTrack: make(map[string]string), accountsTrack: make(map[string]string),
accountsAlias: make(map[string]string), accountsAlias: make(map[string]string),
vouchers: make(map[string]Voucher), vouchers: make(map[string]Voucher),
vouchersAddress: make(map[string]string), vouchersAddress: make(map[string]string),
txs: make(map[string]Tx), txs: make(map[string]Tx),
txsTrack: make(map[string]string), txsTrack: make(map[string]string),
autoVoucherValue: make(map[string]int), autoVoucherValue: make(map[string]int),
defaultAccount: zeroAddress, defaultAccount: zeroAddress,
pfx: []byte("__"), pfx: []byte("__"),
} }
if ss != nil { if ss != nil {
var err error var err error
@ -151,7 +152,7 @@ func (das *DevAccountService) WithPrefix(pfx []byte) *DevAccountService {
} }
func (das *DevAccountService) prefixKeyFor(k string, v string) []byte { func (das *DevAccountService) prefixKeyFor(k string, v string) []byte {
return append(das.pfx, []byte(k + "_" + v)...) return append(das.pfx, []byte(k+"_"+v)...)
} }
func (das *DevAccountService) loadAccount(ctx context.Context, pubKey string, v []byte) error { func (das *DevAccountService) loadAccount(ctx context.Context, pubKey string, v []byte) error {
@ -183,6 +184,15 @@ func (das *DevAccountService) loadTx(ctx context.Context, hsh string, v []byte)
return nil return nil
} }
func (das *DevAccountService) loadAlias(ctx context.Context, alias string, key []byte) error {
result, err := das.db.Get(ctx, key)
if err != nil {
return err
}
das.accountsAlias[alias] = strings.ReplaceAll(string(result), `"`, "")
return nil
}
func (das *DevAccountService) loadItem(ctx context.Context, k []byte, v []byte) error { func (das *DevAccountService) loadItem(ctx context.Context, k []byte, v []byte) error {
var err error var err error
s := string(k) s := string(k)
@ -194,6 +204,8 @@ func (das *DevAccountService) loadItem(ctx context.Context, k []byte, v []byte)
err = das.loadAccount(ctx, ss[1], v) err = das.loadAccount(ctx, ss[1], v)
} else if ss[0] == "tx" { } else if ss[0] == "tx" {
err = das.loadTx(ctx, ss[1], v) err = das.loadTx(ctx, ss[1], v)
} else if ss[0] == "alias" {
err = das.loadAlias(ctx, ss[1], k)
} else { } else {
logg.ErrorCtxf(ctx, "unknown double underscore key", "key", ss[0]) logg.ErrorCtxf(ctx, "unknown double underscore key", "key", ss[0])
} }
@ -225,7 +237,7 @@ func (das *DevAccountService) loadAll(ctx context.Context) error {
} }
func (das *DevAccountService) indexAll(ctx context.Context) error { func (das *DevAccountService) indexAll(ctx context.Context) error {
for k, v := range(das.txs) { for k, v := range das.txs {
acc := das.accounts[v.From] acc := das.accounts[v.From]
acc.Txs = append(acc.Txs, k) acc.Txs = append(acc.Txs, k)
logg.TraceCtxf(ctx, "add tx to sender index", "from", v.From, "tx", k) logg.TraceCtxf(ctx, "add tx to sender index", "from", v.From, "tx", k)
@ -265,8 +277,8 @@ func (das *DevAccountService) AddVoucher(ctx context.Context, symbol string) err
z := h.Sum(nil) z := h.Sum(nil)
address := fmt.Sprintf("0x%x", z) address := fmt.Sprintf("0x%x", z)
das.vouchers[symbol] = Voucher{ das.vouchers[symbol] = Voucher{
Name: symbol, Name: symbol,
Symbol: symbol, Symbol: symbol,
Address: address, Address: address,
} }
das.vouchersAddress[address] = symbol das.vouchersAddress[address] = symbol
@ -288,14 +300,14 @@ func (das *DevAccountService) CheckBalance(ctx context.Context, publicKey string
if !ok { if !ok {
return nil, fmt.Errorf("balance not found for default token %s pubkey %v", acc.DefaultVoucher, publicKey) return nil, fmt.Errorf("balance not found for default token %s pubkey %v", acc.DefaultVoucher, publicKey)
} }
return &models.BalanceResult { return &models.BalanceResult{
Balance: strconv.Itoa(bal), Balance: strconv.Itoa(bal),
Nonce: json.Number(strconv.Itoa(acc.Nonce)), Nonce: json.Number(strconv.Itoa(acc.Nonce)),
}, nil }, nil
} }
func (das *DevAccountService) balanceAuto(ctx context.Context, pubKey string) error { func (das *DevAccountService) balanceAuto(ctx context.Context, pubKey string) error {
for _, v := range(das.autoVouchers) { for _, v := range das.autoVouchers {
voucher, ok := das.vouchers[v] voucher, ok := das.vouchers[v]
if !ok { if !ok {
return fmt.Errorf("balance auto voucher set but not resolved: %s", v) return fmt.Errorf("balance auto voucher set but not resolved: %s", v)
@ -312,6 +324,10 @@ func (das *DevAccountService) balanceAuto(ctx context.Context, pubKey string) er
return nil return nil
} }
func (das *DevAccountService) GetAliases(ctx context.Context) map[string]string {
return das.accountsAlias
}
func (das *DevAccountService) saveAccount(ctx context.Context, acc Account) error { func (das *DevAccountService) saveAccount(ctx context.Context, acc Account) error {
if das.db == nil { if das.db == nil {
return nil return nil
@ -326,6 +342,27 @@ func (das *DevAccountService) saveAccount(ctx context.Context, acc Account) erro
return das.db.Put(ctx, []byte(k), v) return das.db.Put(ctx, []byte(k), v)
} }
func (das *DevAccountService) saveAlias(ctx context.Context, alias map[string]string) error {
if das.db == nil {
return fmt.Errorf("Db cannot be nil")
}
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return fmt.Errorf("unresolved session id")
Outdated
Review

This is probably not correct? Alias is bound to a session, right?

This is probably not correct? Alias is bound to a session, right?

Yeah that's right.Resolved by: ed549cba70

Yeah that's right.Resolved by: ed549cba7046818638f28ce28fae15c3eb344bc8
}
for k, v := range alias {
k_ := das.prefixKeyFor("alias", k)
v_, err := json.Marshal(v)
if err != nil {
return err
}
das.db.SetSession(sessionId)
das.db.SetPrefix(db.DATATYPE_USERDATA)
return das.db.Put(ctx, []byte(k_), v_)
}
return nil
}
func (das *DevAccountService) CreateAccount(ctx context.Context) (*models.AccountResult, error) { func (das *DevAccountService) CreateAccount(ctx context.Context) (*models.AccountResult, error) {
var b [pubKeyLen]byte var b [pubKeyLen]byte
uid, err := uuid.NewV4() uid, err := uuid.NewV4()
@ -341,7 +378,7 @@ func (das *DevAccountService) CreateAccount(ctx context.Context) (*models.Accoun
} }
pubKey := fmt.Sprintf("0x%x", b) pubKey := fmt.Sprintf("0x%x", b)
acc := Account{ acc := Account{
Track: uid.String(), Track: uid.String(),
Address: pubKey, Address: pubKey,
} }
@ -363,7 +400,7 @@ func (das *DevAccountService) CreateAccount(ctx context.Context) (*models.Accoun
if das.emitterFunc != nil { if das.emitterFunc != nil {
msg := event.Msg{ msg := event.Msg{
Typ: event.EventRegistrationTag, Typ: event.EventRegistrationTag,
Item: acc, Item: acc,
} }
err = das.emitterFunc(ctx, msg) err = das.emitterFunc(ctx, msg)
@ -374,7 +411,7 @@ func (das *DevAccountService) CreateAccount(ctx context.Context) (*models.Accoun
logg.TraceCtxf(ctx, "account created", "account", acc) logg.TraceCtxf(ctx, "account created", "account", acc)
return &models.AccountResult{ return &models.AccountResult{
PublicKey: pubKey, PublicKey: pubKey,
TrackingId: uid.String(), TrackingId: uid.String(),
}, nil }, nil
} }
@ -392,22 +429,20 @@ func (das *DevAccountService) TrackAccountStatus(ctx context.Context, publicKey
func (das *DevAccountService) FetchVouchers(ctx context.Context, publicKey string) ([]dataserviceapi.TokenHoldings, error) { func (das *DevAccountService) FetchVouchers(ctx context.Context, publicKey string) ([]dataserviceapi.TokenHoldings, error) {
var holdings []dataserviceapi.TokenHoldings var holdings []dataserviceapi.TokenHoldings
acc, ok := das.accounts[publicKey] _, ok := das.accounts[publicKey]
if !ok { if !ok {
return nil, fmt.Errorf("account not found (publickey): %v", publicKey) return nil, fmt.Errorf("account not found (publickey): %v", publicKey)
Outdated
Review

Why hardcoded number?

Why hardcoded number?
} }
for k, v := range(acc.Balances) { //TODO: Iterate over the account acc.Balances object
voucher, ok := das.vouchers[k] for _, voucher := range das.vouchers {
if !ok {
return nil, fmt.Errorf("voucher has balance but object not found: %v", k)
}
holdings = append(holdings, dataserviceapi.TokenHoldings{ holdings = append(holdings, dataserviceapi.TokenHoldings{
ContractAddress: voucher.Address, ContractAddress: voucher.Address,
TokenSymbol: voucher.Symbol, TokenSymbol: voucher.Symbol,
TokenDecimals: strconv.Itoa(voucher.Decimals), TokenDecimals: strconv.Itoa(voucher.Decimals),
Balance: strconv.Itoa(v), Balance: strconv.Itoa(int(defaultVoucherBalance)),
}) })
} }
return holdings, nil return holdings, nil
} }
@ -417,24 +452,24 @@ func (das *DevAccountService) FetchTransactions(ctx context.Context, publicKey s
if !ok { if !ok {
return nil, fmt.Errorf("account not found (publickey): %v", publicKey) return nil, fmt.Errorf("account not found (publickey): %v", publicKey)
} }
for i, v := range(acc.Txs) { for i, v := range acc.Txs {
mytx := das.txs[v] mytx := das.txs[v]
if i == 10 { if i == 10 {
break break
} }
voucher, ok := das.vouchers[mytx.Voucher] voucher, ok := das.vouchers[mytx.Voucher]
if !ok { if !ok {
return nil, fmt.Errorf("voucher %s in tx list but not found in voucher list", mytx.Voucher) return nil, fmt.Errorf("voucher %s in tx list but not found in voucher list", mytx.Voucher)
} }
lasttx = append(lasttx, dataserviceapi.Last10TxResponse{ lasttx = append(lasttx, dataserviceapi.Last10TxResponse{
Sender: mytx.From, Sender: mytx.From,
Recipient: mytx.To, Recipient: mytx.To,
TransferValue: strconv.Itoa(mytx.Value), TransferValue: strconv.Itoa(mytx.Value),
ContractAddress: voucher.Address, ContractAddress: voucher.Address,
TxHash: mytx.Hsh, TxHash: mytx.Hsh,
DateBlock: mytx.When, DateBlock: mytx.When,
TokenSymbol: voucher.Symbol, TokenSymbol: voucher.Symbol,
TokenDecimals: strconv.Itoa(voucher.Decimals), TokenDecimals: strconv.Itoa(voucher.Decimals),
}) })
} }
return lasttx, nil return lasttx, nil
@ -450,13 +485,12 @@ func (das *DevAccountService) VoucherData(ctx context.Context, address string) (
return nil, fmt.Errorf("voucher address %v found but does not resolve", address) return nil, fmt.Errorf("voucher address %v found but does not resolve", address)
} }
return &models.VoucherDataResult{ return &models.VoucherDataResult{
TokenName: voucher.Name, TokenName: voucher.Name,
TokenSymbol: voucher.Symbol, TokenSymbol: voucher.Symbol,
TokenDecimals: voucher.Decimals, TokenDecimals: voucher.Decimals,
SinkAddress: voucher.Sink, SinkAddress: voucher.Sink,
TokenCommodity: voucher.Commodity, TokenCommodity: voucher.Commodity,
TokenLocation: voucher.Location, TokenLocation: voucher.Location,
}, nil }, nil
} }
@ -481,12 +515,12 @@ func (das *DevAccountService) TokenTransfer(ctx context.Context, amount, from, t
} }
accFrom, ok := das.accounts[from] accFrom, ok := das.accounts[from]
if !ok { if !ok {
return nil, fmt.Errorf("sender account %v not found", from) return nil, fmt.Errorf("sender account %v not found", from)
} }
accTo, ok := das.accounts[to] accTo, ok := das.accounts[to]
if !ok { if !ok {
if !das.toAutoCreate { if !das.toAutoCreate {
return nil, fmt.Errorf("recipient account %v not found, and not creating", from) return nil, fmt.Errorf("recipient account %v not found, and not creating", from)
} }
} }
@ -512,13 +546,13 @@ func (das *DevAccountService) TokenTransfer(ctx context.Context, amount, from, t
} }
hsh := fmt.Sprintf("0x%x", b) hsh := fmt.Sprintf("0x%x", b)
mytx := Tx{ mytx := Tx{
Hsh: hsh, Hsh: hsh,
To: accTo.Address, To: accTo.Address,
From: accFrom.Address, From: accFrom.Address,
Voucher: voucher.Symbol, Voucher: voucher.Symbol,
Value: value, Value: value,
Track: uid.String(), Track: uid.String(),
When: time.Now(), When: time.Now(),
} }
err = das.saveTokenTransfer(ctx, mytx) err = das.saveTokenTransfer(ctx, mytx)
if err != nil { if err != nil {
@ -527,7 +561,7 @@ func (das *DevAccountService) TokenTransfer(ctx context.Context, amount, from, t
das.txs[hsh] = mytx das.txs[hsh] = mytx
if das.emitterFunc != nil { if das.emitterFunc != nil {
msg := event.Msg{ msg := event.Msg{
Typ: event.EventTokenTransferTag, Typ: event.EventTokenTransferTag,
Item: mytx, Item: mytx,
} }
err = das.emitterFunc(ctx, msg) err = das.emitterFunc(ctx, msg)
@ -568,12 +602,22 @@ func (das *DevAccountService) applyPhoneAlias(ctx context.Context, publicKey str
func (das *DevAccountService) RequestAlias(ctx context.Context, publicKey string, hint string) (*models.RequestAliasResult, error) { func (das *DevAccountService) RequestAlias(ctx context.Context, publicKey string, hint string) (*models.RequestAliasResult, error) {
var alias string var alias string
uid, err := uuid.NewV4()
if !aliasRegex.MatchString(hint) { if !aliasRegex.MatchString(hint) {
return nil, fmt.Errorf("alias hint does not match: %s", publicKey) return nil, fmt.Errorf("alias hint does not match: %s", publicKey)
} }
acc, ok := das.accounts[publicKey] acc, ok := das.accounts[publicKey]
if !ok { if !ok {
return nil, fmt.Errorf("address %s not found", publicKey) //Handle accounts created via the api
acc = Account{
Track: uid.String(),
Address: publicKey,
}
err = das.saveAccount(ctx, acc)
if err != nil {
return nil, err
}
das.accounts[publicKey] = acc
} }
alias = hint alias = hint
isPhone, err := das.applyPhoneAlias(ctx, publicKey, alias) isPhone, err := das.applyPhoneAlias(ctx, publicKey, alias)
@ -592,7 +636,12 @@ func (das *DevAccountService) RequestAlias(ctx context.Context, publicKey string
alias += "x" alias += "x"
} }
acc.Alias = alias acc.Alias = alias
alias = alias + searchDomain
das.accountsAlias[alias] = publicKey das.accountsAlias[alias] = publicKey
err := das.saveAlias(ctx, map[string]string{alias: publicKey})
if err != nil {
return nil, fmt.Errorf("Failed to save the account alias with error: %s", err.Error())
}
} }
logg.DebugCtxf(ctx, "set alias", "addr", publicKey, "alias", alias) logg.DebugCtxf(ctx, "set alias", "addr", publicKey, "alias", alias)
return &models.RequestAliasResult{ return &models.RequestAliasResult{

View File

@ -9,6 +9,7 @@ import (
func TestApiRequestAlias(t *testing.T) { func TestApiRequestAlias(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", "+25471234565")
storageService := mocks.NewMemStorageService(ctx) storageService := mocks.NewMemStorageService(ctx)
svc := NewDevAccountService(ctx, storageService) svc := NewDevAccountService(ctx, storageService)
ra, err := svc.CreateAccount(ctx) ra, err := svc.CreateAccount(ctx)
@ -16,10 +17,10 @@ func TestApiRequestAlias(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
addr := ra.PublicKey addr := ra.PublicKey
_, err = svc.RequestAlias(ctx, addr, "+254f00") _, err = svc.RequestAlias(ctx, addr, "+254f00")
if err == nil { if err == nil {
t.Fatalf("expected error") t.Fatalf("expected error")
} }
alias := "+254712345678" alias := "+254712345678"
rb, err := svc.RequestAlias(ctx, addr, alias) rb, err := svc.RequestAlias(ctx, addr, alias)
@ -39,6 +40,7 @@ func TestApiRequestAlias(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
alias = "foo.sarafu.local"
if rb.Alias != alias { if rb.Alias != alias {
t.Fatalf("expected '%s', got '%s'", alias, rb.Alias) t.Fatalf("expected '%s', got '%s'", alias, rb.Alias)
} }
@ -56,12 +58,12 @@ func TestApiRequestAlias(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
addr = ra.PublicKey addr = ra.PublicKey
alias = "foox"
rb, err = svc.RequestAlias(ctx, addr, alias) rb, err = svc.RequestAlias(ctx, addr, alias)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
alias = "foox" alias = "foox.sarafu.local"
if rb.Alias != alias { if rb.Alias != alias {
t.Fatalf("expected '%s', got '%s'", alias, rb.Alias) t.Fatalf("expected '%s', got '%s'", alias, rb.Alias)
} }

View File

@ -3,20 +3,26 @@ package http
import ( import (
"bytes" "bytes"
"context" "context"
"fmt"
"encoding/json" "encoding/json"
"errors" "errors"
"io" "io"
"log" "log"
"net/http" "net/http"
"net/url" "net/url"
"regexp"
"git.grassecon.net/grassrootseconomics/sarafu-api/config" "git.grassecon.net/grassrootseconomics/sarafu-api/config"
"git.grassecon.net/grassrootseconomics/sarafu-api/dev"
"git.grassecon.net/grassrootseconomics/sarafu-api/models" "git.grassecon.net/grassrootseconomics/sarafu-api/models"
"git.grassecon.net/grassrootseconomics/visedriver/testutil/mocks"
"github.com/grassrootseconomics/eth-custodial/pkg/api" "github.com/grassrootseconomics/eth-custodial/pkg/api"
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
) )
var (
aliasRegex = regexp.MustCompile("^\\+?[a-zA-Z0-9\\-_]+$")
Outdated
Review

THe searchdomain should not be necessary here

THe searchdomain should not be necessary here
)
type HTTPAccountService struct { type HTTPAccountService struct {
} }
@ -220,8 +226,11 @@ func (as *HTTPAccountService) CheckAliasAddress(ctx context.Context, alias strin
return &r, err return &r, err
} }
// TODO: Use actual custodial api to request available alias
func (as *HTTPAccountService) RequestAlias(ctx context.Context, publicKey string, hint string) (*models.RequestAliasResult, error) { func (as *HTTPAccountService) RequestAlias(ctx context.Context, publicKey string, hint string) (*models.RequestAliasResult, error) {
Review

Can't we just point this to devapi.RequestAlias?

Can't we just point this to devapi.RequestAlias?
Review

@lash Nice catch.Actually that brings up an idea,could we use the same implementation of the devapi to resolve the alias' address given that the api always returns the same address?

@lash Nice catch.Actually that brings up an idea,could we use the same implementation of the devapi to resolve the alias' address given that the api always returns the same address?
Review

yes for sure, while we wait or the api implementation.

yes for sure, while we wait or the api implementation.
return nil, fmt.Errorf("not yet implemented") storageService := mocks.NewMemStorageService(ctx)
svc := dev.NewDevAccountService(ctx, storageService)
return svc.RequestAlias(ctx, publicKey, hint)
} }
// TODO: remove eth-custodial api dependency // TODO: remove eth-custodial api dependency