diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 0.4.5 *October 10th 2023*
+* Support for GHC-9.8.1
+
 ## 0.4.4 *February 20th 2023*
 * Support for GHC-9.6.0.20230210
 
diff --git a/defaults.dhall b/defaults.dhall
--- a/defaults.dhall
+++ b/defaults.dhall
@@ -1,5 +1,5 @@
 { name = "ghc-tcplugins-extra"
-, version = "0.4.4"
+, version = "0.4.5"
 , synopsis = "Utilities for writing GHC type-checker plugins"
 , description =
     ''
@@ -17,7 +17,7 @@
 , license = "BSD2"
 , license-file = "LICENSE"
 , tested-with =
-    "GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC == 9.2.6, GHC == 9.4.4, GHC == 9.6.1"
+    "GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC == 9.2.8, GHC == 9.4.7, GHC == 9.6.3, GHC == 9.8.1"
 , extra-source-files =
   [ "README.md", "CHANGELOG.md", "defaults.dhall", "package.dhall" ]
 , ghc-options = [ "-Wall" ]
diff --git a/ghc-tcplugins-extra.cabal b/ghc-tcplugins-extra.cabal
--- a/ghc-tcplugins-extra.cabal
+++ b/ghc-tcplugins-extra.cabal
@@ -1,11 +1,11 @@
 cabal-version: 2.0
 
--- This file has been generated from package.dhall by hpack version 0.35.2.
+-- This file has been generated from package.dhall by hpack version 0.35.5.
 --
 -- see: https://github.com/sol/hpack
 
 name:           ghc-tcplugins-extra
-version:        0.4.4
+version:        0.4.5
 synopsis:       Utilities for writing GHC type-checker plugins
 description:    Utilities for writing GHC type-checker plugins, such as
                 creating constraints, with a stable API covering multiple
@@ -21,7 +21,7 @@
 license-file:   LICENSE
 build-type:     Simple
 tested-with:
-    GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC == 9.2.6, GHC == 9.4.4, GHC == 9.6.1
+    GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC == 9.2.8, GHC == 9.4.7, GHC == 9.6.3, GHC == 9.8.1
 extra-source-files:
     README.md
     CHANGELOG.md
@@ -47,7 +47,7 @@
   ghc-options: -Wall
   build-depends:
       base >=4.8 && <5
-    , ghc >=7.10 && <9.8
+    , ghc >=7.10 && <9.10
   default-language: Haskell2010
   if impl(ghc >= 8.0.0)
     ghc-options: -Wcompat -Wincomplete-uni-patterns -Widentities -Wredundant-constraints
@@ -55,6 +55,19 @@
     ghc-options: -fhide-source-paths
   if flag(deverror)
     ghc-options: -Werror
+  if impl(ghc >= 9.8) && impl(ghc < 9.10)
+    other-modules:
+        GhcApi.Constraint
+        GhcApi.Predicate
+        GhcApi.GhcPlugins
+        Internal.Type
+        Internal.Constraint
+        Internal.Evidence
+    hs-source-dirs:
+        src-ghc-tree-9.4
+        src-ghc-9.8
+    build-depends:
+        ghc >=9.8 && <9.10
   if impl(ghc >= 9.4) && impl(ghc < 9.8)
     other-modules:
         GhcApi.Constraint
diff --git a/package.dhall b/package.dhall
--- a/package.dhall
+++ b/package.dhall
@@ -26,11 +26,12 @@
                 //  { library =
                       { source-dirs = "src"
                       , dependencies =
-                        [ "base >=4.8 && <5", "ghc >=7.10 && <9.8" ]
+                        [ "base >=4.8 && <5", "ghc >=7.10 && <9.10" ]
                       , exposed-modules = "GHC.TcPluginM.Extra"
                       , other-modules = "Internal"
                       , when =
-                        [ version "9.4" "9.8" [ "tree-9.4", "9.4" ] ghc mods
+                        [ version "9.8" "9.10" [ "tree-9.4", "9.8" ] ghc mods
+                        , version "9.4" "9.8" [ "tree-9.4", "9.4" ] ghc mods
                         , version "9.2" "9.4" [ "tree", "9.2" ] ghc mods
                         , version "9.0" "9.2" [ "tree", "9.0" ] ghc mods
                         , version "8.10" "9.0" [ "flat", "8.10" ] ghc mods
diff --git a/src-ghc-9.8/GhcApi/Constraint.hs b/src-ghc-9.8/GhcApi/Constraint.hs
new file mode 100644
--- /dev/null
+++ b/src-ghc-9.8/GhcApi/Constraint.hs
@@ -0,0 +1,13 @@
+module GhcApi.Constraint
+  ( Ct(..)
+  , CtEvidence(..)
+  , CtLoc
+  , CanEqLHS(..)
+  , ctLoc
+  , ctEvId
+  , mkNonCanonical
+  )
+where
+
+import GHC.Tc.Types.Constraint
+  (Ct (..), CtEvidence (..), CanEqLHS (..), CtLoc, ctLoc, ctEvId, mkNonCanonical)
diff --git a/src-ghc-9.8/GhcApi/GhcPlugins.hs b/src-ghc-9.8/GhcApi/GhcPlugins.hs
new file mode 100644
--- /dev/null
+++ b/src-ghc-9.8/GhcApi/GhcPlugins.hs
@@ -0,0 +1,5 @@
+module GhcApi.GhcPlugins (module GHC.Plugins, FindResult(..), findPluginModule) where
+
+import GHC.Plugins hiding (TcPlugin, mkSubst)
+import GHC.Unit.Finder (findPluginModule)
+import GHC.Tc.Plugin (FindResult(..))
diff --git a/src-ghc-9.8/Internal/Constraint.hs b/src-ghc-9.8/Internal/Constraint.hs
new file mode 100644
--- /dev/null
+++ b/src-ghc-9.8/Internal/Constraint.hs
@@ -0,0 +1,64 @@
+{-# LANGUAGE RecordWildCards #-}
+
+module Internal.Constraint (newGiven, flatToCt, mkSubst, overEvidencePredType) where
+
+import GhcApi.GhcPlugins
+import GhcApi.Constraint
+  (Ct(..), CtEvidence(..), CanEqLHS(..), CtLoc, ctLoc, ctEvId, mkNonCanonical)
+
+import GHC.Tc.Utils.TcType (TcType)
+import GHC.Tc.Types.Constraint (DictCt(..), IrredCt(..), EqCt(..), QCInst(..))
+import GHC.Tc.Types.Evidence (EvTerm(..), EvBindsVar)
+import GHC.Tc.Plugin (TcPluginM)
+import qualified GHC.Tc.Plugin as TcPlugin (newGiven)
+
+-- | Create a new [G]iven constraint, with the supplied evidence. This must not
+-- be invoked from 'tcPluginInit' or 'tcPluginStop', or it will panic.
+newGiven :: EvBindsVar -> CtLoc -> PredType -> EvTerm -> TcPluginM CtEvidence
+newGiven tcEvbinds loc pty (EvExpr ev) = TcPlugin.newGiven tcEvbinds loc pty ev
+newGiven _ _ _ ev = panicDoc "newGiven: not an EvExpr: " (ppr ev)
+
+flatToCt :: [((TcTyVar,TcType),Ct)] -> Maybe Ct
+flatToCt [((_,lhs),ct),((_,rhs),_)]
+    = Just
+    $ mkNonCanonical
+    $ CtGiven (mkPrimEqPred lhs rhs)
+              (ctEvId ct)
+              (ctLoc ct)
+
+flatToCt _ = Nothing
+
+-- | Create simple substitution from type equalities
+mkSubst :: Ct -> Maybe ((TcTyVar, TcType),Ct)
+mkSubst ct@(CEqCan (EqCt {..}))
+  | TyVarLHS tyvar <- eq_lhs
+  = Just ((tyvar,eq_rhs),ct)
+mkSubst _ = Nothing
+
+-- | Modify the predicate type of the evidence term of a constraint
+overEvidencePredType :: (TcType -> TcType) -> Ct -> Ct
+overEvidencePredType f (CDictCan di) =
+  let
+    ev :: CtEvidence
+    ev = di_ev di
+  in CDictCan ( di { di_ev = ev { ctev_pred = f (ctev_pred ev) } } )
+overEvidencePredType f (CIrredCan ir) =
+  let
+    ev :: CtEvidence
+    ev = ir_ev ir
+  in CIrredCan ( ir { ir_ev = ev { ctev_pred = f (ctev_pred ev) } } )
+overEvidencePredType f (CEqCan eq) =
+  let
+    ev :: CtEvidence
+    ev = eq_ev eq
+  in CEqCan ( eq { eq_ev = ev { ctev_pred = f (ctev_pred ev) } } )
+overEvidencePredType f (CNonCanonical ct) =
+  let
+    ev :: CtEvidence
+    ev = ct
+  in CNonCanonical ( ev { ctev_pred = f (ctev_pred ev) } )
+overEvidencePredType f (CQuantCan qci) =
+  let
+    ev :: CtEvidence
+    ev = qci_ev qci
+  in CQuantCan ( qci { qci_ev = ev { ctev_pred = f (ctev_pred ev) } } )
diff --git a/src-ghc-9.8/Internal/Evidence.hs b/src-ghc-9.8/Internal/Evidence.hs
new file mode 100644
--- /dev/null
+++ b/src-ghc-9.8/Internal/Evidence.hs
@@ -0,0 +1,14 @@
+module Internal.Evidence (evByFiat) where
+
+import GHC.Tc.Types.Evidence (EvTerm(..))
+import GHC.Core.TyCo.Rep (UnivCoProvenance (..))
+
+import GhcApi.GhcPlugins
+
+-- | The 'EvTerm' equivalent for 'Unsafe.unsafeCoerce'
+evByFiat :: String -- ^ Name the coercion should have
+         -> Type   -- ^ The LHS of the equivalence relation (~)
+         -> Type   -- ^ The RHS of the equivalence relation (~)
+         -> EvTerm
+evByFiat name t1 t2 =
+  EvExpr $ Coercion $ mkUnivCo (PluginProv name) Nominal t1 t2
diff --git a/src-ghc-9.8/Internal/Type.hs b/src-ghc-9.8/Internal/Type.hs
new file mode 100644
--- /dev/null
+++ b/src-ghc-9.8/Internal/Type.hs
@@ -0,0 +1,30 @@
+module Internal.Type (substType) where
+
+import Data.Maybe (fromMaybe)
+import GHC.Tc.Utils.TcType (TcType)
+import GHC.Core.TyCo.Rep (Type (..))
+import GHC.Types.Var (TcTyVar)
+
+-- | Apply substitutions in Types
+--
+-- __NB:__ Doesn't substitute under binders
+substType
+  :: [(TcTyVar, TcType)]
+  -> TcType
+  -> TcType
+substType subst tv@(TyVarTy v) =
+  fromMaybe tv (lookup v subst)
+substType subst (AppTy t1 t2) =
+  AppTy (substType subst t1) (substType subst t2)
+substType subst (TyConApp tc xs) =
+  TyConApp tc (map (substType subst) xs)
+substType _subst t@(ForAllTy _tv _ty) =
+  -- TODO: Is it safe to do "dumb" substitution under binders?
+  -- ForAllTy tv (substType subst ty)
+  t
+substType subst (FunTy k1 k2 t1 t2) =
+  FunTy k1 k2 (substType subst t1) (substType subst t2)
+substType _ l@(LitTy _) = l
+substType subst (CastTy ty co) =
+  CastTy (substType subst ty) co
+substType _ co@(CoercionTy _) = co
