Please help me get my wireguard tunnel setup using systemd-networkd

I have a functioning wireguard “server” that has multiple other “clients” already successfully connected to it using the wg-quick method. I’m trying to get my nixos-based “client” laptop setup with wireguard using systemd-networkd but have exhausted my own ability to troubleshoot. I feel like I’m close here but really need a hint on what I’m missing. Here are the relevant bits so far:

A module I’m calling “networking.nix” wired into configuration.nix, that successfully manages two ethernet and one wifi connection:

{ lib, config, pkgs, ... }: 

{

  services.resolved.enable = true; # use systemd-resolved for DNS functionality

  networking = {
    useDHCP = false; # disable defaut dhcpcd networking backend in favor of systemd-networkd enabled below
    hostName = "thinkpad";
    firewall = {
      enable = true;
      #allowedTCPPorts = [ 
      #  28764 # not needed as openssh server if active automatically opens its port(s)
      #];
      #allowedUDPPorts = [ 
        
      #];
    };
    wireless.iwd = { 
      enable = true;
      settings = {
        IPv6 = {
        Enabled = false;
        };
        Settings = {
          AutoConnect = true;
          AlwaysRandomizeAddress = false;
        };
      };
    };
  };

  systemd.services.systemd-networkd-wait-online.enable = lib.mkForce false; # for wait-online error - this works to fix the wait-online timeout error but need to find a more elegant solution
  systemd.network = {
    enable = true;
    #wait-online.anyInterface = true; # doesn't seem to fix the wait-online timeout error
    networks = {
      "10-ethernet" = {
        matchConfig.Name = "enp0s31f6";
        networkConfig.DHCP = "ipv4";
        dhcpV4Config.RouteMetric = 300;
        dhcpV6Config.RouteMetric = 300;
        linkConfig.RequiredForOnline = "no";
      };    
      "20-ethernet-dock" = {
        matchConfig.Name = "enp0s20f0u2u1u2";
        networkConfig.DHCP = "ipv4";
        dhcpV4Config.RouteMetric = 300;
        dhcpV6Config.RouteMetric = 300;
        linkConfig.RequiredForOnline = "no";
      };    
      "30-wifi" = {
        matchConfig.Name = "wlan0";
        networkConfig = {
          DHCP = "ipv4";
          IgnoreCarrierLoss = "3s"; # avoid re-configuring interface when wireless roaming between APs
        };
        dhcpV4Config.RouteMetric = 600;
        dhcpV6Config.RouteMetric = 600;
        linkConfig.RequiredForOnline = "no";
      };
    };
  };
}

Another module I’m calling “wireguard.nix” that also is wired into configuration.nix - I’m targeting the systemd-networkd wireguard configuration described on the arch wiki page for the " systemd-networkd: routing all traffic over WireGuard" section and can confirm this module successfully generates the required netdev and network files in /etc/systemd/network:

{ lib, config, pkgs, ... }: 

let
  wgFwMark = 4242;
  wgTable = 1000;
in

{

  sops = {
    secrets = {
      wg-key = {
        owner = "${config.users.users.systemd-network.name}";
        group = "${config.users.users.systemd-network.group}";
        mode = "0440";
      };
    };
  };

  systemd.network = {
    
    netdevs = {
      "99-wg0" = {
        netdevConfig = {
          Kind = "wireguard";
          Name = "wg0";
        };
        wireguardConfig = {
          PrivateKeyFile = "${config.sops.secrets.wg-key.path}";
          ListenPort = 9918;
          FirewallMark = wgFwMark;
        };
        wireguardPeers = [
          {
            wireguardPeerConfig = {
              PublicKey = "JH+yC7BcAp2G7l24/8KtwCI0pwLMdYw4e2r59TyrFnk="; # wireguard server pubkey
              AllowedIPs = [
                "0.0.0.0/0" 
              ];
              #Endpoint = "vpn.example.com:51820"; # SEE NOTE 1 AT BOTTOM OF POST
              #Endpoint = "ip-address:51820"; # SEE NOTE 2 AT BOTTOM OF POST
              PersistentKeepalive = 25;
            };
          }
        ];
      };
      
    };

    networks = {

      "99-wg0" = {
        matchConfig.Name = "wg0";
        networkConfig = {
          Address = "172.22.1.6/22";
          DNS = "192.168.1.2";
          DNSDefaultRoute = true; # make wireguard tunnel the default route for all DNS requests?
          Domains = "~."; # default DNS route for all domains?
        };
        routingPolicyRules = [
        {
          routingPolicyRuleConfig = {
            InvertRule = true;
            FirewallMark = wgFwMark;
            Table = wgTable;
            Priority = 10;
          };
        }
      ];
      routes = [
        {
          routeConfig = {
            Destination = "0.0.0.0/0";
            Table = wgTable;
          };
        }
      ];
        linkConfig = {
          ActivationPolicy = "manual"; # manually turn on/off wireguard tunnel with networkctl instead of automatically at boot
          RequiredForOnline = "no";
        };
      };    
    };
  
  };

}

When I bring the wireguard tunnel up with sudo networkctl up wg0 and follow the wireguard logs I see the following:

NOTE 1 with Domain - does not receive a handshake: wireguard: wg0: Handshake for peer 4 (192.168.1.251820) did not complete after 5 seconds, retrying (try 2).

NOTE 2 with IP address - does not receive a handshake: wireguard: wg0: Handshake for peer 4 (correct-IP address.251820) did not complete after 5 seconds, retrying (try 2).

I know this has something to do with DNS resolution but can’t figure it out on my own. It seems like when the endpoint address is set to the correct public domain name, it tries to connect to the internal IP address where the wireguard server lives on my network (this server incidentally also is running an unbound DNS server hence why I want to use it for DNS resolution in the wireguard tunnel), but can’t connect because the tunnel has not yet been established. When I just use the actual public IP of the server it tries to connect to that, but still doesn’t make a handshake with the server.