PSChia.psm1

$Script:HostName = "localhost"
function Add-ChiaPlotDirectory {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [string]$Path
    )

    $Param = @{
        Command = "add_plot_directory"
        Parameters = (@{dirname = $Path} | ConvertTo-Json)
        Service = "Harvester"
    }

    Invoke-chiaRPCCommand @Param
}
function Close-ChiaConnection {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [int]$NodeId
    )

    $Param = @{
        Command = "close_connection"
        Parameters = @{node_id = $NodeId} | ConvertTo-Json
        Service = "Full_Node"
    }

    Invoke-chiaRPCCommand @Param
}
function Enter-ChiaPSSession {
    param(
        [ArgumentCompleter({
            param ($commandName,$parameterName,$wordToComplete,$commandAst,$fakeBoundParameters)
            Get-ChildItem -Path $env:LOCALAPPDATA\PSChia -Filter "*$wordToComplete*" -Directory | foreach {
                [System.Management.Automation.CompletionResult]::new($_.Name,$_.Name,"ParameterValue",$_.Name)
            }
        })]
        [ValidateScript(
            {$_ -in (Get-ChildItem -Path $env:LOCALAPPDATA\PSChia -Directory).Name}
        )]
        $HostName
    )

    $Script:HostName = $HostName
}
function Find-ChiaFarmedBlock {
    [CmdletBinding()]
    param(
        [int]$WalletId = 1
    )

    $Transactions = Get-ChiaTransaction -WalletId $WalletId | where {$_.Type -eq 2 -or $_.Type -eq 3}
    $grouped = $Transactions | group confirmed_at_height

    foreach ($group in $grouped){
        $blocks = Get-ChiaBlock -StartHeight ($group.Name - 100) -EndHeight $group.Name
        $farmedBlock = $blocks | where {$_.foliage.foliage_block_data.farmer_reward_puzzle_hash -eq $group.Group[0].to_puzzle_hash}

        [PSCustomObject]@{
            ConfirmedHeight = $group.Name
            FarmedHeight = $farmedBlock.reward_chain_block.height
            plot_public_key = $farmedBlock.reward_chain_block.proof_of_space.plot_public_key
        }
    }
}
function Get-ChiaAdditionsandRemovals{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$HeaderHash,

        [Parameter(Mandatory)]
        [string]$NewerHeaderHash
    )

    $Param = @{
        Command = "get_additions_and_removals"
        Parameters = (@{header_hash = $HeaderHash; newer_block_header_hash = $NewerHeaderHash}) | ConvertTo-Json
        Service = "Full_Node"
    }

    $Response = Invoke-chiaRPCCommand @Param
    if ($Response.success){
        [PSCustomObject]@{
            Additions = $Response.additions
            Removals = $Response.removals
        }
    }
    else{
        Write-Error "Command Failed: $($Response.error)"
    }
}
function Get-ChiaBlock {
    [CmdletBinding(DefaultParameterSetName = "SingleBlock")]
    param(
        [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName,
        ParameterSetName = "SingleBlock")]
        [Alias("header_hash")]
        [string[]]$HeaderHash,

        [Parameter(Mandatory,ParameterSetName = "Blocks")]
        [int]$StartHeight,

        [Parameter(Mandatory,ParameterSetName = "Blocks")]
        [int]$EndHeight,

        [Parameter(ParameterSetName = "Blocks")]
        [switch]$ExcludeHeaderHash

    )

    Begin{
        $Param = @{
            Command = "get_block"
            Parameters = "" | ConvertTo-Json
            Service = "Full_Node"
        }
    }

    Process{
        if ($PSBoundParameters.ContainsKey("HeaderHash")){
            foreach ($hash in $HeaderHash){
                $Param["Parameters"] = @{header_hash = $hash} | ConvertTo-Json
                $Response = Invoke-chiaRPCCommand @Param
                if ($Response.success){
                    $Response.block
                }
                else{
                    $Response
                }
            }
        }
        else{
            $Parameters = @{
                start = $StartHeight
                end = $EndHeight
                Exclude_header_hash = $ExcludeHeaderHash.IsPresent
            }
            $Param["Command"] = "get_blocks"
            $Param["Parameters"] = ($Parameters | ConvertTo-Json)
            $Response = Invoke-chiaRPCCommand @Param
            if ($Response.success){
                $Response.blocks
            }
            else{
                $Response
            }
        }
    }

}
function Get-ChiaBlockChainState {
    [CmdletBinding()]
    param()

    $Param = @{
        Command = "get_blockchain_state"
        Parameters = ("" | ConvertTo-Json)
        Service = "Full_Node"
    }

    $Response = Invoke-chiaRPCCommand @Param
    if ($Response.success){
        $BlockChainState = $Response.blockchain_state
        $BlockChainState.PSObject.TypeNames.Insert(0,"PSChia.ChiaBlockChainState")
        $BlockChainState | Add-Member -MemberType ScriptProperty -Name Height -Value {$this.peak.height}
        $BlockChainState | Add-Member -MemberType ScriptProperty -Name Synced -Value {$this.sync.synced}
        $BlockChainState | Add-Member -MemberType ScriptProperty -Name SpacePB -Value {[math]::Round($this.Space / 1.126e+15,2)}
        $BlockChainState
    }
    else{
        Write-Warning "Command failed"
        $Response
    }
}
function Get-ChiaBlockRecord{
    [CmdletBinding(DefaultParameterSetName = "Height")]
    param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,
        ParameterSetName = "Height")]
        [int[]]$Height,

        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,
        ParameterSetName = "HeaderHash")]
        [string[]]$HeaderHash,

        [Parameter(Mandatory, ParameterSetName = "StartAndEndHeight")]
        [int]$StartHeight,

        [Parameter(Mandatory, ParameterSetName = "StartAndEndHeight")]
        [int]$EndHeight
    )

    Begin{
        switch ($PSCmdlet.ParameterSetName){
            "Height" {$Command = "get_block_record_by_height"}
            "HeaderHash" {$Command = "get_block_record"}
            "StartAndEndHeight" {$Command = "get_block_records"}
        }
        $Param = @{
            Command = $Command
            Parameters = "" | ConvertTo-Json
            Service = "Full_Node"
        }
    }

    Process{
        switch ($PSCmdlet.ParameterSetName){
            "Height" {
                foreach ($h in $Height){
                    $Param["Parameters"] = (@{height = $h} | ConvertTo-Json)
                    $Response = Invoke-chiaRPCCommand @Param
                    if ($Response.success){
                        $Response.block_record
                    }
                    else{
                       Write-Error "Command Failed: $($Response.error)"
                    }
                } #foreach
            }

            "HeaderHash" {
                foreach ($hash in $HeaderHash){
                    $Param["Parameters"] = (@{header_hash = $hash} | ConvertTo-Json)

                    $Response = Invoke-chiaRPCCommand @Param
                    if ($Response.success){
                        $Response.block_record
                    }
                    else{
                        Write-Error "Command Failed: $($Response.error)"
                    }
                }
            }

            "StartAndEndHeight" {
                $Param["Parameters"] = (@{start = $StartHeight; end = $EndHeight} | ConvertTo-Json)

                $Response = Invoke-chiaRPCCommand @Param
                if ($Response.success){
                    $Response.block_records
                }
                else{
                    Write-Error "Command Failed: $($Response.error)"
                }
            }
        }
    }
}
function Get-ChiaConnection {
    [CmdletBinding()]
    param(
        [Parameter()]
        [ValidateSet("Harvester","Wallet","Full_Node","Farmer")]
        [string]$Service = "Full_Node"
    )

    $Param = @{
        Command = "get_connections"
        Parameters = "" | ConvertTo-Json
        Service = $Service
    }

    $Response = Invoke-chiaRPCCommand @Param
    if ($Response.success){
        $Response.connections
    }
    else{
        Write-Error "Command Failed: $($Response.error)"
    }
}
function Get-ChiaFarmedAmount {
    [CmdletBinding()]
    param()

    $Param = @{
        Command = "get_farmed_amount"
        Parameters = "" | ConvertTo-Json
        Service = "Wallet"
    }

    $Response = Invoke-chiaRPCCommand @Param
    if ($Response.success){
        $Response
    }
    else{
        Write-Error "Command Failed: $($Response.error)"
    }
}
function Get-ChiaFarmedPlot {
    [CmdletBinding()]
    param()

    $FarmedBlocks = Find-ChiaFarmedBlock
    $Plots = Get-ChiaPlot

    $Plots | where Plot_Public_Key -in $FarmedBlocks.plot_public_key
}
function Get-ChiaInitialFreezePeriod {
    [CmdletBinding()]
    param()

    $Param = @{
        Command = "get_initial_freeze_period"
        Parameters = "" | ConvertTo-Json
        Service = "Wallet"
    }
<#
#?? Command Failed; get_initial_freeze_period() takes 1 positional argument but 2 were given ??
    $Response = Invoke-chiaRPCCommand @Param
    if ($Response.success){
        $Response
    }
    else{
        Write-Error "Command Failed; $($Response.error)"
    }
#>


}
function Get-ChiaNetworkInfo {
    [CmdletBinding()]
    param()

    $Param = @{
        Command = "get_network_info"
        Parameters = "" | ConvertTo-Json
        Service = "Full_Node"
    }

    $Response = Invoke-chiaRPCCommand @Param
    if ($Response.success){
        $Response
    }
    else{
        Write-Error "Command Failed: $($Response.error)"
    }
}
function Get-ChiaNetworkSpace{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$OlderHeaderHash,

        [Parameter(Mandatory)]
        [string]$NewerHeaderHash
    )

    $Param = @{
        Command = "get_network_space"
        Parameters = (@{older_block_header_hash = $OlderHeaderHash; newer_block_header_hash = $NewerHeaderHash} | ConvertTo-Json)
        Service = "Full_Node"
    }

    $Response = Invoke-chiaRPCCommand @Param
    if ($Response.success){
        $Response.space
    }
    else{
        Write-Error "Command Failed: $($Response.error)"
    }

}
function Get-ChiaPlot {
    [CmdletBinding()]
    param(
    )

    $Param = @{
        Command = "get_plots"
        Parameters = ("" | ConvertTo-Json)
        Service = "Harvester"
    }

    $Response = Invoke-chiaRPCCommand @Param
    if ($Response.success){
        foreach ($plot in $Response.plots){
            [PSCustomObject]@{
                PSTypeName = "PSChia.ChiaPlot"
                Parent_Folder = (Split-Path $plot.filename -Parent)
                File_Name = (Split-Path $plot.filename -Leaf)
                FullName = $plot.filename
                File_Size = $plot.file_size
                File_SizeGB = [math]::Round($plot.file_size / 1gb,2)
                "K-Size" = $plot.size
                Modified_Time = ConvertFrom-UnixEpoch $Plot.time_modified
                Plot_Seed = $plot."plot-seed"
                Plot_Public_Key = $plot.plot_public_key
                Pool_Public_Key = $plot.pool_public_key
                Pool_Contract_Puzzle_Hash = $plot.pool_contract_puzzle_hash
            }
        }
    }
}
function Get-ChiaPlotDirectory {
    [CmdletBinding()]
    param()

    $Param = @{
        Command = "get_plot_directories"
        Parameters = ("" | ConvertTo-Json)
        Service = "Harvester"
    }

    $Response = Invoke-chiaRPCCommand @Param
    if ($Response.success){
        foreach ($directory in $Response.directories){
            [PSCustomObject]@{
                DirectoryPath = $directory
            }
        }
    }
    else{
        Write-Error "Command Failed: $($Response.error)"
    }
}
function Get-ChiaRewardTarget {
    [CmdletBinding()]
    param(
        [switch]$SearchForPrivateKey
    )

    $Param = @{
        Command = "get_reward_targets"
        Parameters = @{search_for_private_key = $SearchForPrivateKey.IsPresent} | ConvertTo-Json
        Service = "Farmer"
    }

    $Response = Invoke-chiaRPCCommand @Param
    if ($Response.success){
        [PSCustomObject]@{
            FarmerTarget = $Response.farmer_target
            PoolTarget = $Response.pool_target
            HaveFarmerSK = $Response.have_farmer_sk
            HavePoolSK = $Response.have_pool_sk
        }
    }
    else{
        Write-Error "Command Failed: $($Response.error)"
    }
}
function Get-ChiaSignagePoint {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        [Alias("SigPoint","sp_hash")]
        [string[]]$SignagePoint
    )

    Begin{
        $Param = @{
            Command = "get_signage_point"
            Parameters = "" | ConvertTo-Json
            Service = "Farmer"
        }
    }

    Process{
        if ($PSBoundParameters.ContainsKey("SignagePoint")){
            foreach ($hash in $SignagePoint){
                Write-Information "Getting Sig Point $hash"
                $Param["Parameters"] = @{sp_hash = $hash} | ConvertTo-Json
                $Response = Invoke-chiaRPCCommand @Param
                if ($Response.success){
                    [PSCustomObject]@{
                        Proofs = $Response.proofs

                    }
                }
                else{
                    Write-Error "Command Failed: $($Response.error)"
                }
            }
        }
        else{
            Write-Information "Getting all recent sig points"
            $Param["Command"] = "get_signage_points"
            $Response = Invoke-chiaRPCCommand @Param
            if ($Response.success){
                $Response.signage_points | foreach {
                    [PSCustomObject]@{
                        Proofs = $_.proofs
                        SignagePoint = $_.signage_point
                    }
                }
            }
            else{
                Write-Error "Command Failed: $($Response.error)"
            }
        }
    } #Process
}
function Get-ChiaTransaction {
    [CmdletBinding(DefaultParameterSetName = "WalletId")]
    param(
        #[Parameter(Mandatory, ParameterSetName = "TransactionId")]
        #[string]$TransactionID,

        [Parameter(Mandatory, ParameterSetName = "WalletId")]
        [ValidateRange(1, [int]::MaxValue)]
        [int]$WalletId
    )

    if ($PSCmdlet.ParameterSetName -eq "WalletId"){
        $Param = @{
            Command = "get_transactions"
            Parameters = @{wallet_id = $WalletId} | ConvertTo-Json
            Service = "Wallet"
        }
    }
    else{
        $Param = @{
            Command = "get_transaction"
            Parameters = @{transaction_id = $TransactionID} | ConvertTo-Json
            Service = "Wallet"
        }
    }

    try{
        $Response = Invoke-chiaRPCCommand @Param -ErrorAction Stop
        if ($Response.success){
            $Response.transactions
            #$Response.transaction
        }
        else{
            Write-Error "Command Failed: $($Response.error)"
        }
    }
    catch{
        $PSCmdlet.WriteError($_)
    }

}
function Get-ChiaTransactionCount {
    [CmdletBinding()]
    param(
        [ValidateRange(1,[int]::MaxValue)]
        [int]$WalletId
    )

    $Param = @{
        Command = "get_transaction_count"
        Parameters = @{wallet_id = $WalletId} | ConvertTo-Json
        Service = "Wallet"
    }

    $Response = Invoke-chiaRPCCommand @Param
    if ($Response.success){
        [pscustomobject]@{
            WalletId = $Response.wallet_id
            Count = $Response.count
        }
    }
    else{
        Write-Error "Command Failed: $($Response.error)"
    }
}
function Get-ChiaUnfinishedBlockHeader{
    [CmdletBinding()]
    param()

    $Param = @{
        Command = "get_unfinished_block_headers"
        Parameters = "" | ConvertTo-Json
        Service = "Full_Node"
    }

    $Response = Invoke-chiaRPCCommand @Param
    if ($Response.success){
        $Response
    }
}
function Invoke-ChiaRefreshPlots {
    [CmdletBinding()]
    param()

    $Param = @{
        Command = "refresh_plots"
        Parameters = ("" | ConvertTo-Json)
        Service = "Harvester"
    }

    Invoke-chiaRPCCommand @Param
}
function New-ChiaPSSession {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [Alias("IPAddress")]
        [string]$HostName,

        [Parameter(Mandatory)]
        [ValidateSet("Harvester","Wallet","Full_Node","Farmer")]
        [string]$Service,

        [Parameter()]
        [string]$CertPathDirectory
    )

    if ($PSBoundParameters.ContainsKey("CertPathDirectory")){
        New-chiaPFXCert -HostName $HostName -Service $Service -CertPathDirectory $CertPathDirectory
    }
    else{
        New-chiaPFXCert -HostName $HostName -Service $Service
    }
}
function Open-ChiaConnection {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [Alias("IPAddress")]
        [string]$Hostname,

        [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [int]$Port
    )

    $Param = @{
        Command = "open_connection"
        Parameters = @{host = $Hostname; port = $Port} | ConvertTo-Json
        Service = "Full_Node"
    }

    Invoke-chiaRPCCommand @Param
}
function Remove-ChiaPlot {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [Alias("FullName")]
        [string[]]$FileName
    )

    Process{
        foreach ($plot in $FileName){
            $Param = @{
                Command = "delete_plot"
                Parameters = (@{filename = $plot} | ConvertTo-Json)
                Service = "Harvester"
            }

            #Write-Warning "Function not tested yet and so not yet implemented"
            $response = Invoke-chiaRPCCommand @Param
            $response
        }
    }
}
function Remove-ChiaPlotDirectory {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [string[]]$Path
    )

    Process{
        foreach ($directory in $Path){
            $Param = @{
                Command = "remove_plot_directory"
                Parameters = (@{dirname = $directory} | ConvertTo-Json)
                Service = "Harvester"
            }
            Invoke-chiaRPCCommand @Param | foreach {
                [PSCustomObject]@{
                    Path = $directory
                    Success = $_.success
                }
            }
        }
    }
}
function Set-ChiaRewardTarget {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$FarmerTargetAddress,

        [Parameter(Mandatory)]
        [string]$PoolTargetAddress
    )

    $Param = @{
        Command = "set_reward_targets"
        Parameters = @{farmer_target = $FarmerTargetAddress; pool_target = $PoolTargetAddress} | ConvertTo-Json
        Service = "Farmer"
    }

    Invoke-chiaRPCCommand @Param
}
function Stop-ChiaNode {
    [CmdletBinding()]
    param()

    $Param = @{
        Command = "stop_node"
        Parameters = "" | ConvertTo-Json
        Service = "Full_Node"
    }
    
    Write-Warning "Untested"
    #Invoke-chiaRPCCommand @Param
}
function ConvertFrom-UnixEpoch{
    param(
        $Seconds
    )
    [DateTime]::new(1970,1,1,0,0,0,[System.DateTimeKind]::Utc).AddSeconds($Seconds).ToLocalTime()
}
function Get-chiaPFXCert{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateSet("Harvester","Wallet","Full_Node","Farmer")]
        [string]$Service,
        
        [string]$HostName = "Localhost"
    )
    Write-Information "Grabbing $Service PFX Cert"
    $ErrorActionPreference = "Stop"
    try{
        $PSChiaPath = "$ENV:LOCALAPPDATA\PSChia\$HostName"
        if (Test-Path "$PSChiaPath\$Service.pfx"){
            $encryptedPassword = Get-Content "$PSChiaPath\$($Service)Pass.txt"
            $password = [pscredential]::new("Chia",(ConvertTo-SecureString -String $encryptedPassword)).GetNetworkCredential().Password
            Write-Information "Importing $Service PFX Cert"
            $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::New("$PSChiaPath\$Service.pfx",$password,'DefaultKeySet')
            $ErrorActionPreference = "Continue"
            return $cert
        }
        elseif ($HostName -eq "Localhost"){
            Write-Information "$Service Cert not found, going to try and create one now"
            New-chiaPFXCert -Service $Service -ErrorAction Stop
            Get-chiaPFXCert -Service $Service -ErrorAction Stop
        }
    }
    catch{
        $ErrorActionPreference = "Continue"
        $PSCmdlet.WriteError($_)
    }
}
function Get-OpenSSLPath {
    [CmdletBinding()]
    param()
    $OpenSSLPath = "C:\Program Files\Git\mingw64\bin\openssl.exe"
    $OpenSSL2ndPath = "$ENV:LOCALAPPDATA\Programs\Git\mingw64\bin\openssl.exe"
    if (Test-Path $OpenSSLPath){
        $OpenSSLPath
    }
    elseif (Test-Path $OpenSSL2ndPath){
        $OpenSSL2ndPath
    }
    else{
        $Message = "GIT is not installed, please install GIT so that OpenSSL can be used."
        $ErrorRecord = [System.Management.Automation.ErrorRecord]::new(
            [System.IO.FileNotFoundException]::new($Message,"C:\Program Files\Git\mingw64\bin\openssl.exe"),
            'GITNotInstalledException',
            [System.Management.Automation.ErrorCategory]::ObjectNotFound ,
            "C:\Program Files\Git\mingw64\bin\openssl.exe"
        )
        $PSCmdlet.WriteError($ErrorRecord)
    }
}
function Invoke-chiaRPCCommand {
    [CmdletBinding()]
    param(
        [string]$Command,

        [string]$Parameters,

        [ValidateSet("Harvester","Wallet","Full_Node","Daemon","Farmer")]
        [string]$Service,

        [string]$HostName = $Script:HostName
    )

    Try{
        $Cert = Get-chiaPFXCert -Service $Service -HostName $HostName -ErrorAction Stop
        switch ($Service){
            "Harvester" {
                Write-Information "Harvester service flagged, setting port and getting cert"
                $Port = 8560
            }
            "Wallet" {
                $Port = 9256
            }
            "Full_Node" {
                $Port = 8555
            }
            "Farmer" {
                $Port = 8559
            }
            "Daemon" {
                $Port = 55400
            }
        } #switch
    }
    catch{
       Write-Error "Unable to grab/create Cert for $Service service: $_" -ErrorAction Stop
    }

    $Param = @{
        Method = "Post"
        Uri = "https://$($HostName):$($Port)/$($Command)"
        ContentType = "application/json"
        Body = $Parameters
        Certificate = $Cert
    }

    try{
        Invoke-RestMethod @Param
    }
    catch [System.InvalidOperationException]{
        if ($_.Exception.Message -like "*Could not establish trust relationship for the SSL/TLS secure channel.*"){
            Write-Information "Insecure sessions not allowed, setting Cert Call Back to allow."
            Set-CertCallBack
            Invoke-RestMethod @Param
        }
        else{
            $PSCmdlet.WriteError($_)
        }
    }
    catch{
        $PSCmdlet.WriteError($_)
    }
}
function New-chiaPassword {
    $Length = 0..20
    [System.Collections.ArrayList]$ASCII = @(48..57)
    65..90 | foreach {$ASCII.Add($_)} | Out-Null
    97..122 | foreach {$ASCII.Add($_)} | Out-Null
    ($Length | foreach {[char](Get-Random -InputObject $ASCII)}) -join ""
}
function New-chiaPFXCert {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateSet("Harvester","Wallet","Full_Node","Farmer")]
        [string]$Service,
        [string]$HostName = "Localhost",
        [string]$CertPathDirectory
    )
    Write-Information "Creating new PFX Cert for $Service service"
    $ErrorActionPreference = "Stop"
    try{
        $OpenSSL = Get-OpenSSLPath -ErrorAction Stop
        if ($PSBoundParameters.ContainsKey("CertPathDirectory")){
            $ServicePath = $CertPathDirectory
        }
        else{
            $ServicePath = "$ENV:USERPROFILE\.Chia\mainnet\config\ssl\$Service"
        }
        $PFXPath = "$ENV:LOCALAPPDATA\PSChia"
        if (!(Test-Path $PFXPath)){
            New-Item -Path "$ENV:LOCALAPPDATA\PSChia" -ItemType Directory | Out-Null
        }
        if ((Test-Path "$ServicePath\private_$Service.crt") -and (Test-Path "$ServicePath\private_$Service.key")){
            $cert = "$ServicePath\private_$Service.crt"
            $key = "$ServicePath\private_$Service.key"
        }
        else{
            $Message = "Chia Certs/Key Not Found for $Service"
            $ErrorRecord = [System.Management.Automation.ErrorRecord]::new(
                [System.IO.FileNotFoundException]::new($Message,$SErvicePath),
                'CertNotFound',
                [System.Management.Automation.ErrorCategory]::ObjectNotFound,
                "$ServicePath"
            )
            $PSCmdlet.ThrowTerminatingError($ErrorRecord)
        }

        $PFXHostPath = "$ENV:LOCALAPPDATA\PSChia\$Hostname"
        if (!(Test-Path $PFXHostPath)){
            New-Item -Path "$ENV:LOCALAPPDATA\PSChia\$Hostname" -ItemType Directory | Out-Null
        }

        $pass = New-chiaPassword
        $password = ConvertTo-SecureString -String $pass -AsPlainText -Force
        $EncryptedPassword = ConvertFrom-SecureString -SecureString $password
        $EncryptedPassword | Out-File -FilePath "$PFXHostPath\$($Service)Pass.txt"
    
        &$OpenSSL pkcs12 -export -out "$PFXHostPath\$($Service).pfx" -inkey $key -in $cert -passout pass:$pass
        Write-Information "$Service PFX Cert successfully created"
        $ErrorActionPreference = "Continue"
    }
    catch [System.IO.FileNotFoundException]{
        $ErrorActionPreference = "Continue"
        $PSCmdlet.WriteError($_)
    }
    catch{
        $ErrorActionPreference = "Continue"
        Write-Error "Unable to create $Service Cert: $($_)" -ErrorAction Stop
    }
}
function Set-CertCallBack {
    if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type)
    {
        $certCallback = @"
            using System;
            using System.Net;
            using System.Net.Security;
            using System.Security.Cryptography.X509Certificates;
            public class ServerCertificateValidationCallback
            {
                public static void Ignore()
                {
                    if(ServicePointManager.ServerCertificateValidationCallback ==null)
                    {
                        ServicePointManager.ServerCertificateValidationCallback +=
                            delegate
                            (
                                Object obj,
                                X509Certificate certificate,
                                X509Chain chain,
                                SslPolicyErrors errors
                            )
                            {
                                return true;
                            };
                    }
                }
            }
"@

            Add-Type $certCallback
    }
    [ServerCertificateValidationCallback]::Ignore()

}
Export-ModuleMember -function Add-ChiaPlotDirectory, Close-ChiaConnection, Enter-ChiaPSSession, Find-ChiaFarmedBlock, Get-ChiaAdditionsandRemovals, Get-ChiaBlock, Get-ChiaBlockChainState, Get-ChiaBlockRecord, Get-ChiaConnection, Get-ChiaFarmedAmount, Get-ChiaFarmedPlot, Get-ChiaInitialFreezePeriod, Get-ChiaNetworkInfo, Get-ChiaNetworkSpace, Get-ChiaPlot, Get-ChiaPlotDirectory, Get-ChiaRewardTarget, Get-ChiaSignagePoint, Get-ChiaTransaction, Get-ChiaTransactionCount, Get-ChiaUnfinishedBlockHeader, Invoke-ChiaRefreshPlots, New-ChiaPSSession, Open-ChiaConnection, Remove-ChiaPlot, Remove-ChiaPlotDirectory, Set-ChiaRewardTarget, Stop-ChiaNode