Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,106 @@
import 'package:komodo_defi_types/komodo_defi_types.dart';

class AddressFormat {
const AddressFormat({
required this.format,
required this.network,
});

factory AddressFormat.fromCoinSubClass(
CoinSubClass subClass, {
bool isBchNetwork = false,
}) {
switch (subClass) {
case CoinSubClass.erc20:
case CoinSubClass.ethereumClassic:
return AddressFormat(
format: AddressFormatType.mixedCase.toString(),
network: '',
);
case CoinSubClass.qrc20:
return AddressFormat(
format: AddressFormatType.contract.toString(),
network: '',
);
case CoinSubClass.utxo:
// The only explicitly defined coins are ETH, UTXO and QTUM, and the
// behaviour previously was to use cashaddress as the default
// unless the coin was ERC20.
// ignore: no_default_cases
default:
return AddressFormat(
format: AddressFormatType.cashAddress.toString(),
// Only set network for BCH coins
network:
isBchNetwork ? AddressFormatNetwork.bitcoinCash.toString() : '',
);
}
}

final String format;
final String network;

Map<String, dynamic> toJson() => {
'format': format,
'network': network,
if (network.isNotEmpty) 'network': network,
};
}

/// The address format to which the input address should be converted.
enum AddressFormatType {
/// Use for ETH, ERC20 coins
mixedCase,

/// Use [cashAddress] OR [standard] for UTXO coins
cashAddress,

/// Use [cashAddress] OR [standard] for UTXO coins
standard,

/// Use [contract] or [wallet] for QTUM and QRC20 coins
contract,

/// Use [contract] or [wallet] for QTUM and QRC20 coins
wallet;

@override
String toString() {
switch (this) {
case AddressFormatType.mixedCase:
return 'mixedcase';
case AddressFormatType.cashAddress:
return 'cashaddress';
case AddressFormatType.standard:
return 'standard';
case AddressFormatType.contract:
return 'contract';
case AddressFormatType.wallet:
return 'wallet';
}
}
}

/// [AddressFormat] network prefix for [AddressFormatType.cashAddress]
/// format. Used only for UTXO coins, specifically BCH at the moment.
enum AddressFormatNetwork {
/// BCH main network (mainnet)
bitcoinCash,

/// BCH test network (testnet)
bchTest,

/// BCH regtest
bchReg;

@override
String toString() {
switch (this) {
case AddressFormatNetwork.bitcoinCash:
return 'bitcoincash';
case AddressFormatNetwork.bchTest:
return 'bchtest';
case AddressFormatNetwork.bchReg:
return 'bchreg';
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ class ConvertAddressRequest
required this.coin,
required this.fromAddress,
required this.toAddressFormat,
}) : super(
method: 'convertaddress',
mmrpc: '2.0',
);
}) : super(method: 'convertaddress', mmrpc: null);

final String coin;
final String fromAddress;
Expand All @@ -21,11 +18,9 @@ class ConvertAddressRequest
@override
Map<String, dynamic> toJson() => {
...super.toJson(),
'params': {
'coin': coin,
'from': fromAddress,
'to_address_format': toAddressFormat.toJson(),
},
'coin': coin,
'from': fromAddress,
'to_address_format': toAddressFormat.toJson(),
};

@override
Expand All @@ -41,7 +36,7 @@ class ConvertAddressResponse extends BaseResponse {

factory ConvertAddressResponse.parse(Map<String, dynamic> json) {
return ConvertAddressResponse(
mmrpc: json.value<String>('mmrpc'),
mmrpc: json.valueOrNull<String>('mmrpc'),
address: json.value<String>('result', 'address'),
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import 'package:komodo_defi_rpc_methods/komodo_defi_rpc_methods.dart';
import 'package:komodo_defi_types/komodo_defi_type_utils.dart';

class EnableCustomErc20TokenRequest
extends BaseRequest<EnableErc20Response, GeneralErrorResponse>
with RequestHandlingMixin {
EnableCustomErc20TokenRequest({
required String rpcPass,
required this.ticker,
required this.activationParams,
required this.platform,
required this.contractAddress,
}) : super(method: 'enable_erc20', rpcPass: rpcPass, mmrpc: '2.0');

final String ticker;
final Erc20ActivationParams activationParams;
final String platform;
final String contractAddress;

@override
Map<String, dynamic> toJson() {
assert(
platform.isNotEmpty,
'Platform is required when activating a custom token.',
);
assert(
contractAddress.isNotEmpty,
'Contract address is required when activating a custom token.',
);

return super.toJson().deepMerge({
'params': {
'ticker': ticker,
'activation_params': activationParams.toRpcParams(),
'protocol': {
'type': 'ERC20',
'protocol_data': {
'platform': platform,
'contract_address': contractAddress,
},
},
},
});
}

@override
EnableErc20Response parse(Map<String, dynamic> json) =>
EnableErc20Response.parse(json);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:komodo_defi_rpc_methods/komodo_defi_rpc_methods.dart';
import 'package:komodo_defi_rpc_methods/src/rpc_methods/eth/enable_custom_erc20.dart';

/// Extensions for ETH-related RPC methods
// lib/src/rpc_methods/eth/eth_rpc_extensions.dart
Expand Down Expand Up @@ -32,4 +33,21 @@ class Erc20MethodsNamespace extends BaseRpcMethodNamespace {
),
);
}

Future<EnableErc20Response> enableCustomErc20Token({
required String ticker,
required Erc20ActivationParams activationParams,
required String platform,
required String contractAddress,
}) {
return execute(
EnableCustomErc20TokenRequest(
rpcPass: rpcPass ?? '',
ticker: ticker,
activationParams: activationParams,
platform: platform,
contractAddress: contractAddress,
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import 'package:komodo_defi_rpc_methods/komodo_defi_rpc_methods.dart';
import 'package:komodo_defi_types/komodo_defi_type_utils.dart';

/// Request to get the ticker and decimals values required for custom token
/// activation, given a platform and contract as input
class GetTokenInfoRequest
extends BaseRequest<GetTokenInfoResponse, GeneralErrorResponse>
with RequestHandlingMixin {
GetTokenInfoRequest({
required String rpcPass,
required this.protocolType,
required this.platform,
required this.contractAddress,
}) : super(method: 'get_token_info', rpcPass: rpcPass, mmrpc: '2.0');

/// Token type - e.g ERC20 for tokens on the Ethereum network
final String protocolType;

/// The parent coin of the token's platform - e.g MATIC for PLG20 tokens
/// protocol_data.platform
final String platform;

/// Must be mixed case The identifying hex string for the token's contract.
/// Can be found on sites like EthScan, BscScan & PolygonScan
/// platform_data.contract_address
final String contractAddress;

@override
Map<String, dynamic> toJson() {
return super.toJson().deepMerge({
'params': {
'protocol': {
'type': protocolType,
'protocol_data': {
'platform': platform,
'contract_address': contractAddress,
},
},
},
});
}

@override
GetTokenInfoResponse parse(Map<String, dynamic> json) =>
GetTokenInfoResponse.parse(json);
}

class GetTokenInfoResponse extends BaseResponse {
GetTokenInfoResponse({
required super.mmrpc,
required this.type,
required this.info,
});

factory GetTokenInfoResponse.parse(Map<String, dynamic> json) {
final result = json.value<JsonMap>('result');
return GetTokenInfoResponse(
mmrpc: json.valueOrNull<String>('mmrpc'),
type: result.value<String>('type'),
info: TokenInfo.fromJson(result.value<JsonMap>('info')),
);
}

/// Token type - e.g PLG20 for tokens on the Polygon network
final String type;
final TokenInfo info;

@override
Map<String, dynamic> toJson() {
return {
'type': type,
'info': info.toJson(),
};
}
}

class TokenInfo {
TokenInfo({
required this.symbol,
required this.decimals,
});

factory TokenInfo.fromJson(Map<String, dynamic> json) {
return TokenInfo(
symbol: json.value<String>('symbol'),
decimals: json.value<int>('decimals'),
);
}

/// The ticker of the token linked to the contract address and
/// network requested
final String symbol;

/// Defines the number of digits after the decimal point that should be
/// used to display the orderbook amounts, balance, and the value of inputs
/// to be used in the case of order creation or a withdraw transaction.
final int decimals;

Map<String, dynamic> toJson() {
return {
'symbol': symbol,
'decimals': decimals,
};
}
}
25 changes: 25 additions & 0 deletions packages/komodo_defi_rpc_methods/lib/src/rpc_methods_library.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// ignore_for_file: unused_field, unused_element

import 'package:komodo_defi_rpc_methods/src/internal_exports.dart';
import 'package:komodo_defi_rpc_methods/src/rpc_methods/utility/get_token_info.dart';
import 'package:komodo_defi_types/komodo_defi_types.dart';

/// A class that provides a library of RPC methods used by the Komodo DeFi
Expand Down Expand Up @@ -43,6 +44,7 @@ class KomodoDefiRpcMethods {
// Add other namespaces here, e.g.:
// TradeNamespace get trade => TradeNamespace(_client);
// UtilityNamespace get utility => UtilityNamespace(_client);
UtilityMethods get utility => UtilityMethods(_client);
}

class TaskMethods extends BaseRpcMethodNamespace {
Expand Down Expand Up @@ -73,6 +75,29 @@ class WalletMethods extends BaseRpcMethodNamespace {
execute(GetPublicKeyHashRequest(rpcPass: rpcPass));
}

/// KDF v2 Utility Methods not specific to any larger feature
/// or namespace (e.g. current MTP, token info for custom token activation).
class UtilityMethods extends BaseRpcMethodNamespace {
UtilityMethods(super.client);

/// Returns the ticker and decimals values required for activation of a custom
/// token, given a [platform], [protocolType], and [contractAddress].
Future<GetTokenInfoResponse> getTokenInfo({
required String protocolType,
required String platform,
required String contractAddress,
String? rpcPass,
}) =>
execute(
GetTokenInfoRequest(
protocolType: protocolType,
platform: platform,
contractAddress: contractAddress,
rpcPass: rpcPass ?? '',
),
);
}

class GeneralActivationMethods extends BaseRpcMethodNamespace {
const GeneralActivationMethods(super.client);

Expand Down
Loading