diff --git a/Sources/XXClient/Models/Contact.swift b/Sources/XXClient/Models/Contact.swift
index 03e08f2a517d98571ee0ad9efc497c9ce930460d..6bc9b769841482eadf0f7544869769361254c860 100644
--- a/Sources/XXClient/Models/Contact.swift
+++ b/Sources/XXClient/Models/Contact.swift
@@ -44,6 +44,18 @@ extension Contact: Equatable {
   }
 }
 
+extension Contact {
+  public func getFact(_ type: FactType) throws -> Fact? {
+    try getFacts().get(type)
+  }
+
+  public mutating func setFact(_ type: FactType, _ value: String?) throws {
+    var facts = try getFacts()
+    facts.set(type, value)
+    try setFacts(facts)
+  }
+}
+
 extension Contact {
   public static func live(
     _ data: Data,
diff --git a/Tests/XXClientTests/Models/ContactTests.swift b/Tests/XXClientTests/Models/ContactTests.swift
new file mode 100644
index 0000000000000000000000000000000000000000..8347e0dc6ac997147e11171ceb77869f45f1cb8e
--- /dev/null
+++ b/Tests/XXClientTests/Models/ContactTests.swift
@@ -0,0 +1,61 @@
+import CustomDump
+import XCTest
+@testable import XXClient
+
+final class ContactTests: XCTestCase {
+  func testGetFact() throws {
+    var contact = Contact.unimplemented("contact-data".data(using: .utf8)!)
+    contact.getFactsFromContact.run = { _ in
+      [
+        Fact(fact: "username", type: 0),
+        Fact(fact: "email", type: 1),
+        Fact(fact: "phone", type: 2),
+        Fact(fact: "other", type: 3),
+      ]
+    }
+
+    XCTAssertNoDifference(
+      [
+        try contact.getFact(.username),
+        try contact.getFact(.email),
+        try contact.getFact(.phone),
+        try contact.getFact(.other(3)),
+        try contact.getFact(.other(4)),
+      ],
+      [
+        Fact(fact: "username", type: 0),
+        Fact(fact: "email", type: 1),
+        Fact(fact: "phone", type: 2),
+        Fact(fact: "other", type: 3),
+        nil
+      ]
+    )
+  }
+
+  func testSetFact() throws {
+    var contact = Contact.unimplemented("contact-data".data(using: .utf8)!)
+    var facts: [Fact] = [
+      Fact(fact: "username", type: 0),
+      Fact(fact: "email", type: 1),
+      Fact(fact: "phone", type: 2),
+      Fact(fact: "other-3", type: 3),
+    ]
+    contact.getFactsFromContact.run = { _ in facts }
+    contact.setFactsOnContact.run = { data, newFacts in
+      facts = newFacts
+      return data
+    }
+
+    try contact.setFact(.username, "new-username")
+    try contact.setFact(.other(4), "new-other-4")
+    try contact.setFact(.other(3), "new-other-3")
+    try contact.setFact(.email, nil)
+
+    XCTAssertNoDifference(facts, [
+      Fact(fact: "new-username", type: 0),
+      Fact(fact: "phone", type: 2),
+      Fact(fact: "new-other-3", type: 3),
+      Fact(fact: "new-other-4", type: 4),
+    ])
+  }
+}