📄 Identity.sol
D-OPEN SOVEREIGN
1/*
2 * Copyright (c) 2026 DataPond D-Library Pty Ltd. ("The Sanctuary")
3 * Non-Profit Public Library — The World Library
4 *
5 * D-SAFE Certification issued by POND Enterprise.
6 * Published under the D-Open Code Sovereign Licence v1.0 framework
7 * DataPond D-Library All exclusive Right reserved on modifiying the code - CC Attribution to data pond, Non modifiable, Non Commercial.
8 * https://registry.world.bibliotech.com/licence
9 * Source code donated to DataPond D-Library by it's author: data pond.
10 *
11 * Technical Guardian ("The Shield"): Pond Enterprise Pty Ltd. (ACN 694 747 987)
12 * All liability claims about D-SAFE certification issues coming from the published D-Safe direction must be addressed with Pond Enterprise Pty Ltd.
13 * Code Modification automatically voids the certified liability protection provided by Pond Enterprise.
14 */
15
16// SPDX-License-Identifier: Apache-2.0
17pragma solidity ^0.8.24;
18
19import "./DateUtils.sol";
20import {ErrorLibrary} from "./ErrorLibrary.sol";
21
22contract Identity {
23
24 string[255] private adjectives;
25 uint8 private nbAdjectives = 0;
26 string[255] private verbs;
27 uint8 private nbVerbs = 0;
28
29 mapping(string => address) public usernames;
30 mapping(address => string) public usernamesInverted;
31 address private __owner;
32
33 constructor() {
34 __owner = msg.sender;
35 }
36
37 function identityStats() public view returns (uint8 _nbVerbs, uint8 _nbAdjectives) {
38 return (nbVerbs, nbAdjectives);
39 }
40
41 function _generateUsername(uint32 userId) internal view returns (string memory) {
42 uint256 _nbAdjectives = nbAdjectives;
43 uint256 _nbVerbs = nbVerbs;
44
45 if (_nbVerbs == 0 || _nbAdjectives == 0) {
46 revert ErrorLibrary.noDefinitionErr();
47 }
48
49 // Use (userId - 1) to ensure the first user (ID 1) gets Index 0, 0
50 uint256 normalizedId = userId - 1;
51
52 uint256 verbIndex = normalizedId % _nbVerbs;
53 uint256 adjIndex = (normalizedId / _nbVerbs) % _nbAdjectives;
54 uint256 rollover = normalizedId / (_nbAdjectives * _nbVerbs);
55
56 return string.concat(
57 adjectives[adjIndex],
58 "-",
59 verbs[verbIndex],
60 "-",
61 DateUtils.getYearMonthString(),
62 "-",
63 DateUtils.uintToString(rollover)
64 );
65 }
66
67 function defineCombinations(string[] calldata _adjectives, string[] calldata _verbs) public virtual {
68 if (__owner != msg.sender) {
69 revert ErrorLibrary.IdentityUnauthorizedAccount(msg.sender);
70 }
71
72 uint16 al = uint16(_adjectives.length);
73 uint16 vl = uint16(_verbs.length);
74
75 if (al > 255 - nbAdjectives) {
76 revert ErrorLibrary.TooManyAdjectiveDefined();
77 }
78 if (vl > 255 - nbVerbs) {
79 revert ErrorLibrary.TooManyVerbsDefined();
80 }
81 for (uint16 i = 0; i < al; i++) {
82 adjectives[nbAdjectives] = _adjectives[i];
83 nbAdjectives++;
84 }
85 for (uint16 i = 0; i < vl; i++) {
86 verbs[nbVerbs] = _verbs[i];
87 nbVerbs++;
88 }
89 }
90
91 function usernameExists(string calldata username) public view returns (bool ok) {
92 return usernames[username] != address(0);
93 }
94
95 function getAddressByUsername(string calldata username) public view returns (address addr) {
96 //username deosn't exist
97 if (usernames[username] == address(0)) {
98 revert ErrorLibrary.UsernameNotDefined();
99 }
100 return usernames[username];
101 }
102
103 function getUsernameByAddress(address addr) public virtual view returns (string memory username) {
104 return usernamesInverted[addr];
105 }
106
107 function linkUsernameToAddress(address addr, string memory username) internal {
108 // username already taken by an address
109 if (usernames[username] != address(0)) {
110 revert ErrorLibrary.UserNameAlreadyTaken();
111 }
112 usernames[username] = addr;
113 usernamesInverted[addr] = username;
114 }
115
116
117}