📄 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}