TESTNET|Data may be reset

Yappr Data Contract

Dash Platform data contract for the Yappr social media platform

Version: 7
Documents: 15
Indices: 30

Contract Definition

{
  "version": 7,
  "documents": {
    "like": {
      "type": "object",
      "indices": [
        {
          "name": "postAndOwner",
          "unique": true,
          "properties": [
            {
              "postId": "asc"
            },
            {
              "$ownerId": "asc"
            }
          ]
        },
        {
          "name": "postOwnerLikes",
          "properties": [
            {
              "postOwnerId": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        }
      ],
      "mutable": false,
      "required": [
        "$createdAt",
        "postId"
      ],
      "properties": {
        "postId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 0,
          "byteArray": true,
          "description": "ID of the liked post or reply",
          "contentMediaType": "application/x.dash.dpp.identifier"
        },
        "postOwnerId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 1,
          "byteArray": true,
          "description": "Identity ID of the post owner (for efficient notification queries)",
          "contentMediaType": "application/x.dash.dpp.identifier"
        }
      },
      "description": "A like on a post or reply",
      "additionalProperties": false
    },
    "post": {
      "type": "object",
      "indices": [
        {
          "name": "ownerAndTime",
          "properties": [
            {
              "$ownerId": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        },
        {
          "name": "languageTimeline",
          "properties": [
            {
              "language": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        },
        {
          "name": "quotedPostAndOwner",
          "unique": true,
          "properties": [
            {
              "quotedPostId": "asc"
            },
            {
              "$ownerId": "asc"
            }
          ]
        },
        {
          "name": "quotedPostOwnerAndTime",
          "properties": [
            {
              "quotedPostOwnerId": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        }
      ],
      "required": [
        "$createdAt",
        "language"
      ],
      "properties": {
        "content": {
          "type": "string",
          "position": 0,
          "maxLength": 500,
          "minLength": 0,
          "description": "Post content (public content or teaser for private posts). Empty for pure reposts."
        },
        "mediaUrl": {
          "type": "string",
          "pattern": "^https?://.+$",
          "position": 1,
          "maxLength": 512,
          "description": "URL to media file (temporary field - will support multiple media in future)"
        },
        "quotedPostId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 2,
          "byteArray": true,
          "description": "ID of quoted post",
          "contentMediaType": "application/x.dash.dpp.identifier"
        },
        "language": {
          "type": "string",
          "pattern": "^[a-z]{2}$",
          "position": 3,
          "maxLength": 2,
          "description": "Language code of the post"
        },
        "sensitive": {
          "type": "boolean",
          "position": 4,
          "description": "Whether post contains sensitive content"
        },
        "encryptedContent": {
          "type": "array",
          "maxItems": 1024,
          "minItems": 1,
          "position": 5,
          "byteArray": true,
          "description": "Encrypted private post content (AEAD ciphertext). Presence indicates private post."
        },
        "epoch": {
          "type": "integer",
          "minimum": 1,
          "maximum": 4294967295,
          "position": 6,
          "description": "Epoch number for private post key derivation"
        },
        "nonce": {
          "type": "array",
          "maxItems": 24,
          "minItems": 24,
          "position": 7,
          "byteArray": true,
          "description": "24-byte nonce for XChaCha20-Poly1305 encryption"
        },
        "quotedPostOwnerId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 8,
          "byteArray": true,
          "description": "Identity ID of the quoted post owner (for notification queries)",
          "contentMediaType": "application/x.dash.dpp.identifier"
        }
      },
      "description": "A top-level post in the social network (not a reply)",
      "additionalProperties": false
    },
    "reply": {
      "type": "object",
      "indices": [
        {
          "name": "ownerAndTime",
          "properties": [
            {
              "$ownerId": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        },
        {
          "name": "parentAndTime",
          "properties": [
            {
              "parentId": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        },
        {
          "name": "parentOwnerAndTime",
          "properties": [
            {
              "parentOwnerId": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        }
      ],
      "required": [
        "$createdAt",
        "parentId",
        "parentOwnerId"
      ],
      "properties": {
        "content": {
          "type": "string",
          "position": 0,
          "maxLength": 500,
          "minLength": 0,
          "description": "Reply content"
        },
        "mediaUrl": {
          "type": "string",
          "pattern": "^https?://.+$",
          "position": 1,
          "maxLength": 512,
          "description": "URL to media file"
        },
        "parentId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 2,
          "byteArray": true,
          "description": "ID of post or reply being replied to",
          "contentMediaType": "application/x.dash.dpp.identifier"
        },
        "parentOwnerId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 3,
          "byteArray": true,
          "description": "Owner of parent (for notifications)",
          "contentMediaType": "application/x.dash.dpp.identifier"
        },
        "sensitive": {
          "type": "boolean",
          "position": 4,
          "description": "Whether reply contains sensitive content"
        },
        "encryptedContent": {
          "type": "array",
          "maxItems": 1024,
          "minItems": 1,
          "position": 5,
          "byteArray": true,
          "description": "Encrypted reply content for private threads"
        },
        "epoch": {
          "type": "integer",
          "minimum": 1,
          "maximum": 4294967295,
          "position": 6,
          "description": "Epoch number for private reply key derivation"
        },
        "nonce": {
          "type": "array",
          "maxItems": 24,
          "minItems": 24,
          "position": 7,
          "byteArray": true,
          "description": "24-byte nonce for XChaCha20-Poly1305 encryption"
        }
      },
      "description": "A reply to a post or another reply",
      "additionalProperties": false
    },
    "block": {
      "type": "object",
      "indices": [
        {
          "name": "ownerAndBlocked",
          "unique": true,
          "properties": [
            {
              "$ownerId": "asc"
            },
            {
              "blockedId": "asc"
            }
          ]
        },
        {
          "name": "ownerBlocks",
          "properties": [
            {
              "$ownerId": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        }
      ],
      "mutable": false,
      "required": [
        "$createdAt",
        "blockedId"
      ],
      "properties": {
        "blockedId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 0,
          "byteArray": true,
          "description": "Identity ID of the blocked user",
          "contentMediaType": "application/x.dash.dpp.identifier"
        },
        "message": {
          "type": "string",
          "minLength": 1,
          "maxLength": 280,
          "position": 1,
          "description": "Optional public reason/message for blocking"
        }
      },
      "description": "A block relationship with optional public message/reason",
      "additionalProperties": false
    },
    "blockFilter": {
      "type": "object",
      "indices": [
        {
          "name": "owner",
          "unique": true,
          "properties": [
            {
              "$ownerId": "asc"
            }
          ]
        }
      ],
      "required": [
        "$createdAt",
        "$updatedAt",
        "filterData"
      ],
      "properties": {
        "filterData": {
          "type": "array",
          "byteArray": true,
          "minItems": 1,
          "maxItems": 5000,
          "position": 0,
          "description": "Serialized bloom filter data (up to 5KB)"
        },
        "itemCount": {
          "type": "integer",
          "minimum": 0,
          "position": 1,
          "description": "Number of items added to the filter"
        },
        "version": {
          "type": "integer",
          "minimum": 1,
          "maximum": 255,
          "position": 2,
          "description": "Bloom filter parameters version for forward compatibility"
        }
      },
      "description": "Bloom filter of blocked users for efficient probabilistic matching. One per user.",
      "additionalProperties": false
    },
    "blockFollow": {
      "type": "object",
      "indices": [
        {
          "name": "owner",
          "unique": true,
          "properties": [
            {
              "$ownerId": "asc"
            }
          ]
        }
      ],
      "required": [
        "$createdAt",
        "$updatedAt",
        "followedBlockers"
      ],
      "properties": {
        "followedBlockers": {
          "type": "array",
          "byteArray": true,
          "minItems": 32,
          "maxItems": 3200,
          "position": 0,
          "description": "Encoded array of user IDs whose blocks are inherited (max 100 users * 32 bytes)"
        }
      },
      "description": "Tracks which users' block lists this user inherits (hard blocks). One per user.",
      "additionalProperties": false
    },
    "follow": {
      "type": "object",
      "indices": [
        {
          "name": "ownerAndFollowing",
          "unique": true,
          "properties": [
            {
              "$ownerId": "asc"
            },
            {
              "followingId": "asc"
            }
          ]
        },
        {
          "name": "following",
          "properties": [
            {
              "$ownerId": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        },
        {
          "name": "followers",
          "properties": [
            {
              "followingId": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        }
      ],
      "mutable": false,
      "required": [
        "$createdAt",
        "followingId"
      ],
      "properties": {
        "followingId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 0,
          "byteArray": true,
          "description": "Identity ID of the user being followed",
          "contentMediaType": "application/x.dash.dpp.identifier"
        }
      },
      "description": "A follow relationship between users",
      "additionalProperties": false
    },
    "profile": {
      "type": "object",
      "indices": [
        {
          "name": "owner",
          "unique": true,
          "properties": [
            {
              "$ownerId": "asc"
            }
          ]
        }
      ],
      "required": [
        "$createdAt",
        "displayName"
      ],
      "properties": {
        "bio": {
          "type": "string",
          "position": 1,
          "maxLength": 160,
          "description": "User biography"
        },
        "website": {
          "type": "string",
          "pattern": "^https?://.+$",
          "position": 4,
          "maxLength": 100,
          "description": "User's website"
        },
        "avatarId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 2,
          "byteArray": true,
          "description": "Reference to the user's avatar document",
          "contentMediaType": "application/x.dash.dpp.identifier"
        },
        "location": {
          "type": "string",
          "position": 5,
          "maxLength": 50,
          "description": "User location"
        },
        "bannerUrl": {
          "type": "string",
          "pattern": "^https?://.+$",
          "position": 3,
          "maxLength": 512,
          "description": "URL to profile banner image"
        },
        "displayName": {
          "type": "string",
          "position": 0,
          "maxLength": 50,
          "minLength": 1,
          "description": "Display name shown on profile"
        }
      },
      "description": "User profile information",
      "additionalProperties": false
    },
    "bookmark": {
      "type": "object",
      "indices": [
        {
          "name": "ownerAndPost",
          "unique": true,
          "properties": [
            {
              "$ownerId": "asc"
            },
            {
              "postId": "asc"
            }
          ]
        },
        {
          "name": "ownerBookmarks",
          "properties": [
            {
              "$ownerId": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        }
      ],
      "mutable": false,
      "required": [
        "$createdAt",
        "postId"
      ],
      "properties": {
        "postId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 0,
          "byteArray": true,
          "description": "ID of the bookmarked post or reply",
          "contentMediaType": "application/x.dash.dpp.identifier"
        }
      },
      "description": "A bookmarked post or reply",
      "additionalProperties": false
    },
    "followRequest": {
      "type": "object",
      "indices": [
        {
          "name": "targetAndRequester",
          "unique": true,
          "properties": [
            {
              "targetId": "asc"
            },
            {
              "$ownerId": "asc"
            }
          ]
        },
        {
          "name": "target",
          "properties": [
            {
              "targetId": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        }
      ],
      "required": [
        "$createdAt",
        "targetId"
      ],
      "properties": {
        "targetId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 0,
          "byteArray": true,
          "description": "Identity ID of the private feed owner being requested",
          "contentMediaType": "application/x.dash.dpp.identifier"
        },
        "publicKey": {
          "type": "array",
          "maxItems": 33,
          "minItems": 33,
          "position": 1,
          "byteArray": true,
          "description": "Requester's secp256k1 public key (compressed, 33 bytes) - required if only hash160 on-chain"
        }
      },
      "description": "A request to follow a user's private feed",
      "additionalProperties": false
    },
    "privateFeedGrant": {
      "type": "object",
      "indices": [
        {
          "name": "ownerAndRecipient",
          "unique": true,
          "properties": [
            {
              "$ownerId": "asc"
            },
            {
              "recipientId": "asc"
            }
          ]
        },
        {
          "name": "ownerAndLeaf",
          "unique": true,
          "properties": [
            {
              "$ownerId": "asc"
            },
            {
              "leafIndex": "asc"
            }
          ]
        }
      ],
      "mutable": false,
      "required": [
        "$createdAt",
        "recipientId",
        "leafIndex",
        "epoch",
        "encryptedPayload"
      ],
      "properties": {
        "recipientId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 0,
          "byteArray": true,
          "description": "Identity ID of the approved private follower",
          "contentMediaType": "application/x.dash.dpp.identifier"
        },
        "leafIndex": {
          "type": "integer",
          "minimum": 0,
          "maximum": 65535,
          "position": 1,
          "description": "Assigned leaf index in the key tree (0-1023 for 1024-leaf tree)"
        },
        "epoch": {
          "type": "integer",
          "minimum": 1,
          "maximum": 4294967295,
          "position": 2,
          "description": "Epoch at time of grant"
        },
        "encryptedPayload": {
          "type": "array",
          "maxItems": 600,
          "minItems": 1,
          "position": 3,
          "byteArray": true,
          "description": "ECIES-encrypted payload containing path keys and current CEK (~485 bytes)"
        }
      },
      "description": "A grant giving a user access to decrypt private feed posts",
      "additionalProperties": false
    },
    "privateFeedRekey": {
      "type": "object",
      "indices": [
        {
          "name": "ownerAndEpoch",
          "unique": true,
          "properties": [
            {
              "$ownerId": "asc"
            },
            {
              "epoch": "asc"
            }
          ]
        }
      ],
      "mutable": false,
      "required": [
        "$createdAt",
        "epoch",
        "revokedLeaf",
        "packets",
        "encryptedCEK"
      ],
      "properties": {
        "epoch": {
          "type": "integer",
          "minimum": 2,
          "maximum": 4294967295,
          "position": 0,
          "description": "New epoch number after this rekey (starts at 2 for first revocation)"
        },
        "revokedLeaf": {
          "type": "integer",
          "minimum": 0,
          "maximum": 65535,
          "position": 1,
          "description": "Leaf index that was revoked"
        },
        "packets": {
          "type": "array",
          "maxItems": 2048,
          "minItems": 1,
          "position": 2,
          "byteArray": true,
          "description": "Binary-encoded rekey packets for LKH key update (~1.2KB typical)"
        },
        "encryptedCEK": {
          "type": "array",
          "maxItems": 48,
          "minItems": 48,
          "position": 3,
          "byteArray": true,
          "description": "CEK[epoch] encrypted under new root key (32 bytes + 16 byte auth tag)"
        }
      },
      "description": "A rekey document created when revoking a private feed follower.",
      "additionalProperties": false
    },
    "privateFeedState": {
      "type": "object",
      "canBeDeleted": false,
      "indices": [
        {
          "name": "owner",
          "unique": true,
          "properties": [
            {
              "$ownerId": "asc"
            }
          ]
        }
      ],
      "mutable": false,
      "required": [
        "$createdAt",
        "treeCapacity",
        "maxEpoch",
        "encryptedSeed"
      ],
      "properties": {
        "treeCapacity": {
          "type": "integer",
          "minimum": 1,
          "maximum": 65535,
          "position": 0,
          "description": "Key tree capacity (typically 1024 for 1024 max private followers)"
        },
        "maxEpoch": {
          "type": "integer",
          "minimum": 1,
          "maximum": 4294967295,
          "position": 1,
          "description": "Maximum pre-generated epoch chain length (typically 2000)"
        },
        "encryptedSeed": {
          "type": "array",
          "maxItems": 256,
          "minItems": 1,
          "position": 2,
          "byteArray": true,
          "description": "ECIES-encrypted feed seed (33 byte ephemeral pubkey + encrypted payload)"
        }
      },
      "description": "Private feed state document created when enabling a private feed. IMMUTABLE - cannot be deleted.",
      "additionalProperties": false
    },
    "postHashtag": {
      "type": "object",
      "indices": [
        {
          "name": "hashtagsByTime",
          "properties": [
            {
              "$createdAt": "asc"
            }
          ]
        },
        {
          "name": "hashtagAndTime",
          "properties": [
            {
              "hashtag": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        },
        {
          "name": "postAndHashtag",
          "unique": true,
          "properties": [
            {
              "postId": "asc"
            },
            {
              "hashtag": "asc"
            }
          ]
        }
      ],
      "mutable": false,
      "required": [
        "$createdAt",
        "postId",
        "hashtag"
      ],
      "properties": {
        "postId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 0,
          "byteArray": true,
          "description": "ID of the post containing the hashtag",
          "contentMediaType": "application/x.dash.dpp.identifier"
        },
        "hashtag": {
          "type": "string",
          "pattern": "^[a-z0-9_]{1,63}$",
          "position": 1,
          "maxLength": 63,
          "minLength": 1,
          "description": "Lowercase hashtag without # prefix"
        }
      },
      "description": "A hashtag associated with a post",
      "additionalProperties": false
    },
    "postMention": {
      "type": "object",
      "indices": [
        {
          "name": "mentionedUserAndTime",
          "properties": [
            {
              "mentionedUserId": "asc"
            },
            {
              "$createdAt": "asc"
            }
          ]
        },
        {
          "name": "postAndMentioned",
          "unique": true,
          "properties": [
            {
              "postId": "asc"
            },
            {
              "mentionedUserId": "asc"
            }
          ]
        }
      ],
      "mutable": false,
      "required": [
        "$createdAt",
        "postId",
        "mentionedUserId"
      ],
      "properties": {
        "postId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 0,
          "byteArray": true,
          "description": "ID of the post containing the mention",
          "contentMediaType": "application/x.dash.dpp.identifier"
        },
        "mentionedUserId": {
          "type": "array",
          "maxItems": 32,
          "minItems": 32,
          "position": 1,
          "byteArray": true,
          "description": "Identity ID of the mentioned user",
          "contentMediaType": "application/x.dash.dpp.identifier"
        }
      },
      "description": "A mention of a user in a post",
      "additionalProperties": false
    }
  }
}

Document Types

  • like
  • post
  • reply
  • block
  • blockFilter
  • blockFollow
  • follow
  • profile
  • bookmark
  • followRequest
  • privateFeedGrant
  • privateFeedRekey
  • privateFeedState
  • postHashtag
  • postMention

Key Features

  • 500 character posts
  • Media attachments
  • Encrypted DMs
  • User verification
  • Lists & bookmarks

Deployment Instructions

  1. Update the ownerId field with your Dash identity ID
  2. Use the Dash SDK to register the contract on Platform
  3. Fund the contract with credits for storage operations
  4. Start building your decentralized social network!

Menu