PSFlexPool.psm1

function ConvertFrom-CoinBaseUnit {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [Alias("Coin")]
        [string]$CoinTicker,
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias("Reward","Balance")]
        $Value
    )

    Process{
        if ($CoinTicker -eq "XCH"){
            $Value / [math]::Pow(10,12)
        }
        else{
            $Value / [math]::Pow(10,18)
        }
    }
}
function Get-fpAverageBlockReward {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/averageBlockReward?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    [pscustomobject]@{
                        Coin = $coin
                        AverageBlockReward = [int64]$Results.Result
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpAverageHashrate {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/averageHashrate?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    [pscustomobject]@{
                        Coin = $coin
                        AverageHashRate = [int64]$Results.Result
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpAverageLuck {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/averageLuck?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    [pscustomobject]@{
                        Coin = $coin
                        AverageLuck = [decimal]$Results.Result
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpBlock {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker = "xch",
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [int]$Page = 0
    )
    
    Process{
        try{
            $Query = "pool/blocks?coin=$CoinTicker&page=$Page"
            $Results = Invoke-FlexPoolAPI -Query $Query
            if ($null -eq $Results.error){
                $Results.result.data | ForEach-Object {
                    $_.psobject.TypeNames.Insert(0,"PSFlexPool.Block")
                    $_.TimeStamp = ConvertFrom-UNIXTime $_.TimeStamp
                }
                [PSCustomObject]@{
                    PSTypeName = "PSFlexPool.BlockPage"
                    TotalItems = $Results.result.TotalItems
                    TotalPages = $Results.result.TotalPages
                    CurrentPage = $Page
                    Blocks = $Results.result.data 
                }
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpBlockByHash {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker = "xch",

        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [Alias("Hash")]
        [string]$Blockhash
    )

    Process{
        try{
            $Query = "pool/blockByHash?coin=$CoinTicker&blockHash=$BlockHash"
            $Results = Invoke-FlexPoolAPI -Query $Query
            if ($null -eq $Results.error){
                $Results.result.psobject.TypeNames.Insert(0,"PSFlexPool.Block")
                $Results.result.TimeStamp = ConvertFrom-UNIXTime $Results.result.TimeStamp
                $Results.result
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpBlocksChart {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/blocksChart?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    foreach ($blockchart in $Results.result){
                        $blockchart.psobject.TypeNames.Insert(0,"PSFlexPool.BlockChart")
                        $blockchart.TimeStamp = ConvertFrom-UNIXTime $blockchart.TimeStamp
                        $blockchart | Add-Member -MemberType NoteProperty -Name Coin -Value $coin
                        $blockchart
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpBlockStatistics {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/blockStatistics?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    foreach ($blockstat in $Results.result){
                        $blockstat.psobject.TypeNames.Insert(0,"PSFlexPool.BlockStatistic")
                        $blockstat | Add-Member -MemberType NoteProperty -Name Coin -Value $coin
                        $blockstat
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpCoin {
    [CmdletBinding()]
    param()

    try{
        $Results = Invoke-FlexPoolAPI -Query "pool/coins"
        if ($null -eq $Results.error){
            Write-Information "Got results back"
            foreach ($coin in $Results.Result.Coins){
                $coin.psobject.TypeNames.Insert(0,"PSFlexPool.Coin")
                $coin
            } #foreach
        } #if
        else{
            Write-Error $Results.Error -ErrorAction Stop
        } #else
    }
    catch{
        $PSCmdlet.WriteError($_)
    } #try/catch
}
function Get-fpCoinsFull {
    [CmdletBinding()]
    param()

    try{
        $Results = Invoke-FlexPoolAPI -Query "pool/coinsFull"
        if ($null -eq $Results.error){
            Write-Information "Got results back"
            $Results.result | ForEach-Object {
                $_.psobject.TypeNames.Insert(0,"PSFlexPool.CoinFull")
                $_
            }
        } #if
        else{
            Write-Error $Results.Error -ErrorAction Stop
        } #else
    }
    catch{
        $PSCmdlet.WriteError($_)
    } #try/catch
}
function Get-fpCurrentLuck {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/currentLuck?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    [pscustomobject]@{
                        Coin = $coin
                        AverageLuck = [decimal]$Results.Result
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpDailyRewardPerGigahashSec {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/dailyRewardPerGigahashSec?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    [pscustomobject]@{
                        Coin = $coin
                        DailyRewardPerGigahashSec = [decimal]$Results.Result
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpHashrate{
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/hashrate?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    [PSCustomObject]@{
                        Coin = $coin
                        Total = $Results.Result.total
                        Regions = $Results.Result.regions
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpHashrateChart {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/hashrateChart?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    [PSCustomObject]@{
                        Coin = $coin
                        Total = $Results.Result.Total
                        TimeStamp = $Results.Result.TimeStamp
                        Regions = $Results.Result.Regions
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpMinerAddressCoin {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Address
    )

    Process{
        try{
            $Query = "miner/locateAddress?address=$Address"
            $Results = Invoke-FlexPoolAPI -Query $Query
            if ($null -eq $Results.error){
                [PSCustomObject]@{
                    PSTypeName = "PSFlexPool.AddressCoin"
                    Coin = $Results.result
                    Address = $Address
                }
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpMinerBalance {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker,
        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Address,
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]$CounterValue = "USD"
    )

    Process{
        try{
            $Query = "miner/balance?coin=$CoinTicker&address=$Address&countervalue=$CounterValue"
            $Results = Invoke-FlexPoolAPI -Query $Query
            if ($null -eq $Results.error){
                [PSCustomObject]@{
                    PSTypeName = "PSFlexPool.MinerBalance"
                    Balance = $Results.result.balance
                    $CounterValue = $Results.result.balancecountervalue
                    Price = $Results.result.price
                    Coin = $CoinTicker
                    Address = $Address
                }
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpMinerBlock {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker,
        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Address,
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [int]$Page = 0
    )

    Process{
        try{
            $Query = "miner/blocks?coin=$CoinTicker&address=$Address&page=$Page"
            $Results = Invoke-FlexPoolAPI -Query $Query
            if ($null -eq $Results.error){
                $Results.result.data | ForEach-Object {
                    $_.psobject.TypeNames.Insert(0,"PSFlexPool.MinerBlock")
                    $_.TimeStamp = ConvertFrom-UNIXTime $_.TimeStamp
                }
                [PSCustomObject]@{
                    PSTypeName = "PSFlexPool.MinerBlockPage"
                    TotalItems = $Results.result.TotalItems
                    TotalPages = $Results.result.TotalPages
                    CurrentPage = $Page
                    Blocks = $Results.result.data
                    Coin = $CoinTicker
                    Address = $Address
                }
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpMinerBlockReward {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker,
        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Address
    )

    Process{
        try{
            $Query = "miner/blockRewards?coin=$CoinTicker&address=$Address"
            $Results = Invoke-FlexPoolAPI -Query $Query
            if ($null -eq $Results.error){
                $Results.result | Foreach-Object {
                    $_.psobject.TypeNames.insert(0,"PSFlexPool.MinerBlockReward")
                    $_.TimeStamp = ConvertFrom-UNIXTime $_.TimeStamp
                }
                $Results.result | Add-Member -NotePropertyMembers @{
                    Coin = $CoinTicker
                    Address = $Address
                }
                $Results.result
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpMinerChart {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker,
        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Address
    )

    Process{
        try{
            $Query = "miner/chart?coin=$CoinTicker&address=$Address"
            $Results = Invoke-FlexPoolAPI -Query $Query
            if ($null -eq $Results.error){
                $Results.result | Foreach-Object {
                    $_.psobject.TypeNames.insert(0,"PSFlexPool.MinerChart")
                    $_.TimeStamp = ConvertFrom-UNIXTime $_.TimeStamp
                }
                $Results.result | Add-Member -NotePropertyMembers @{
                    Coin = $CoinTicker
                    Address = $Address
                }
                $Results.result
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpMinerCount {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/minerCount?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    [PSCustomObject]@{
                        Coin = $coin
                        MinerCount = $Results.Result
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpMinerPayment {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker,
        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Address,
        [Parameter(ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [string]$CounterValue = "USD",
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [int]$Page = 0
    )

    Process{
        try{
            $Query = "miner/payments?coin=$CoinTicker&address=$Address&countervalue=$CounterValue&page=$Page"
            $Results = Invoke-FlexPoolAPI -Query $Query -ErrorAction Stop
            if ($null -eq $Results.error){
                $Results.result.data | ForEach-Object {
                    $_.psobject.TypeNames.Insert(0,"PSFlexPool.MinerPayment")
                    $_.TimeStamp = ConvertFrom-UNIXTime $_.TimeStamp
                    $_.ConfirmedTimeStamp = ConvertFrom-UNIXTime $_.ConfirmedTimeStamp
                    $_.duration = New-TimeSpan -Seconds $_.duration
                    $FiatPayment = [math]::Round($Results.result.countervalue * (ConvertFrom-CoinBaseUnit -CoinTicker 'XCH' -Value $_.value),2)
                    $_ | Add-Member -MemberType NoteProperty -Name "FiatValue" -Value $FiatPayment
                }
                [PSCustomObject]@{
                    PSTypeName = "PSFlexPool.MinerPaymentPage"
                    TotalItems = $Results.result.TotalItems
                    TotalPages = $Results.result.TotalPages
                    Payments = $Results.result.data
                    CounterValue = $Results.result.countervalue
                    Coin = $CoinTicker
                    Address = $Address
                }
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpMinerPaymentsStats {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker,
        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Address,
        [Parameter(ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [string]$CounterValue = "USD"
    )

    Process{
        try{
            $Query = "miner/paymentsStats?coin=$CoinTicker&address=$Address&countervalue=$CounterValue"
            $Results = Invoke-FlexPoolAPI -Query $Query -ErrorAction Stop
            
            if ($null -eq $Results.error){
                $paymentStats = $Results.result
                if ($null -ne $paymentStats.stats){
                    $paymentStats.lastpayment.timestamp = ConvertFrom-UNIXTime $paymentStats.lastpayment.timestamp
                    $paymentStats.lastpayment.duration = New-TimeSpan -Seconds $paymentStats.lastpayment.duration
                    $paymentStats.stats.averageDuration = New-TimeSpan -Seconds $paymentStats.stats.averageDuration
                    $FiatPayment = [math]::Round($paymentStats.countervalue * (ConvertFrom-CoinBaseUnit -CoinTicker 'XCH' -Value $paymentStats.lastpayment.value),2)
                    $totalfiatpaid = [math]::Round($paymentStats.countervalue * (ConvertFrom-CoinBaseUnit -CoinTicker 'XCH' -Value $paymentStats.stats.totalpaid),2)
                    $paymentStats.lastpayment | Add-Member -MemberType NoteProperty -Value $FiatPayment -Name "FiatValue"
                    $paymentStats.stats | Add-Member -MemberType NoteProperty -Name "TotalFiatPaid" -Value $totalfiatpaid
                }
                $paymentStats | Add-Member -NotePropertyMembers @{
                    PSTypeName = "PSFlexPool.MinerPaymentsStats"
                    Coin = $CoinTicker
                    Address = $Address
                }
                $paymentStats
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpMinerRoundShare {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker,
        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Address
    )

    Process{
        try{
            $Query = "miner/roundShare?coin=$CoinTicker&address=$Address"
            $Results = Invoke-FlexPoolAPI -Query $Query
            if ($null -eq $Results.error){
                [PSCustomObject]@{
                    PSTypeName = "PSFlexPool.MinerRoundShare"
                    RoundShare = $Results.result
                    Coin = $CoinTicker
                    Address = $Address
                }
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpMinerRoundShareByBlock {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker,
        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Address,
        [Parameter(ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [Alias("Hash")]
        [string]$BlockHash
    )

    Process{
        try{
            $Query = "miner/roundShareAt?coin=$CoinTicker&address=$Address"
            if ($PSBoundParameters.ContainsKey("BlockHash")){
                $Query += "&blockHash=$BlockHash"
            }
            $Results = Invoke-FlexPoolAPI -Query $Query
            if ($null -eq $Results.error){
                if ($PSBoundParameters.ContainsKey("BlockHash")){
                    [PSCustomObject]@{
                        PSTypeName = "PSFlexPool.MinerRoundShareByBlock"
                        RoundShare = $Results.result.roundShare
                        RewardShare = $Results.result.rewardShare
                        Coin = $CoinTicker
                        Address = $Address
                    }
                }
                else{
                    [PSCustomObject]@{
                        PSTypeName = "PSFlexPool.MinerRoundShareByBlock"
                        RoundShare = $Results.result
                        RewardShare = $null
                        Coin = $CoinTicker
                        Address = $Address
                    }
                }
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpMinersDistribution {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/minersDistribution?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    foreach ($minerdistribution in $Results.result){
                        $minerdistribution.psobject.TypeNames.Insert(0,"PSFlexPool.MinerDistribution")
                        $minerdistribution | Add-Member -MemberType NoteProperty -Name Coin -Value $coin
                        $minerdistribution
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpMinerStats {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker,
        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Address
    )

    Process{
        try{
            $Query = "miner/stats?coin=$CoinTicker&address=$Address"
            $Results = Invoke-FlexPoolAPI -Query $Query
            if ($null -eq $Results.error){
                $Results.result.psobject.TypeNames.insert(0,"PSFlexPool.MinerStats")
                $Results.result | Add-Member -NotePropertyMembers @{
                    Coin = $CoinTicker
                    Address = $Address
                }
                $Results.result
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpMinerWorker {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker,
        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Address,
        [Parameter(ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [Alias("Name","Worker")]
        [string]$WorkerName
    )

    Process{
        try{
            $Query = "miner/workers?coin=$CoinTicker&address=$Address"
            if ($PSBoundParameters.ContainsKey("WorkerName")){
                $Query += "&worker=$WorkerName"
            }
            $Results = Invoke-FlexPoolAPI -Query $Query -ErrorAction Stop
            if ($null -eq $Results.error){
                $Results.result | ForEach-Object {
                    $_.psobject.TypeNames.insert(0,"PSFlexPool.MinerWorker")
                    $_.lastSeen = ConvertFrom-UNIXTime $_.lastSeen
                }
                $Results.result | Add-Member -NotePropertyMembers @{
                    Coin = $CoinTicker
                    Address = $Address
                }
                $Results.result
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpMinerWorkerCount {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string]$CoinTicker,
        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Address
    )

    Process{
        try{
            $Query = "miner/workerCount?coin=$CoinTicker&address=$Address"
            $Results = Invoke-FlexPoolAPI -Query $Query
            if ($null -eq $Results.error){
                [PSCustomObject]@{
                    PSTypeName = "PSFlexPool.MinerWorkerCount"
                    WorkersOnline = $Results.result.WorkersOnline
                    WorkersOffline = $Results.result.WorkersOffline
                    Coin = $CoinTicker
                    Address = $Address
                }
            }
            else{
                Write-Error $Results.error -ErrorAction Stop
            }
        }
        catch{
            $PSCmdlet.WriteError($_)
        } #try/catch
    } #Process
}
function Get-fpNetworkDifficulty {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/networkHashrate?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    [PSCustomObject]@{
                        Coin = $coin
                        NetworkDifficulty = [decimal]$Results.result
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpNetworkHashrate{
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/networkHashrate?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    [PSCustomObject]@{
                        Coin = $coin
                        NetworkHashrate = [decimal]$Results.result
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpTopMiners {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/topMiners?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    foreach ($miner in $Results.result){
                        $miner.psobject.TypeNames.Insert(0,"PSFlexPool.TopMiner")
                        $miner | Add-Member -MemberType NoteProperty -Name Coin -Value $coin
                        $miner.firstJoined = ConvertFrom-UNIXTime $miner.firstJoined
                        $miner | Add-Member -NotePropertyMembers @{
                            "Balance_$Coin" = (ConvertFrom-CoinBaseUnit $Coin -Value $miner.balance)
                        }
                        $miner
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Get-fpWorkerCount {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateSet("XCH","ETH")]
        [string[]]$CoinTicker = @("XCH","ETH")
    )

    Process{
        foreach ($coin in $CoinTicker){
            try{
                $Query = "pool/workerCount?coin=$coin"
                $Results = Invoke-FlexPoolAPI -Query $Query
                if ($null -eq $Results.error){
                    [PSCustomObject]@{
                        Coin = $coin
                        WorkerCount = $Results.Result
                    }
                }
                else{
                    Write-Error $Results.error -ErrorAction Stop
                }
            }
            catch{
                $PSCmdlet.WriteError($_)
            } #try/catch
        } #foreach coin
    } #Process
}
function Set-fpMinerAddress {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [string]$Address
    )

    Process {
        try{
            $PSFlexPoolPath = "$ENV:LOCALAPPDATA\PSFlexPool"
            if (-not(Test-Path $PSFlexPoolPath)){
                [void](New-Item -Path $PSFlexPoolPath -ItemType Directory)
            }
            try {
                $AddressCoinPair = Get-fpMinerAddressCoin @PSBoundParameters -ErrorAction Stop
                $AddressCoinPair | Export-Clixml "$PSFlexPoolPath\SavedAddress.xml"
            }   
            catch{
                Write-Error "Unable to find address on FlexPool: $($_.Exception.Message)" -ErrorAction Stop
            }
            Import-fpMinerAddress
        }
        catch{
            $PSCmdlet.WriteError($_)            
        } #try/catch
    } #Process
}
function ConvertFrom-UNIXTime {
    [CmdletBinding()]
    param(
        [int]$Seconds
    )
    return [DateTime]::new(1970,1,1,0,0,0,[System.DateTimeKind]::Utc).AddSeconds([int]$Seconds).ToLocalTime()
}
function Import-fpMinerAddress {
    [CmdletBinding()]
    param()

    try{
        $AddressPath = "$ENV:LOCALAPPDATA\PSFlexPool\SavedAddress.xml"
        if (Test-Path $AddressPath){
            $AddressCoinPair = Import-Clixml $AddressPath
            Get-Command -Module PSFlexPool -ParameterName "Address" | ForEach-Object {
                try {
                    $Global:PSDefaultParameterValues["$($_.Name):Address"] = $AddressCoinPair.Address
                    $Global:PSDefaultParameterValues["$($_.Name):CoinTicker"] = $AddressCoinPair.Coin
                }
                catch{
                    Write-Warning "Unable to set default parameter value for $($_.Name)"
                }
            }
        }
        else{
            Write-Warning "No saved miner address found. Use Set-fpMinerAddress to set default address to use for Miner functions!"
        }
    }
    catch{
        $PSCmdlet.WriteError($_)
    }
}
function Invoke-FlexPoolAPI {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$Query
    )

    try{
        $BaseURL = "https://api.flexpool.io/v2/"
        $RestMethodParameters = @{
            Uri = $BaseURL + $Query
            Method = "GET"
        }
        Invoke-RestMethod @RestMethodParameters
    }
    catch{
        $PSCmdlet.WriteError($_)
    } #try/catch
}
Import-fpMinerAddress
Export-ModuleMember -function ConvertFrom-CoinBaseUnit, Get-fpAverageBlockReward, Get-fpAverageHashrate, Get-fpAverageLuck, Get-fpBlock, Get-fpBlockByHash, Get-fpBlocksChart, Get-fpBlockStatistics, Get-fpCoin, Get-fpCoinsFull, Get-fpCurrentLuck, Get-fpDailyRewardPerGigahashSec, Get-fpHashrate, Get-fpHashrateChart, Get-fpMinerAddressCoin, Get-fpMinerBalance, Get-fpMinerBlock, Get-fpMinerBlockReward, Get-fpMinerChart, Get-fpMinerCount, Get-fpMinerPayment, Get-fpMinerPaymentsStats, Get-fpMinerRoundShare, Get-fpMinerRoundShareByBlock, Get-fpMinersDistribution, Get-fpMinerStats, Get-fpMinerWorker, Get-fpMinerWorkerCount, Get-fpNetworkDifficulty, Get-fpNetworkHashrate, Get-fpTopMiners, Get-fpWorkerCount, Set-fpMinerAddress