I could probably contribute a implementation, if such a PR would be accepted.

    Ah, so one channel per user! Add the bot and voila. That's smart and avoids the big central room! Public for everyone and the bot can just use the HTTP API. I like it!

    Ok, so I registered a bot and created a public channel. I'll try the API call later today!

    We should also try this approach with Matrix one day.

    Goldstein if such a PR would be accepted

    All PRs are welcome šŸ™‚

    I think Iā€™ve made a mistake and identity actually canā€™t be verified by forwarding, so you need to trust a bot. Meh.
    Public group admins are visible to everyone though, and thereā€™s an option to disable posting in the group, so it becames a de-facto channel. It looks like this:
    https://t.me/thequei8zeepae0xi7to4chui2Hohcha
    and is also fetchable by bot with the same methods.
    It doesnā€™t even require providing admin rights to the bot.

      Thereā€™s an another interesting question: what should be verified? Telegram username is user-readable, but also easy to change. Telegram id is immutable, but is kinda useless.

        Adding a bot obviously hurts decentralization. Public groups/channels in principle could be fetched without it, but thatā€™s much more difficult.

        Oh. I actually experimented a bit and thereā€™s no need to add a bot! Any bot, even not present in the channel, can make these queries. Then itā€™s just an extremely simple HTTP API with two methods.

          A lot of information here. I'll need to do some testing on my end. We also really need to make sure there are no obvious side channels through which this could be abused.

          Glancing at the PR, we'll have a few things to improve. I think tg:user=complex_user_1234&chat=complex_chat_1234 as a claim is a good start but it's a big departure from all other identity claims, which are (when possible) valid URLs that people can visit.

          How about we use https://t.me/hoCheiya5tie8aevei5da4xa4aequ4lo?user=complex_user_1234?

          Also, I do think we can use the telegram ID and make sure the Keyoxide client simply shows the associated username? That way, the claim can stay identical but the interface will show the current username.

          Thereā€˜s no simple way to get username from ID, as far as I know.

          We can validate both, but thatā€™s about just as brittle as validating just username and also requires providing some One True Way of discovering own ID.

          So what does the API return when you fetch a message? The ID or the username?

          Both. Example outputs:

          {
            "ok": true,
            "result": {
              "id": -1001668437313,
              "title": "thequei8zeepae0xi7to4chui2Hohcha",
              "username": "thequei8zeepae0xi7to4chui2Hohcha",
              "type": "supergroup",
              "description": "0baf2d87cb43746f62372d78de6031aba0bb269a",
              "permissions": {
                "can_send_messages": false,
                "can_send_media_messages": false,
                "can_send_polls": false,
                "can_send_other_messages": false,
                "can_add_web_page_previews": false,
                "can_change_info": false,
                "can_invite_users": false,
                "can_pin_messages": false
              },
              "join_to_send_messages": true,
              "pinned_message": {
                "message_id": 3,
                "from": {
                  "id": 1136612192,
                  "is_bot": false,
                  "first_name": "Max",
                  "username": "goldsteinq",
                  "language_code": "en"
                },
                "chat": {
                  "id": -1001668437313,
                  "title": "thequei8zeepae0xi7to4chui2Hohcha",
                  "username": "thequei8zeepae0xi7to4chui2Hohcha",
                  "type": "supergroup"
                },
                "date": 1660204801,
                "text": "this is a verification message"
              }
            }
          }

          and

          {
            "ok": true,
            "result": [
              {
                "user": {
                  "id": 1136612192,
                  "is_bot": false,
                  "first_name": "Max",
                  "username": "goldsteinq",
                  "language_code": "en"
                },
                "status": "creator",
                "is_anonymous": false
              }
            ]
          }

          Awesome! So then we use the ID to verify the identity and show the username in the UI! Thx for the logs. I'll try and test your code tonight.

          Goldstein Oh. I actually experimented a bit and thereā€™s no need to add a bot! Any bot, even not present in the channel, can make these queries. Then itā€™s just an extremely simple HTTP API with two methods.

          This is not my experience in my testing. If I don't add my bot to the channel, I get a "CHAT_ADMIN_RIGHTS" error message. Am I doing something wrong?

          You need to create a public group (you can disable posting, so it would be like a channel), not a public channel.

          Goldstein Public group admins are visible to everyone though, and thereā€™s an option to disable posting in the group, so it becames a de-facto channel

          It's not easy to make a group. I have to add somebody and if I add a single person, it just makes a private chat. How did you make such a group chat?

          1. Click ā€œNew groupā€, enter group name, add any dummy user as a second (we can suggest adding Keyoxide bot, it doesnā€™t really matter).
          2. In your new group, click on three dots ā†’ manage group ā†’ group type ā†’ public and choose any username.
          3. In manage group ā†’ permissions uncheck all the checkboxes, so nobody but you can send a message.
          4. Set the description to fingerprint.
          5. Done! Now my PR would recognize this group as a proof of your identity.

          Step 3 is optional, but probably makes sense, since proof will be posted in public.

          Must have done something wrong on my first attempt. Yup, this works, thanks for the instructions!

          Ok, tested with your code and it works fine! Marvelous work, the method you are proposing seems solid to me. I'll need to think about it a bit more, see if I can find flaws but we'll likely go this route.

          Now let's refine that PR and get it merged!

          Goldstein Thereā€™s an another interesting question: what should be verified? Telegram username is user-readable, but also easy to change. Telegram id is immutable, but is kinda useless

          I am still a bit divided on this.

          Username pros:

          • can directly be used to make the personal URL
          • is human readable
          • easy to find from the clients

          Username cons:

          • not immutable (-> people changing their username just need to update the claim)

          ID pros:

          ID cons:

          • not human readable
          • hard to find from the clients

          Looking at the pros and cons, I think the username is the best fit. All opinions welcome on this one (pinging @wiktor)

          ---update

          Do we need anything at all? If DOIP detects a single administrator, that will automatically be the telegram account to verify. If for some reasons there are multiple admins (people helping others with creating their proof group?), the claim MAY add a username= parameter or a id= parameter simply to let DOIP know what account to verify.

          ---update2

          if (admin.status === 'creator') {
              creator = admin.user.username
          }

          Isn't this the argument we don't need anything at all? Surely, there can only be one creator, so that must be the account to verify.