Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BIP-39 import #285

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 1 addition & 11 deletions scripts/configure.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,21 +211,11 @@ let configFileToBeWritten =
| Some theTool -> initialConfigFile.Add("LegacyBuildTool", theTool)
| None -> initialConfigFile

let configFileStageThree =
let finalConfigFile =
match buildTool with
| Some theTool -> configFileStageTwo.Add("BuildTool", theTool)
| None -> configFileStageTwo

let finalConfigFile =
let nativeSegwitEnabled =
argsToThisFsxScript
|> List.contains "--native-segwit"
if nativeSegwitEnabled then
configFileStageThree
|> AddToDefinedConstants "NATIVE_SEGWIT"
else
configFileStageThree

finalConfigFile

let lines =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"Value": {
"TransactionInfo": {
"Proposal": {
"OriginAddress": "16pKBjGGZkUXo1afyBNf5ttFvV9hauS1kR",
"OriginMainAddress": "16pKBjGGZkUXo1afyBNf5ttFvV9hauS1kR",
"Amount": {
"ValueToSend": 10.01,
"BalanceAtTheMomentOfSending": 12.02,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"Value": {
"TransactionInfo": {
"Proposal": {
"OriginAddress": "0xf3j4m0rjx94sushh03j",
"OriginMainAddress": "0xf3j4m0rjx94sushh03j",
"Amount": {
"ValueToSend": 10.01,
"BalanceAtTheMomentOfSending": 12.02,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"Value": {
"TransactionInfo": {
"Proposal": {
"OriginAddress": "0xba766d6d13E2Cc921Bf6e896319D32502af9e37E",
"OriginMainAddress": "0xba766d6d13E2Cc921Bf6e896319D32502af9e37E",
"Amount": {
"ValueToSend": 1.0,
"BalanceAtTheMomentOfSending": 7.08,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"TypeName": "GWallet.Backend.UnsignedTransaction`1[GWallet.Backend.UtxoCoin.TransactionMetadata]",
"Value": {
"Proposal": {
"OriginAddress": "16pKBjGGZkUXo1afyBNf5ttFvV9hauS1kR",
"OriginMainAddress": "16pKBjGGZkUXo1afyBNf5ttFvV9hauS1kR",
"Amount": {
"ValueToSend": 10.01,
"BalanceAtTheMomentOfSending": 12.02,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"TypeName": "GWallet.Backend.UnsignedTransaction`1[GWallet.Backend.Ether.TransactionMetadata]",
"Value": {
"Proposal": {
"OriginAddress": "0xf3j4m0rjx94sushh03j",
"OriginMainAddress": "0xf3j4m0rjx94sushh03j",
"Amount": {
"ValueToSend": 10.01,
"BalanceAtTheMomentOfSending": 12.02,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"TypeName": "GWallet.Backend.UnsignedTransaction`1[GWallet.Backend.Ether.TransactionMetadata]",
"Value": {
"Proposal": {
"OriginAddress": "0xba766d6d13E2Cc921Bf6e896319D32502af9e37E",
"OriginMainAddress": "0xba766d6d13E2Cc921Bf6e896319D32502af9e37E",
"Amount": {
"ValueToSend": 1.0,
"BalanceAtTheMomentOfSending": 7.08,
Expand Down
52 changes: 40 additions & 12 deletions src/GWallet.Backend/Account.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ open System.Threading.Tasks

open GWallet.Backend.FSharpUtil.UwpHacks

open NBitcoin

// this exception, if it happens, it would cause a crash because we don't handle it yet
type UnhandledCurrencyServerException(currency: Currency,
innerException: Exception) =
Expand All @@ -17,19 +19,8 @@ type UnhandledCurrencyServerException(currency: Currency,

module Account =

let private isInitialized (accounts: seq<IAccount>) = lazy(
let private isInitialized (_accounts: seq<IAccount>) = lazy(
Config.Init()

#if !NATIVE_SEGWIT
let _readonlyUtxoAccounts =
#else
let readonlyUtxoAccounts =
#endif
accounts.Where(fun acc -> acc.Currency.IsUtxo()).OfType<ReadOnlyAccount>()
#if NATIVE_SEGWIT
UtxoCoin.Account.MigrateReadOnlyAccountsToNativeSegWit readonlyUtxoAccounts
#endif
()
)

let private GetShowableBalanceAndImminentPaymentInternal (account: IAccount)
Expand Down Expand Up @@ -405,6 +396,43 @@ module Account =
|> ignore<ArchivedAccount>
Config.RemoveNormalAccount account

let CreateEphemeralAccountFromSeedMenmonic (mnemonic: string) : UtxoCoin.EphemeralUtxoAccount =
let standardBip84DerivationPath = KeyPath("m/84'/0'/0'")
let rootKey = Mnemonic(mnemonic).DeriveExtKey().Derive(standardBip84DerivationPath)
let firstReceivingAddressKey = rootKey.Derive(0u).Derive(0u)

let currency = Currency.BTC
let network = UtxoCoin.Account.GetNetwork currency
let privateKeyString =
firstReceivingAddressKey.PrivateKey.GetWif(network).ToWif()

let fromPublicKeyToPublicAddress (publicKey: PubKey) =
publicKey.GetAddress(ScriptPubKeyType.Segwit, network).ToString()

let fromAccountFileToPrivateKey (accountConfigFile: FileRepresentation) =
Key.Parse(accountConfigFile.Content(), network)

let fromAccountFileToPublicAddress (accountConfigFile: FileRepresentation) =
fromPublicKeyToPublicAddress(fromAccountFileToPrivateKey(accountConfigFile).PubKey)

let fromAccountFileToPublicKey (accountConfigFile: FileRepresentation) =
fromAccountFileToPrivateKey(accountConfigFile).PubKey

let fileName = fromPublicKeyToPublicAddress(firstReceivingAddressKey.GetPublicKey())
let accountFileRepresentation = { Name = fileName; Content = fun _ -> privateKeyString }

UtxoCoin.EphemeralUtxoAccount(
currency,
accountFileRepresentation,
fromAccountFileToPublicAddress,
fromAccountFileToPublicKey
)

let ConvertEphemeralAccountToArchivedAccount (ephemeralAccount: UtxoCoin.EphemeralUtxoAccount) (currency: Currency) : unit =
// no need for removing account since we don't create any file to begin with (see CreateEphemeralAccountFromSeedMenmonic)
let privateKeyAsString = ephemeralAccount.GetUnencryptedPrivateKey()
CreateArchivedAccount currency privateKeyAsString |> ignore<ArchivedAccount>
webwarrior-ws marked this conversation as resolved.
Show resolved Hide resolved

let SweepArchivedFunds (account: ArchivedAccount)
(balance: decimal)
(destination: IAccount)
Expand Down
5 changes: 4 additions & 1 deletion src/GWallet.Backend/AccountTypes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ namespace GWallet.Backend

open System.IO

type UtxoPublicKey = string

type WatchWalletInfo =
{
UtxoCoinPublicKey: string
UtxoCoinPublicKey: UtxoPublicKey
EtherPublicAddress: string
}

Expand All @@ -30,6 +32,7 @@ type AccountKind =
| Normal
| ReadOnly
| Archived
| Ephemeral
static member All() =
seq {
yield Normal
Expand Down
6 changes: 2 additions & 4 deletions src/GWallet.Backend/Config.fs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@ module Config =
let internal NoNetworkBalanceForDebuggingPurposes = false

let internal UseNativeSegwit =
#if NATIVE_SEGWIT
true
#else
false
#endif

let IsWindowsPlatform() =
RuntimeInformation.IsOSPlatform OSPlatform.Windows
Expand Down Expand Up @@ -114,6 +110,8 @@ module Config =
Path.Combine(accountConfigDir, "readonly")
| AccountKind.Archived ->
Path.Combine(accountConfigDir, "archived")
| AccountKind.Ephemeral ->
failwith "Ephemeral accounts are not supposed to be stored in file"

let configDir = Path.Combine(baseConfigDir, currency.ToString()) |> DirectoryInfo
if not configDir.Exists then
Expand Down
6 changes: 0 additions & 6 deletions src/GWallet.Backend/Transaction.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ type ITransactionDetails =

type internal SignedTransactionDetails =
{
#if !NATIVE_SEGWIT
[<JsonProperty(PropertyName = "OriginAddress")>]
#endif
OriginMainAddress: string

Amount: decimal
Expand All @@ -27,9 +24,6 @@ type internal SignedTransactionDetails =

type UnsignedTransactionProposal =
{
#if !NATIVE_SEGWIT
[<JsonProperty(PropertyName = "OriginAddress")>]
#endif
OriginMainAddress: string

Amount: TransferAmount;
Expand Down
41 changes: 9 additions & 32 deletions src/GWallet.Backend/UtxoCoin/UtxoCoinAccount.fs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ type ArchivedUtxoAccount(currency: Currency, accountFile: FileRepresentation,
interface IUtxoAccount with
member val PublicKey = fromAccountFileToPublicKey accountFile with get

/// Inherits from ArchivedUtxoAccount because SweepArchivedFunds expects ArchivedUtxoAccount instance
/// and sweep funds functionality is needed for this kind of account.
type EphemeralUtxoAccount(currency: Currency, accountFile: FileRepresentation,
fromAccountFileToPublicAddress: FileRepresentation -> string,
fromAccountFileToPublicKey: FileRepresentation -> PubKey) =
inherit ArchivedUtxoAccount(currency, accountFile, fromAccountFileToPublicAddress, fromAccountFileToPublicKey)

override self.Kind = AccountKind.Ephemeral

module Account =

let internal GetNetwork (currency: Currency) =
Expand Down Expand Up @@ -700,38 +709,6 @@ module Account =
Config.AddAccount conceptAccountForReadOnlyAccount AccountKind.ReadOnly
|> ignore<FileRepresentation>

#if NATIVE_SEGWIT
let internal MigrateReadOnlyAccountsToNativeSegWit (readOnlyUtxoAccounts: seq<ReadOnlyAccount>): unit =
let utxoAccountsToMigrate =
seq {
for utxoAccount in readOnlyUtxoAccounts do
let accountFile = utxoAccount.AccountFile
let prefix =
match (utxoAccount :> IAccount).Currency with
| Currency.BTC ->
BITCOIN_ADDRESS_BECH32_PREFIX
| Currency.LTC ->
LITECOIN_ADDRESS_BECH32_PREFIX
| otherCurrency -> failwith <| SPrintF1 "Missed UTXO currency %A when implementing NativeSegwit migration?" otherCurrency
if not (accountFile.Name.StartsWith prefix) then
yield utxoAccount
}

let utxoPublicKeys =
seq {
for utxoReadOnlyAccount in utxoAccountsToMigrate do
let accountFile = utxoReadOnlyAccount.AccountFile
let utxoPublicKey = accountFile.Content()
yield utxoPublicKey
} |> Set.ofSeq

for utxoPublicKey in utxoPublicKeys do
CreateReadOnlyAccounts utxoPublicKey

for utxoReadOnlyAccount in utxoAccountsToMigrate do
Config.RemoveReadOnlyAccount utxoReadOnlyAccount
#endif

let GetSignedTransactionDetails<'T when 'T :> IBlockchainFeeInfo>(rawTransaction: string)
(currency: Currency)
(readonlyUtxoAccounts: seq<ReadOnlyUtxoAccount>)
Expand Down
Loading
Loading