Skip to content

Commit

Permalink
multi: enable token trading
Browse files Browse the repository at this point in the history
client/asset:
Add allowable networks to RegisterToken. The client can then use
the new package function SetNetwork during initialization to filter out
incompatible tokens.

client/asset/eth:
Change OpenTokenWallet to use a single struct argument. Add PeerChange
function and notify token wallets of peer changes.
Fix bugs in swap fee estimation to deal with transfer approval.

client/core:
Plumb in token wallet creation and opening.
Add TokenInfo field to SupportedAsset, populated instead of the
Info field for token wallets. Should consider changing the name
of the Info field to better illustrate the purpose and to break
Go consumer's API to force adaptation to the new semantics.

client/webserver:
Add token to live tests.

ui:
Implement new wallet creation flow for token wallets that includes
a step to sync the parent. Adapt to new SupportedAsset structure.
Add "token-aware symbols", which are symbols that, for tokens, have
an additional <sup> element denoting the parent asset.
  • Loading branch information
buck54321 committed Jun 14, 2022
1 parent f6cccaa commit 61c69fd
Show file tree
Hide file tree
Showing 68 changed files with 1,285 additions and 596 deletions.
55 changes: 44 additions & 11 deletions client/asset/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ import (
"decred.org/dcrdex/dex"
)

type nettedToken struct {
*Token
nets []dex.Network
}

var (
driversMtx sync.RWMutex
drivers = make(map[uint32]Driver)
tokens = make(map[uint32]*Token)
tokens = make(map[uint32]*nettedToken)
)

// CreateWalletParams are the parameters for internal wallet creation. The
Expand Down Expand Up @@ -71,8 +76,10 @@ func Register(assetID uint32, driver Driver) {
drivers[assetID] = driver
}

// RegisterToken should be called to register tokens.
func RegisterToken(tokenID uint32, token *dex.Token, walletDef *WalletDefinition) {
// RegisterToken should be called to register tokens. If no nets are specified
// the token will be registered for all networks. The user must invoke
// SetNetwork to enable net-based filtering of package function output.
func RegisterToken(tokenID uint32, token *dex.Token, walletDef *WalletDefinition, nets ...dex.Network) {
driversMtx.Lock()
defer driversMtx.Unlock()
if _, exists := tokens[tokenID]; exists {
Expand All @@ -82,9 +89,12 @@ func RegisterToken(tokenID uint32, token *dex.Token, walletDef *WalletDefinition
if !exists {
panic(fmt.Sprintf("token %d's parent asset %d isn't registered", tokenID, token.ParentID))
}
tokens[tokenID] = &Token{
Token: token,
Definition: walletDef,
tokens[tokenID] = &nettedToken{
Token: &Token{
Token: token,
Definition: walletDef,
},
nets: nets,
}
}

Expand Down Expand Up @@ -137,17 +147,18 @@ type RegisteredAsset struct {
}

// Assets returns a list of information about supported assets.
func Assets() map[uint32]RegisteredAsset {
func Assets() map[uint32]*RegisteredAsset {
driversMtx.RLock()
defer driversMtx.RUnlock()
assets := make(map[uint32]RegisteredAsset, len(drivers))
assets := make(map[uint32]*RegisteredAsset, len(drivers))
for assetID, driver := range drivers {
assets[assetID] = RegisteredAsset{
assets[assetID] = &RegisteredAsset{
ID: assetID,
Symbol: dex.BipIDSymbol(assetID),
Info: driver.Info(),
}
}

for tokenID, token := range tokens {
parent, found := assets[token.ParentID]
if !found {
Expand All @@ -158,7 +169,7 @@ func Assets() map[uint32]RegisteredAsset {
if parent.Tokens == nil {
parent.Tokens = make(map[uint32]*Token, 1)
}
parent.Tokens[tokenID] = token
parent.Tokens[tokenID] = token.Token
}
return assets
}
Expand All @@ -167,7 +178,11 @@ func Assets() map[uint32]RegisteredAsset {
func TokenInfo(assetID uint32) *Token {
driversMtx.RLock()
defer driversMtx.RUnlock()
return tokens[assetID]
nt := tokens[assetID]
if nt == nil {
return nil
}
return nt.Token
}

// Info returns the WalletInfo for the specified asset, if supported. Info only
Expand Down Expand Up @@ -196,3 +211,21 @@ func UnitInfo(assetID uint32) (dex.UnitInfo, error) {
}
return dex.UnitInfo{}, fmt.Errorf("asset: unsupported asset %d", assetID)
}

// SetNetwork will filter registered assets for those available on the specified
// network. SetNetwork need only be called once during intialization.
func SetNetwork(net dex.Network) {
nextasset:
for assetID, nt := range tokens {
if len(nt.nets) == 0 {
continue
}
for _, allowedNet := range nt.nets {
if net == allowedNet {
continue nextasset
}
}
// This network is not supported for this asset.
delete(tokens, assetID)
}
}
Loading

0 comments on commit 61c69fd

Please sign in to comment.