LogoLogo
  • 🚀DeSo Vision
  • 🪙DeSo Tokenomics
    • No Equity, Just Coins and Code
    • Current DESO Supply
    • Initial DESO Distribution
    • DESO Sinks
    • The BMF: Burn-Maximizing Fee Mechanism
    • Designed for the End-Game
  • 🏛️DeSo Governance
  • ⭐DeSo Tutorial (Build Apps)
  • 🖥️Node Architecture Overview
    • Setup a Node & Frontend Locally
    • Making Your First Changes
  • 📅DeSo Roadmap
  • 🔍DeSo Block Explorer
  • 💸DeSo Wallet
  • 💬DeSo Chat Protocol
  • 👽Openfund
  • 👀Focus
  • 🛠️DeSo Tech Stack
  • 🌐DeSo Applications
  • DeSo Blockchain
    • 1️⃣Bare Metal
    • 2️⃣Scaling Roadmap
    • 3️⃣Content Moderation
    • 4️⃣Infinite-State
    • 5️⃣On-Chain Data
    • 6️⃣Smart Services
    • 7️⃣User Security
  • DeSo Features
    • 1️⃣Associations
    • 2️⃣Creator Coins
    • 3️⃣Feeds & Moderation
    • 4️⃣Social NFTs
    • 5️⃣Social Tipping
  • DeSo Identity
    • 1️⃣Identity: Overview
      • Core Concepts
      • Mobile Integration
    • 2️⃣Identity: iFrame API
      • Overview
      • Endpoints
    • 3️⃣Identity: Window API
      • Overview
      • Endpoints
  • DESO FRONTEND
    • 1️⃣Frontend: Get Started
    • 2️⃣Frontend: React Example
  • DESO BACKEND
    • 1️⃣Backend: Config
      • Onboarding
      • Phone Number Verification
      • Global State
      • Admins
      • Web Security
      • Media
        • Images
        • Videos
      • Hot Feed
      • Selling $DESO
        • Wyre - Buy with USD
        • Buy with BTC
        • Buy with ETH
      • Analytics
      • Emails
      • Supply Monitoring
    • 2️⃣Construct: API
      • Social Transactions API
      • NFT Transactions API
      • Financial Transactions API
      • Derived Keys Transaction API
      • DeSo Tokens Transactions API
      • Associations Transactions API
      • Access Groups API
    • 3️⃣Data: API
      • Admin Endpoints
      • Associations Endpoints
      • DeSo Tokens Endpoints
      • Media Endpoints
      • Miner Endpoints
      • Notification Endpoints
      • NFT Endpoints
      • Social Endpoints
      • Referral Endpoints
      • Tutorial Endpoints
      • Meta Data Endpoints
      • Transaction Spending Limits Endpoints
      • User Endpoints
      • Post Endpoints
      • Messages Endpoints
      • Access Group Endpoints
    • 4️⃣Transactions: API
  • DeSo Exchange Listings
    • 1️⃣Exchange Listing: API
  • DeSo Nodes
    • 2️⃣Node: Setup
    • 3️⃣Node: Staying Up-To-Date
    • 4️⃣Node: FAQ
  • DESO VALIDATORS
    • 1️⃣Run a Validator
  • Openfund
    • What is Openfund?
    • Openfund Tokenomics
    • Openfund Governance
    • Algorithmic Trading
      • The DeSo Python SDK
    • The DeSo Python SDK
      • Getting Help from the Community
      • Creating DeSo Testnet Accounts
      • Debugging Tips and Code Walkthrough
      • Write Blockchain Bots with AI
      • Market-Making Bots
      • Social AI Agents
      • AI-Generating Your Code
    • How Do the Advanced AMMs Work?
  • Focus
    • The Crypto Social Network
    • Next-Generation Token Mechanics
      • Launching Your Token
      • How the Order-Book AMMs Work
    • Crypto-Native Monetization
    • Focus Tokenomics
    • The Social Airdrop
    • Decentralizing Social Media
  • Contact And Media
    • ☀️DeSo Website
    • 📑DeSo Blog
    • 💻DeSo Github
    • 💎DeSo Diamond
    • 🐦DeSo Twitter
    • 📺DeSo YouTube
    • 📬Contact US
    • ⚠️Reporting an Account or Post
  • 中文
    • 什么是DeSo? (What is DeSo?)
    • 愿景 (The Vision)
Powered by GitBook
On this page
  • sign
  • encrypt
  • decrypt
  • jwt

Was this helpful?

  1. DeSo Identity
  2. Identity: iFrame API

Endpoints

List of DeSo Identity iframe API endpoints

PreviousOverviewNextIdentity: Window API

Last updated 2 years ago

Was this helpful?

Note:

The iframe API supports functionality for both public keys and derived keys. You can determine key type from the login response by checking for derivedPublicKeyBase58Check.

sign

AccessLevel: 3, 4 (depends on )

The sign message is responsible for signing transaction hexes. If approval is required an application must call the endpoint in the Window API to sign the transaction.

Payload for public keys

Name
Type
Description

transactionHex

string

Hex of the transaction you want to sign.

Payload for derived keys

Name
Type
Description

transactionHex

string

Hex of the transaction you want to sign.

derivedPublicKeyBase58Check

string

Only required if logged in user is using a derived key to sign on behalf of an owner public key.

Request

{
  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  method: 'sign',
  payload: {
    accessLevel: 4,
    accessLevelHmac: "0fab13f4...",
    encryptedSeedHex: "0fab13f4...",
    transactionHex: "0fab13f4...",
    derivedPublicKeyBase58Check: "0fab13f4...",

  },
}

Response (Success)

You will get this response if the transaction was successful signed.

{
  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  payload: {
    signedTransactionHex: "0fab13f4...",
  },
}

Response (Approval Required)

You will get this response if the accessLevel your user has authorized doesn't match the access level required to sign a transaction.

{
  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  payload: {
    approvalRequired: true,
  },
}

encrypt

AccessLevel: 2

Payload for public keys

Name
Type
Description

recipientPublicKey

string

Public key of the recipient in base58check format.

message

string

Message text that you want to encrypt.

Payload for derived keys

Only required if logged in user is using a derived key to sign on behalf of an owner public key.

recipientPublicKey

string

Public key of the recipient in base58check format.

message

string

Message text that you want to encrypt.

encryptedMessagingKeyRandomness

string

This value is used in place of the encryptedSeedHex when encrypting the message.

derivedPublicKeyBase58Check

string

Public key requesting encryption in base58check format.

ownerPublicKeyBase58Check

string

Public key used only for validation.

Request

{
  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  method: 'encrypt',
  payload: {
    accessLevel: 3,
    accessLevelHmac: "0fab13f4...",
    encryptedSeedHex: "0fab13f4...",
    recipientPublicKey: "BC1YLgwkd7iADbrSgryTfXhMEcsF76cXDaWog4aDzoTunDb2DcZ3myZ"
    message: "This is a message",
    derivedPublicKeyBase58Check: "BC1YLsond7iADbrSgryTfXhMEcsF76cXDaWog4aDzoTunDb2DcZ3myZ",
    ownerPublicKeyBase58Check: "BC1YLdadd7iADbrSgryTfXhMEcsF76cXDaWog4aDzoTunDb2DcZ3myZ",
    encryptedMessagingKeyRandomness: "837fab39...",
    
  },
}

Response for Derived keys (Encrypted Messaging Key Randomness Required)

You will get this response if the request includes a derivedPublicKeyBase58Check and does not include both ownerPublicKeyBase58Check and encryptedMessagingKeyRandomness.

  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  payload: {
    encryptedMessage: "",
    requiresEncryptedMessagingKeyRandomness: true,
  },
}

You can request Encrypted MessagingKeyRandomness by calling the messaging-group in the Window API.

Response (Approval Required)

You will get this response if the accessLevel your user has authorized doesn't match the access level required to sign a transaction.

To fix, the user needs to allow at least access level 2.

{
  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  payload: {
    approvalRequired: true,
  },
}

Response

{
  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  payload: {
    encryptedMessage: "0fab13f4...",
  },
}

decrypt

AccessLevel: 2

The decrypt API is responsible for decrypting messages.

The decrypt API allows you to decrypt multiple messages at once by passing an array of encryptedMessage objects.

The decrypt API is intended to be constructed right after calling the /api/v0/get-messages-stateless backend API endpoint, and so the structure of encryptedMessage matches the structure of the response from backend.

Assuming message is a taken from OrderedContactsWithMessages.Messages from the backend API response, encryptedMessage can be constructed as follows:

encryptedMessage : {
    EncryptedHex: message.EncryptedText,
    PublicKey: message.IsSender ? message.RecipientPublicKeyBase58Check : message.SenderPublicKeyBase58Check,
    IsSender: message.IsSender,
    Legacy: !message.V2,
}

Another use-case for the decrypt API is decrypting unlock-able text in NFTs.

Payload for public keys

Name
Type
Description

encryptedMessages

[]encryptedMessage

List of encrypted messages objects.

Payload for derived keys

derivedPublicKeyBase58Check

string

Public key requesting decryption in base58check format.

ownerPublicKeyBase58Check

string

Used to identify which messaging group member entry is used to decrypt group messages.

encryptedMessagingKeyRandomness

string

Required to decrypt the request.

encryptedMessages

[]encryptedMessage

List of encrypted messages objects.

Request

{
  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  method: 'decrypt',
  payload: {
    accessLevel: 3,
    accessLevelHmac: "0fab13f4...",
    encryptedSeedHex: "0fab13f4...",
    derivedPublicKeyBase58Check: "BC1YLsond7iADbrSgryTfXhMEcsF76cXDaWog4aDzoTunDb2DcZ3myZ",
    ownerPublicKeyBase58Check: "BC1YLdadd7iADbrSgryTfXhMEcsF76cXDaWog4aDzoTunDb2DcZ3myZ",
    encryptedMessagingKeyRandomness: "837fab39...",
    encryptedMessage: [
      {
        EncryptedHex: "0f154bcad...",
        PublicKey: "BC1a4gbK1...",
        IsSender: true,
        Legacy: false
      },
      {
        EncryptedHex: "0afa44bcd...",
        PublicKey: "BC1asKl5j1...",
        IsSender: false,
        Legacy: true
      }, ...
    ]
  },
}

Response (Encrypted Messaging Key Randomness Required)

You will get this response if the request includes a derivedPublicKeyBase58Check and does not include both ownerPublicKeyBase58Check and encryptedMessagingKeyRandomness.

{
  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  payload: {
    decryptedHexes: {}
    requiresEncryptedMessagingKeyRandomness: true,
  },
}

Response (Approval Required)

You will get this response if the accessLevel your user has authorized doesn't match the access level required to sign a transaction.

To fix, the user needs to allow at least access level 2.

{
  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  payload: {
    approvalRequired: true,
  },
}

Response

Response contains a decryptedHexes field which is a map of decrypted messages, indexed by EncryptedHex from the request.

{
  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  payload: {
    decryptedHexes: {
      "0f154bcad...": "hello world"
      "0afa44bcd...": "in retrospect it was inevitable",
    }
  },
}

jwt

AccessLevel: 2

The jwt message creates signed JWT tokens that can be used to verify a user's ownership of a specific public key.

The JWT is only valid for 10 minutes.

JWTs are used in some Backend API endpoints such as /api/v0/upload-image. The best practice is to request the JWT right before calling these endpoints.

Payload for public keys

Name
Type
Description

N/A

N/A

No payload.

payload for derived keys

Name
Type
Description

derivedPublicKeyBase58Check

string

Informs Identity on how to sign the transaction.

Request

{
  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  method: 'jwt',
  payload: {
    accessLevel: 3,
    accessLevelHmac: "0fab13f4...",
    encryptedSeedHex: "0fab13f4...",
    derivedPublicKeyBase58Check: "BC1YLsond7iADbrSgryTfXhMEcsF76cXDaWog4aDzoTunDb2DcZ3myZ",
  },
}

Response

{
  id: '21e02080-0ef4-4056-a319-a66403f33768',
  service: 'identity',
  payload: {
    jwt: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2MTk2NDk4MDcsImV4cCI6MTYxOTY0OTg2N30.FKZF8DSwwlnUaW_eRa7Wr1v2QcG7_iDN-NjdqXUcgrSAPg1EdSfpWsLL4GeUiD9zdLUgrNoKU7EsKkE-ZKMaVQ",
  },
}

Validation in Go

In case you want to validate the JWT token in Go, you could use the code below:

func (fes *APIServer) ValidateJWT(publicKey string, jwtToken string) (bool, error) {
	pubKeyBytes, _, err := lib.Base58CheckDecode(publicKey)
	if err != nil {
		return false, errors.Wrapf(err, "Problem decoding public key")
	}

	pubKey, err := btcec.ParsePubKey(pubKeyBytes, btcec.S256())
	if err != nil {
		return false, errors.Wrapf(err, "Problem parsing public key")
	}

	token, err := jwt.Parse(jwtToken, func(token *jwt.Token) (interface{}, error) {
		// Do not check token issued at time. We still check expiration time.
		mapClaims := token.Claims.(jwt.MapClaims)
		delete(mapClaims, "iat")

		// We accept JWT signed by derived keys. To accommodate this, the JWT claims payload should contain the key
		// "derivedPublicKeyBase58Check" with the derived public key in base58 as value.
		if derivedPublicKeyBase58Check, isDerived := mapClaims[JwtDerivedPublicKeyClaim]; isDerived {
			// Parse the derived public key.
			derivedPublicKeyBytes, _, err := lib.Base58CheckDecode(derivedPublicKeyBase58Check.(string))
			if err != nil {
				return nil, errors.Wrapf(err, "Problem decoding derived public key")
			}
			derivedPublicKey, err := btcec.ParsePubKey(derivedPublicKeyBytes, btcec.S256())
			if err != nil {
				return nil, errors.Wrapf(err, "Problem parsing derived public key bytes")
			}
			// Validate the derived public key.
			utxoView, err := fes.mempool.GetAugmentedUniversalView()
			if err != nil {
				return nil, errors.Wrapf(err, "Problem getting utxoView")
			}
			blockHeight := uint64(fes.blockchain.BlockTip().Height)
			if err := utxoView.ValidateDerivedKey(pubKeyBytes, derivedPublicKeyBytes, blockHeight); err != nil {
				return nil, errors.Wrapf(err, "Derived key is not authorize")
			}

			return derivedPublicKey.ToECDSA(), nil
		}

		return pubKey.ToECDSA(), nil
	})

	if err != nil {
		return false, errors.Wrapf(err, "Problem verifying JWT token")
	}

	return token.Valid, nil
}

The encrypt API is responsible for encrypting messages. For more details check out

As we mentioned in the section, the current messaging protocol is V2; however, it is still possible to decrypt messages from the V1 scheme.

We recommend tracing through function in the DeSo Protocol frontend's src/app/backend-api.service.ts.

To see how this can be done, we recommend tracing through the in the DeSo Protocol repository.

2️⃣
GetMessages()
DecryptUnlockableTexts()
transaction
#approve
Messages
Messages