decred.org/dcrdex@v1.0.5/client/asset/dgb/dgb.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org/license/1.0.0.
     3  
     4  package dgb
     5  
     6  import (
     7  	"fmt"
     8  	"strconv"
     9  
    10  	"decred.org/dcrdex/client/asset"
    11  	"decred.org/dcrdex/client/asset/btc"
    12  	"decred.org/dcrdex/dex"
    13  	dexbtc "decred.org/dcrdex/dex/networks/btc"
    14  	dexdgb "decred.org/dcrdex/dex/networks/dgb"
    15  
    16  	"github.com/btcsuite/btcd/chaincfg"
    17  )
    18  
    19  const (
    20  	version = 0
    21  	BipID   = 20
    22  
    23  	// dustLimit = 1_000_000 // sats => 0.01 DGB, the "soft" limit (DEFAULT_DUST_LIMIT) **TODO check for dgb**
    24  
    25  	// Digibyte's version went from 7170300 in v7.17 to 82200 in version 8.22.
    26  	// I know of no RPC changes that would make 8.22 wallets incompatible with
    27  	// 7.17, so I guess we'll support both and let the chain decide when to
    28  	// kill 7.17 wallets.
    29  	minNetworkVersion       = 82200
    30  	walletTypeRPC           = "digibytedRPC"
    31  	defaultRedeemConfTarget = 2
    32  )
    33  
    34  var (
    35  	configOpts = append(btc.RPCConfigOpts("DigiByte", "14022"), []*asset.ConfigOption{
    36  		{
    37  			Key:          "fallbackfee",
    38  			DisplayName:  "Fallback fee rate",
    39  			Description:  "DigiByte's 'fallbackfee' rate. Units: DGB/kB",
    40  			DefaultValue: strconv.FormatFloat(dexdgb.DefaultFee*1000/1e8, 'f', -1, 64), // higher than BTC default
    41  		},
    42  		{
    43  			Key:         "feeratelimit",
    44  			DisplayName: "Highest acceptable fee rate",
    45  			Description: "This is the highest network fee rate you are willing to " +
    46  				"pay on swap transactions. If feeratelimit is lower than a market's " +
    47  				"maxfeerate, you will not be able to trade on that market with this " +
    48  				"wallet.  Units: BTC/kB",
    49  			DefaultValue: strconv.FormatFloat(dexdgb.DefaultFeeRateLimit*1000/1e8, 'f', -1, 64), // higher than BTC default
    50  		},
    51  		{
    52  			Key:         "redeemconftarget",
    53  			DisplayName: "Redeem confirmation target",
    54  			Description: "The target number of blocks for the redeem transaction " +
    55  				"to be mined. Used to set the transaction's fee rate. " +
    56  				"(default: 2 blocks)",
    57  			DefaultValue: strconv.FormatUint(defaultRedeemConfTarget, 10),
    58  		},
    59  		{
    60  			Key:         "txsplit",
    61  			DisplayName: "Pre-split funding inputs",
    62  			Description: "When placing an order, create a \"split\" transaction to fund the order without locking more of the wallet balance than " +
    63  				"necessary. Otherwise, excess funds may be reserved to fund the order until the first swap contract is broadcast " +
    64  				"during match settlement, or the order is canceled. This an extra transaction for which network mining fees are paid. " +
    65  				"Used only for standing-type orders, e.g. limit orders without immediate time-in-force.",
    66  			IsBoolean:    true,
    67  			DefaultValue: "true", // low fee, fast chain
    68  		}, // no ExternalFeeEstimator, so no apifeefallback option
    69  	}...)
    70  	// WalletInfo defines some general information about a DigiByte wallet.
    71  	WalletInfo = &asset.WalletInfo{
    72  		Name:              "DigiByte",
    73  		SupportedVersions: []uint32{version},
    74  		UnitInfo:          dexdgb.UnitInfo,
    75  		AvailableWallets: []*asset.WalletDefinition{{
    76  			Type:              walletTypeRPC,
    77  			Tab:               "External",
    78  			Description:       "Connect to digibyted",
    79  			DefaultConfigPath: dexbtc.SystemConfigPath("digibyte"),
    80  			ConfigOpts:        configOpts,
    81  		}},
    82  	}
    83  )
    84  
    85  func init() {
    86  	asset.Register(BipID, &Driver{})
    87  }
    88  
    89  // Driver implements asset.Driver.
    90  type Driver struct{}
    91  
    92  // Open creates the DGB exchange wallet. Start the wallet with its Run method.
    93  func (d *Driver) Open(cfg *asset.WalletConfig, logger dex.Logger, network dex.Network) (asset.Wallet, error) {
    94  	return NewWallet(cfg, logger, network)
    95  }
    96  
    97  // DecodeCoinID creates a human-readable representation of a coin ID for
    98  // DigiByte.
    99  func (d *Driver) DecodeCoinID(coinID []byte) (string, error) {
   100  	// DigiByte and Bitcoin have the same tx hash and output format.
   101  	return (&btc.Driver{}).DecodeCoinID(coinID)
   102  }
   103  
   104  // Info returns basic information about the wallet and asset.
   105  func (d *Driver) Info() *asset.WalletInfo {
   106  	return WalletInfo
   107  }
   108  
   109  // MinLotSize calculates the minimum bond size for a given fee rate that avoids
   110  // dust outputs on the swap and refund txs, assuming the maxFeeRate doesn't
   111  // change.
   112  func (d *Driver) MinLotSize(maxFeeRate uint64) uint64 {
   113  	return dexbtc.MinLotSize(maxFeeRate, false)
   114  }
   115  
   116  // NewWallet is the exported constructor by which the DEX will import the
   117  // exchange wallet. The wallet will shut down when the provided context is
   118  // canceled. The configPath can be an empty string, in which case the standard
   119  // system location of the digibyted config file is assumed.
   120  func NewWallet(cfg *asset.WalletConfig, logger dex.Logger, network dex.Network) (asset.Wallet, error) {
   121  	var params *chaincfg.Params
   122  	switch network {
   123  	case dex.Mainnet:
   124  		params = dexdgb.MainNetParams
   125  	case dex.Testnet:
   126  		params = dexdgb.TestNetParams
   127  	case dex.Regtest:
   128  		params = dexdgb.RegressionNetParams
   129  	default:
   130  		return nil, fmt.Errorf("unknown network ID %v", network)
   131  	}
   132  
   133  	// See https://digibyte.org/docs/integrationguide.pdf
   134  
   135  	// Designate the clone ports. These will be overwritten by any explicit
   136  	// settings in the configuration file.
   137  	ports := dexbtc.NetPorts{
   138  		Mainnet: "14022",
   139  		Testnet: "14023",
   140  		Simnet:  "18443",
   141  	}
   142  	cloneCFG := &btc.BTCCloneCFG{
   143  		WalletCFG:           cfg,
   144  		MinNetworkVersion:   minNetworkVersion,
   145  		WalletInfo:          WalletInfo,
   146  		Symbol:              "dgb",
   147  		Logger:              logger,
   148  		Network:             network,
   149  		ChainParams:         params,
   150  		Ports:               ports,
   151  		DefaultFallbackFee:  dexdgb.DefaultFee,
   152  		DefaultFeeRateLimit: dexdgb.DefaultFeeRateLimit,
   153  		LegacyBalance:       true,
   154  		Segwit:              true,
   155  		InitTxSize:          dexbtc.InitTxSizeSegwit,
   156  		InitTxSizeBase:      dexbtc.InitTxSizeBaseSegwit,
   157  		// UnlockSpends:        false, // check listlockunspent after a swap: https://github.com/decred/dcrdex/pull/1558#issuecomment-1096912520
   158  		// ConstantDustLimit:   dustLimit, // commented to use dexbtc.IsDust, but investigate for DGB
   159  		AssetID: BipID,
   160  	}
   161  
   162  	return btc.BTCCloneWallet(cloneCFG)
   163  }