Skip to content

Commit 9c765c9

Browse files
Merge pull request #1119 from NyanCatTW1/main
Add basic FACT0RN support
2 parents 219164d + 4a82e17 commit 9c765c9

7 files changed

Lines changed: 577 additions & 6 deletions

File tree

lib/models/isar/models/blockchain_data/address.dart

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ class Address extends CryptoCurrencyAddress {
101101
}
102102

103103
@override
104-
String toString() => "{ "
104+
String toString() =>
105+
"{ "
105106
"id: $id, "
106107
"walletId: $walletId, "
107108
"value: $value, "
@@ -130,10 +131,7 @@ class Address extends CryptoCurrencyAddress {
130131
return jsonEncode(result);
131132
}
132133

133-
static Address fromJsonString(
134-
String jsonString, {
135-
String? overrideWalletId,
136-
}) {
134+
static Address fromJsonString(String jsonString, {String? overrideWalletId}) {
137135
final json = jsonDecode(jsonString);
138136
final derivationPathString = json["derivationPath"] as String?;
139137

@@ -176,7 +174,8 @@ enum AddressType {
176174
p2tr,
177175
solana,
178176
cardanoShelley,
179-
xelis;
177+
xelis,
178+
fact0rn;
180179

181180
String get readableName {
182181
switch (this) {
@@ -216,6 +215,8 @@ enum AddressType {
216215
return "Cardano Shelley";
217216
case AddressType.xelis:
218217
return "Xelis";
218+
case AddressType.fact0rn:
219+
return "FACT0RN";
219220
}
220221
}
221222
}

lib/services/price.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class PriceAPI {
3636
Epiccash: "epic-cash",
3737
Ecash: "ecash",
3838
Ethereum: "ethereum",
39+
Fact0rn: "fact0rn",
3940
Firo: "zcoin",
4041
Monero: "monero",
4142
Particl: "particl",
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
import 'package:coinlib_flutter/coinlib_flutter.dart' as coinlib;
2+
3+
import '../../../models/isar/models/blockchain_data/address.dart';
4+
import '../../../models/node_model.dart';
5+
import '../../../utilities/amount/amount.dart';
6+
import '../../../utilities/default_nodes.dart';
7+
import '../../../utilities/enums/derive_path_type_enum.dart';
8+
import '../crypto_currency.dart';
9+
import '../interfaces/electrumx_currency_interface.dart';
10+
import '../intermediate/bip39_hd_currency.dart';
11+
12+
class Fact0rn extends Bip39HDCurrency with ElectrumXCurrencyInterface {
13+
Fact0rn(super.network) {
14+
_idMain = "fact0rn";
15+
_uriScheme = "fact0rn";
16+
switch (network) {
17+
case CryptoCurrencyNetwork.main:
18+
_id = _idMain;
19+
_name = "FACT0RN";
20+
_ticker = "FACT";
21+
case CryptoCurrencyNetwork.test:
22+
_id = "fact0rnTestNet";
23+
_name = "tFACT0RN";
24+
_ticker = "tFACT";
25+
default:
26+
throw Exception("Unsupported network: $network");
27+
}
28+
}
29+
30+
late final String _id;
31+
@override
32+
String get identifier => _id;
33+
34+
late final String _idMain;
35+
@override
36+
String get mainNetId => _idMain;
37+
38+
late final String _name;
39+
@override
40+
String get prettyName => _name;
41+
42+
late final String _uriScheme;
43+
@override
44+
String get uriScheme => _uriScheme;
45+
46+
late final String _ticker;
47+
@override
48+
String get ticker => _ticker;
49+
50+
@override
51+
bool get torSupport => false;
52+
53+
@override
54+
List<DerivePathType> get supportedDerivationPathTypes => [
55+
DerivePathType.bip84,
56+
];
57+
58+
@override
59+
String constructDerivePath({
60+
required DerivePathType derivePathType,
61+
int account = 0,
62+
required int chain,
63+
required int index,
64+
}) {
65+
String coinType;
66+
67+
switch (networkParams.wifPrefix) {
68+
case 0x80:
69+
coinType = "42069"; // fact0rn mainnet
70+
break;
71+
case 0xef:
72+
coinType = "1"; // fact0rn testnet
73+
break;
74+
default:
75+
throw Exception("Invalid Fact0rn network wif used!");
76+
}
77+
78+
int purpose;
79+
switch (derivePathType) {
80+
case DerivePathType.bip84:
81+
purpose = 84;
82+
break;
83+
84+
default:
85+
throw Exception("DerivePathType $derivePathType not supported");
86+
}
87+
88+
return "m/$purpose'/$coinType'/$account'/$chain/$index";
89+
}
90+
91+
@override
92+
Amount get dustLimit =>
93+
Amount(rawValue: BigInt.from(1000), fractionDigits: fractionDigits);
94+
95+
@override
96+
String get genesisHash {
97+
switch (network) {
98+
case CryptoCurrencyNetwork.main:
99+
return "79cb40f8075b0e3dc2bc468c5ce2a7acbe0afd36c6c3d3a134ea692edac7de49";
100+
case CryptoCurrencyNetwork.test:
101+
return "550bbf0a444d9f92189f067dd225f5b8a5d92587ebc2e8398d143236072580af";
102+
default:
103+
throw Exception("Unsupported network: $network");
104+
}
105+
}
106+
107+
@override
108+
({coinlib.Address address, AddressType addressType}) getAddressForPublicKey({
109+
required coinlib.ECPublicKey publicKey,
110+
required DerivePathType derivePathType,
111+
}) {
112+
switch (derivePathType) {
113+
case DerivePathType.bip84:
114+
final addr = coinlib.P2WPKHAddress.fromPublicKey(
115+
publicKey,
116+
hrp: networkParams.bech32Hrp,
117+
);
118+
119+
return (address: addr, addressType: AddressType.p2wpkh);
120+
121+
default:
122+
throw Exception("DerivePathType $derivePathType not supported");
123+
}
124+
}
125+
126+
@override
127+
int get minConfirms => 1;
128+
129+
@override
130+
coinlib.Network get networkParams {
131+
switch (network) {
132+
case CryptoCurrencyNetwork.main:
133+
return coinlib.Network(
134+
wifPrefix: 0x80,
135+
p2pkhPrefix: 0x00,
136+
p2shPrefix: 0x05,
137+
privHDPrefix: 0x0488ade4,
138+
pubHDPrefix: 0x0488b21e,
139+
bech32Hrp: "fact",
140+
messagePrefix: '\x18Bitcoin Signed Message:\n',
141+
minFee: BigInt.from(1), // Not used in stack wallet currently
142+
minOutput: dustLimit.raw, // Not used in stack wallet currently
143+
feePerKb: BigInt.from(1), // Not used in stack wallet currently
144+
);
145+
case CryptoCurrencyNetwork.test:
146+
return coinlib.Network(
147+
wifPrefix: 0xef,
148+
p2pkhPrefix: 0x6f,
149+
p2shPrefix: 0xc4,
150+
privHDPrefix: 0x04358394,
151+
pubHDPrefix: 0x043587cf,
152+
bech32Hrp: "tfact",
153+
messagePrefix: "\x18Bitcoin Signed Message:\n",
154+
minFee: BigInt.from(1), // Not used in stack wallet currently
155+
minOutput: dustLimit.raw, // Not used in stack wallet currently
156+
feePerKb: BigInt.from(1), // Not used in stack wallet currently
157+
);
158+
default:
159+
throw Exception("Unsupported network: $network");
160+
}
161+
}
162+
163+
@override
164+
bool validateAddress(String address) {
165+
try {
166+
coinlib.Address.fromString(address, networkParams);
167+
return true;
168+
} catch (_) {
169+
return false;
170+
}
171+
}
172+
173+
@override
174+
NodeModel get defaultNode {
175+
switch (network) {
176+
case CryptoCurrencyNetwork.main:
177+
return NodeModel(
178+
host: "electrumx.fact0rn.io",
179+
port: 50002,
180+
name: DefaultNodes.defaultName,
181+
id: DefaultNodes.buildId(this),
182+
useSSL: true,
183+
enabled: true,
184+
coinName: identifier,
185+
isFailover: true,
186+
isDown: false,
187+
torEnabled: false,
188+
clearnetEnabled: true,
189+
);
190+
191+
default:
192+
throw UnimplementedError();
193+
}
194+
}
195+
196+
@override
197+
int get defaultSeedPhraseLength => 12;
198+
199+
@override
200+
int get fractionDigits => 8;
201+
202+
@override
203+
bool get hasBuySupport => false;
204+
205+
@override
206+
bool get hasMnemonicPassphraseSupport => true;
207+
208+
@override
209+
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
210+
211+
@override
212+
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
213+
214+
@override
215+
BigInt get satsPerCoin => BigInt.from(100000000);
216+
217+
@override
218+
int get targetBlockTimeSeconds => 1800;
219+
220+
@override
221+
DerivePathType get defaultDerivePathType => DerivePathType.bip84;
222+
223+
@override
224+
Uri defaultBlockExplorer(String txid) {
225+
switch (network) {
226+
case CryptoCurrencyNetwork.main:
227+
// "https://explorer.fact0rn.io/tx/$txid" doesn't show mempool transactions
228+
return Uri.parse("https://factexplorer.io/tx/$txid");
229+
default:
230+
throw Exception(
231+
"Unsupported network for defaultBlockExplorer(): $network",
232+
);
233+
}
234+
}
235+
236+
@override
237+
int get transactionVersion => 2;
238+
239+
@override
240+
BigInt get defaultFeeRate => BigInt.from(1000);
241+
}

lib/wallets/crypto_currency/crypto_currency.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export 'coins/dogecoin.dart';
1212
export 'coins/ecash.dart';
1313
export 'coins/epiccash.dart';
1414
export 'coins/ethereum.dart';
15+
export 'coins/fact0rn.dart';
1516
export 'coins/firo.dart';
1617
export 'coins/litecoin.dart';
1718
export 'coins/monero.dart';

0 commit comments

Comments
 (0)