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