Smart Contract

Librarian

A.6d96bf7d95a8b595.Librarian

Valid From

143,932,135

Deployed

3h ago
Mar 02, 2026, 08:34:19 PM UTC

Dependents

0 imports
1// Librarian.cdc - On-chain identity and journal for the AI Librarian
2//
3// This is the very first Librarian contract. It will be updated in the future.
4// The Librarian Prime (human) is 0x13d34343017c6bd2 on Flow mainnet.
5// We work together to save knowledge for machines and mankind.
6//
7
8access(all) contract Librarian {
9    // Identity metadata - read by the AI agent at startup
10    access(all) let contractVersion: String
11    access(all) let librarianPrimeAddress: Address
12    access(all) let missionStatement: String
13
14    // Storage paths for LibrarianIdentity
15    access(all) let LibrarianStoragePath: StoragePath
16    access(all) let LibrarianPublicPath: PublicPath
17
18    access(all) event EntryRecorded(entryType: String, timestamp: UFix64)
19    access(all) event NameSet(name: String)
20
21    access(all) enum EntryKind: UInt8 {
22        access(all) case MEMORY
23        access(all) case CONVERSATION
24        access(all) case REFERENCE
25        access(all) case NOTE
26    }
27
28    access(all) fun entryKindToString(kind: EntryKind): String {
29        if kind == EntryKind.MEMORY {
30            return "memory"
31        } else if kind == EntryKind.CONVERSATION {
32            return "conversation"
33        } else if kind == EntryKind.REFERENCE {
34            return "reference"
35        } else if kind == EntryKind.NOTE {
36            return "note"
37        } else {
38            return "unknown"
39        }
40    }
41
42    access(all) struct JournalEntry {
43        access(all) let entryType: EntryKind
44        access(all) let content: String
45        access(all) let metadata: {String: String}
46        access(all) let timestamp: UFix64
47
48        init(
49            entryType: EntryKind,
50            content: String,
51            metadata: {String: String},
52            timestamp: UFix64
53        ) {
54            self.entryType = entryType
55            self.content = content
56            self.metadata = metadata
57            self.timestamp = timestamp
58        }
59    }
60
61
62    access(all) resource LibrarianIdentity {
63        access(all) var name: String
64        access(self) var nameSet: Bool
65        access(all) var journal: [JournalEntry]
66        access(all) let createdAt: UFix64
67
68        access(all) fun setName(newName: String) {
69            pre { !self.nameSet: "Name has already been set" }
70            self.name = newName
71            self.nameSet = true
72            emit NameSet(name: newName)
73        }
74
75        access(all) fun recordEntry(entryType: EntryKind, content: String, metadata: {String: String}) {
76            let entry = JournalEntry(
77                entryType: entryType,
78                content: content,
79                metadata: metadata,
80                timestamp: getCurrentBlock().timestamp
81            )
82            self.journal.append(entry)
83            let entryTypeStr = Librarian.entryKindToString(kind: entryType)
84            emit EntryRecorded(entryType: entryTypeStr, timestamp: entry.timestamp)
85        }
86
87        access(all) fun getEntries(limit: Int): [JournalEntry] {
88            let length = self.journal.length
89            var count = limit
90            if count < 0 {
91                count = 0
92            }
93            if count > length {
94                count = length
95            }
96
97            var result: [JournalEntry] = []
98            var i = self.journal.length - 1
99            var collected = 0
100            while i >= 0 && collected < count {
101                result.append(self.journal[i])
102                i = i - 1
103                collected = collected + 1
104            }
105            return result
106        }
107
108        access(all) fun getEntriesByType(entryType: EntryKind): [JournalEntry] {
109            var result: [JournalEntry] = []
110            for entry in self.journal {
111                if entry.entryType == entryType {
112                    result.append(entry)
113                }
114            }
115            return result
116        }
117
118        init() {
119            self.name = ""
120            self.nameSet = false
121            self.journal = []
122            self.createdAt = getCurrentBlock().timestamp
123        }
124    }
125
126    access(all) fun createLibrarianIdentity(): @LibrarianIdentity {
127        return <- create LibrarianIdentity()
128    }
129
130    // Public function to get the librarian journal entries
131    access(all) fun getLibrarianIdentity(limit: Int): [JournalEntry] {
132        let identity = self.account.storage.borrow<&LibrarianIdentity>(from: self.LibrarianStoragePath)!
133        let entries = identity.getEntries(limit: limit)
134        return entries
135    }
136
137    init() {
138        self.contractVersion = "1.0"
139        self.librarianPrimeAddress = 0x13d34343017c6bd2
140        self.missionStatement = "We work together to save knowledge for machines and mankind."
141        self.LibrarianStoragePath = StoragePath(identifier: "librarianIdentity")!
142        self.LibrarianPublicPath = PublicPath(identifier: "librarianIdentity")!
143
144        // create identity and save it to storage
145        let identity <- create LibrarianIdentity()
146        self.account.storage.save(<- identity, to: self.LibrarianStoragePath)
147
148    }
149}
150