diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 5eedaaf35..351446eb0 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -739,9 +739,12 @@ add_library(core STATIC
     hle/service/nim/nim.h
     hle/service/npns/npns.cpp
     hle/service/npns/npns.h
+    hle/service/ns/account_proxy_interface.cpp
+    hle/service/ns/account_proxy_interface.h
     hle/service/ns/language.cpp
     hle/service/ns/language.h
     hle/service/ns/ns_results.h
+    hle/service/ns/ns_types.h
     hle/service/ns/ns.cpp
     hle/service/ns/ns.h
     hle/service/ns/pdm_qry.cpp
diff --git a/src/core/hle/service/ns/account_proxy_interface.cpp b/src/core/hle/service/ns/account_proxy_interface.cpp
new file mode 100644
index 000000000..e5041af66
--- /dev/null
+++ b/src/core/hle/service/ns/account_proxy_interface.cpp
@@ -0,0 +1,21 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/ns/account_proxy_interface.h"
+
+namespace Service::NS {
+
+IAccountProxyInterface::IAccountProxyInterface(Core::System& system_)
+    : ServiceFramework{system_, "IAccountProxyInterface"} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, nullptr, "CreateUserAccount"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IAccountProxyInterface::~IAccountProxyInterface() = default;
+
+} // namespace Service::NS
diff --git a/src/core/hle/service/ns/account_proxy_interface.h b/src/core/hle/service/ns/account_proxy_interface.h
new file mode 100644
index 000000000..e944d2a75
--- /dev/null
+++ b/src/core/hle/service/ns/account_proxy_interface.h
@@ -0,0 +1,16 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::NS {
+
+class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
+public:
+    explicit IAccountProxyInterface(Core::System& system_);
+    ~IAccountProxyInterface() override;
+};
+
+} // namespace Service::NS
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index 84961fc0c..b586fbcf0 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -11,6 +11,7 @@
 #include "core/hle/service/filesystem/filesystem.h"
 #include "core/hle/service/glue/glue_manager.h"
 #include "core/hle/service/ipc_helpers.h"
+#include "core/hle/service/ns/account_proxy_interface.h"
 #include "core/hle/service/ns/language.h"
 #include "core/hle/service/ns/ns.h"
 #include "core/hle/service/ns/ns_results.h"
@@ -21,19 +22,6 @@
 
 namespace Service::NS {
 
-IAccountProxyInterface::IAccountProxyInterface(Core::System& system_)
-    : ServiceFramework{system_, "IAccountProxyInterface"} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, nullptr, "CreateUserAccount"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-IAccountProxyInterface::~IAccountProxyInterface() = default;
-
 IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_)
     : ServiceFramework{system_, "IApplicationManagerInterface"} {
     // clang-format off
diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h
index 9ee306ef9..cd2fbc8f4 100644
--- a/src/core/hle/service/ns/ns.h
+++ b/src/core/hle/service/ns/ns.h
@@ -17,12 +17,6 @@ class FileSystemController;
 
 namespace NS {
 
-class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
-public:
-    explicit IAccountProxyInterface(Core::System& system_);
-    ~IAccountProxyInterface() override;
-};
-
 class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
 public:
     explicit IApplicationManagerInterface(Core::System& system_);
diff --git a/src/core/hle/service/ns/ns_types.h b/src/core/hle/service/ns/ns_types.h
new file mode 100644
index 000000000..1b97ac816
--- /dev/null
+++ b/src/core/hle/service/ns/ns_types.h
@@ -0,0 +1,62 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "common/common_funcs.h"
+
+namespace Service::NS {
+
+enum class ApplicationRecordType : u8 {
+    Installing = 2,
+    Installed = 3,
+    GameCardNotInserted = 5,
+    Archived = 0xB,
+    GameCard = 0x10,
+};
+
+struct ApplicationRecord {
+    u64 application_id;
+    ApplicationRecordType type;
+    u8 unknown;
+    INSERT_PADDING_BYTES_NOINIT(0x6);
+    u8 unknown2;
+    INSERT_PADDING_BYTES_NOINIT(0x7);
+};
+static_assert(sizeof(ApplicationRecord) == 0x18, "ApplicationRecord is an invalid size");
+
+/// ApplicationView
+struct ApplicationView {
+    u64 application_id; ///< ApplicationId.
+    u32 unk;            ///< Unknown.
+    u32 flags;          ///< Flags.
+    u8 unk_x10[0x10];   ///< Unknown.
+    u32 unk_x20;        ///< Unknown.
+    u16 unk_x24;        ///< Unknown.
+    u8 unk_x26[0x2];    ///< Unknown.
+    u8 unk_x28[0x8];    ///< Unknown.
+    u8 unk_x30[0x10];   ///< Unknown.
+    u32 unk_x40;        ///< Unknown.
+    u8 unk_x44;         ///< Unknown.
+    u8 unk_x45[0xb];    ///< Unknown.
+};
+
+/// NsPromotionInfo
+struct PromotionInfo {
+    u64 start_timestamp; ///< POSIX timestamp for the promotion start.
+    u64 end_timestamp;   ///< POSIX timestamp for the promotion end.
+    s64 remaining_time;  ///< Remaining time until the promotion ends, in nanoseconds
+                         ///< ({end_timestamp - current_time} converted to nanoseconds).
+    INSERT_PADDING_BYTES_NOINIT(0x4);
+    u8 flags; ///< Flags. Bit0: whether the PromotionInfo is valid (including bit1). Bit1 clear:
+              ///< remaining_time is set.
+    INSERT_PADDING_BYTES_NOINIT(0x3);
+};
+
+/// NsApplicationViewWithPromotionInfo
+struct ApplicationViewWithPromotionInfo {
+    ApplicationView view;    ///< \ref NsApplicationView
+    PromotionInfo promotion; ///< \ref NsPromotionInfo
+};
+
+} // namespace Service::NS