# BEB Dimension GraphQL APIs for Developers Welcome to [BEB Dimensions](https://github.com/bebverse/universe)! Use the example GraphQL endpoint at [`beb.beb.xyz/graphql`](https://beb.beb.xyz/graphql) which is used by [BEBVerse](https://beb.xyz). Query other dimensions GraphQL endpoints with the [deployed Resolver](https://github.com/bebverse/contracts/blob/main/src/Resolver.sol). Check out [B7B](https://github.com/bebverse/b7b), an example app that does this. Alternatively, run [@bebverse/universe locally](https://github.com/bebverse/universe#developing-in-the-bebverseuniverse-repo). The recommended tool for querying @bebverse/universe GraphQL endpoints: [Apollo Sandbox](https://studio.apollographql.com/sandbox/explorer/) ## Authentication 1. Obtain an `AccountNonce` using `findAccountByAddressAndChain` to retrieve the nonce needed for the message. 2. Craft this message to sign for an Ethereum wallet: `@bebverse/universe wants you to sign in with your Ethereum account, secured with a signed message:\n ${account?.nonces?.nonce?.length} ${account?.nonces?.nonce}` 3. Sign the message using [RainbowKit](https://www.rainbowkit.com) or [Metamask SDK](https://docs.metamask.io/guide/). 4. Use `authBySignature` to get an `accessToken` for authenticated mutations and queries. Authenticated Queries require: `Authorization: Bearer $accessToken` ## Example App [B7B](https://github.com/bebverse/b7b) is a reference open-source client that browses all dimensions using [the BEB dimension resolver](https://github.com/bebverse/contracts). ## Full Schema Refer to the GraphQL Schema at [@bebverse/universe#graphql/typeDefs](https://github.com/bebverse/universe/tree/main/graphql/typeDefs). Here's the full schema using [gql-sdl](https://github.com/jkmartindale/gql-sdl) as of March 2023: ``` $ gql-sdl https://beb.beb.xyz/graphql ``` ```graphql= directive @cacheControl(maxAge: Int, scope: CacheControlScope, inheritMaxAge: Boolean) on FIELD_DEFINITION | OBJECT | INTERFACE | UNION type Portfolio { NFTScore: String NFTScoreUSD: String tokenScore: String walletScore: String updatedAt: String } type AccountExp { _id: ID baseExp: Int exp: Int account: Account portfolio: [Portfolio] } type IndexerRuleAllowlist { _id: ID addresses: [String] chain: Chain indexerRule: IndexerRule } type IndexerRuleAPI { _id: ID uri: String indexerRule: IndexerRule } type IndexerRuleNFT { _id: ID address: Address indexerRule: IndexerRule tokenId: String minAmount: String } type IndexerRuleAllowlistUnion { _id: ID indexerRuleType: IndexerRuleType indexerRuleAllowlistData: IndexerRuleAllowlist } type IndexerRuleAPIUnion { _id: ID indexerRuleType: IndexerRuleType indexerRuleAPIData: IndexerRuleAPI } type IndexerRuleNFTUnion { _id: ID indexerRuleType: IndexerRuleType indexerRuleNFTData: IndexerRuleNFT } union IndexerRuleData = IndexerRuleAllowlistUnion | IndexerRuleNFTUnion | IndexerRuleAPIUnion enum IndexerRuleType { ALLOWLIST PUBLIC NFT FARCASTER API } enum IndexerRuleOwnerType { ROLE CHANNEL RICH_BLOCK } type IndexerRule { _id: ID indexerRuleType: IndexerRuleType community: Community lastIndexedBlock: String lastIndexedAt: String ruleOwnerType: IndexerRuleOwnerType ruleData: IndexerRuleData } enum AssetRarity { COMMON UNCOMMON RARE EPIC LEGENDARY MYTHICAL ONE_OF_ONE } interface MutationResponse { code: String! success: Boolean! message: String! } interface Asset { description: String rarity: AssetRarity } type KeyValueFields { _id: ID key: String value: String } type Link { _id: ID url: String image: String title: String description: String logo: String iframe: String } type AuthBySignatureResponse implements MutationResponse { code: String! success: Boolean! message: String! account: Account accessToken: String } type AccountAddressMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! accountAddress: AccountAddress account: Account } type AccountMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! account: Account } type AccountRolesMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! account: Account roles: [Role] } type AccountDeleteMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! } type AccountSectionMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! accountSection: AccountSection } type ThreadTransactionSingleMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! threadTransaction: ThreadTransaction } type ThreadTransactionMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! thread: Thread threadTransaction: ThreadTransaction } type AccountThreadMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! accountThread: AccountThread } type AccountChannelMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! accountChannel: AccountChannel } type ThreadMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! thread: Thread accountThreads: [AccountThread] } type ThreadMessageMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! threadMessage: ThreadMessage } type PostMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! post: Post } type AccountRelationshipMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! relationship: AccountRelationship } type AccountCommunityMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! accountCommunity: AccountCommunity } type AccountReactionWithPostMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! post: Post accountReaction: AccountReaction } type CommunityMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! community: Community } type ChannelMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! channel: Channel } type ChannelDeleteMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! channelId: ID } type RoleMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! role: Role } type RoleDeleteMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! roleId: ID } type AccountCommunityRoleMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! accountCommunityRole: AccountCommunityRole } type IndexerRuleMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! indexerRule: IndexerRule } type PermissionOverwriteMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! permissionOverwrite: PermissionOverwrite } type CommunityQuestMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! communityQuest: CommunityQuest } type CommunityRoomMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! peers: [Peer] } type CommunityQuestWithAssetsMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! communityQuest: CommunityQuest communityAssets: [CommunityAsset] } type CommunityAssetMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! communityAsset: CommunityAsset communityAssetMetadata: CommunityAssetMetadata } type WithCountMutationResponse implements MutationResponse { code: String! success: Boolean! message: String! count: Int } type Mutation { createAccountFromAddress(address: String!, chainId: Int!, email: String): AccountMutationResponse authBySignature(address: String!, chainId: Int!, signature: String!): AuthBySignatureResponse updateCurrentAccount(email: String, username: String, location: String, profileImageId: String, bio: String, isOnboarded: Boolean, expoPushToken: String): AccountMutationResponse updateCurrentAddress(address: String!, signature: String!): AccountAddressMutationResponse claimAllRoles(communityId: ID!): AccountRolesMutationResponse deleteAccount: AccountDeleteMutationResponse addAccountSection(includeDefaultEntry: Boolean, title: String): AccountSectionMutationResponse updateAccountSection(isVisible: Boolean, title: String, accountSectionId: ID!): AccountSectionMutationResponse deleteAccountSection(accountSectionId: ID!): AccountSectionMutationResponse updateAccountSectionEntry(entryId: ID!, accountSectionId: ID!, imageId: ID, link: String, title: String): AccountSectionMutationResponse addAccountSectionEntry(accountSectionId: ID!): AccountSectionMutationResponse deleteAccountSectionEntry(entryId: ID!, accountSectionId: ID!): AccountSectionMutationResponse createThread(recipientAddress: String!, recipientChainId: Int!): ThreadMutationResponse createStakedThread(recipientAddress: String!, recipientChainId: Int!, nonce: String!, tokenAmount: String!, signature: String!, transactionHash: String!): ThreadTransactionMutationResponse completeThreadTransaction(threadTransactionId: ID!, completionTransactionHash: String!): ThreadTransactionSingleMutationResponse acceptAccountThread(threadId: ID!): AccountThreadMutationResponse updateAccountThreadLastSeen(threadId: ID!): AccountThreadMutationResponse createThreadMessage(threadId: ID!, contentRaw: String, contentJson: String, contentHtml: String, blocks: [RichContentBlockInput!]): ThreadMessageMutationResponse createPostOrReplyForAccount(parentId: ID, communityId: ID, channelId: ID, contentRaw: String, contentJson: String, contentHtml: String, blocks: [RichContentBlockInput!]): PostMutationResponse hidePost(postId: ID!): PostMutationResponse reactForPost(postId: ID!, reactionType: String!, amount: Int): AccountReactionWithPostMutationResponse toggleFollow(to: ID!): AccountRelationshipMutationResponse toggleBlock(to: ID!): AccountRelationshipMutationResponse updateUnseenNotifications: WithCountMutationResponse updateAccountCommunityLastSeen(communityId: ID!): AccountCommunityMutationResponse joinOrLeaveAccountCommunity(communityId: ID!, joined: Boolean!): AccountCommunityMutationResponse updateAccountChannelLastSeen(channelId: ID!): AccountChannelMutationResponse editCommunity(communityId: String!, name: String, imageId: String, bannerImageId: String, bio: ContentInput): CommunityMutationResponse registerCommunity(bebdomain: String!, tld: String): CommunityMutationResponse addChannelForCommunity(communityId: ID!, channelInput: ChannelInput, recipients: [String!]): ChannelMutationResponse editChannel(channelId: ID!, channelInput: ChannelInput): ChannelMutationResponse deleteChannel(channelId: ID!): ChannelMutationResponse createRoleForCommunity(communityId: ID!, roleInput: RoleInput, ruleDataInputs: [IndexerRuleDataInput]): RoleMutationResponse editRole(roleId: ID!, roleInput: RoleInput): RoleMutationResponse deleteRole(roleId: ID!): RoleDeleteMutationResponse updateRolePermissions(roleId: ID!, permissionIds: [String]): RoleMutationResponse createPermissionOverwrite(channelId: ID!): PermissionOverwriteMutationResponse deletePermissionOverwrite(permissionOverwriteId: ID!): PermissionOverwriteMutationResponse deleteAllPermissionOverwrites(channelId: ID!): WithCountMutationResponse createIndexerRuleForRole(roleId: ID!, ruleDataInput: IndexerRuleDataInput): IndexerRuleMutationResponse editIndexerRule(indexerRuleId: ID!, ruleDataInput: IndexerRuleDataInput): IndexerRuleMutationResponse grantRole(roleId: ID!, accountId: String, address: String): AccountCommunityRoleMutationResponse revokeRole(roleId: ID!, accountId: String, address: String): AccountCommunityRoleMutationResponse claimRole(roleId: ID!): AccountCommunityRoleMutationResponse completeQuest(questId: ID!, communityId: ID!): CommunityQuestMutationResponse claimReward(questId: ID!, communityId: ID!): CommunityQuestWithAssetsMutationResponse editCommunityAsset(communityAssetId: ID!, metadataId: ID, position: PositionInput, positions: [PositionInput], deleteAsset: Boolean): CommunityAssetMutationResponse getPeers(communityId: ID!): CommunityRoomMutationResponse setPeer(communityId: ID!, peerId: String): CommunityRoomMutationResponse } input RichContentBlockInput { blockType: String! blockId: ID! } input ContentInput { raw: String json: String html: String } input ChannelInput { name: String! description: ContentInput iconId: String color: String } input RoleInput { name: String! description: ContentInput iconId: String color: String isManagedByIndexer: Boolean } input PositionInput { x: Int y: Int z: Int } input IndexerRuleNFTInput { address: String tokenId: String minAmount: String chainId: Int } input IndexerRuleAPIInput { uri: String! } input IndexerRuleAllowlistInput { addresses: [String] } input IndexerRuleDataInput { indexerRuleType: IndexerRuleType indexerRuleAllowlistInput: IndexerRuleAllowlistInput indexerRuleNFTInput: IndexerRuleNFTInput indexerRuleAPIInput: IndexerRuleAPIInput } enum NotificationType { MESSAGE_REQUEST POST_COMMENT POST_REACTION CONNECTION_REQUEST POST_MENTION } type Notification { _id: ID content: Content initiator: Account receiver: Account externalUrl: String lastSeen: String createdAt: String image: Image title: String type: NotificationType } type Peer { peerId: String username: String expiresAt: String } type ScriptableAction { _id: ID title: String originalScriptUrl: String scriptUrl: String } type SocialLinks { _id: ID discord: String medium: String telegram: String twitter: String instagram: String website: String } type ThreadTransaction { _id: ID thread: Thread signature: String nonce: String tokenAddress: Address isCompleted: Boolean tokenAmount: String sender: Account recipient: Account transactionHash: String completionTransactionHash: String } type ThreadMessage { _id: ID thread: Thread sender: Account richContent: RichContent createdAt: String } type Thread { _id: ID messages(limit: Int, offset: Int): [ThreadMessage] transactions: [ThreadTransaction] recipients: [Account] recipientAccountThreads: [AccountThread] } enum Asset3DFormat { GLTF FBX } enum Asset3DType { LAND PROPS HUMANOID } type Asset3DUnion { _id: ID asset3D: Asset3D type: String } type Asset3D implements Asset { _id: ID url: String name: String previewImage: String format: Asset3DFormat assetType: Asset3DType description: String rarity: AssetRarity components: [RichContentBlock] } enum CommunityAssetType { ASSET_3D } union CommunityAssetItem = Asset3DUnion type CommunityAssetModification { _id: ID position: [Int] } type CommunityAssetMetadata { _id: ID position: Vector3D modification: Modification3D } type CommunityAsset { _id: ID community: Community type: CommunityAssetType asset: CommunityAssetItem modification: Modification3D position: Vector3D positions: [Vector3D] maxQuantity: Int metadata: [CommunityAssetMetadata] } type AccountActivity { _id: ID isWhitelisted: Boolean isOnboarded: Boolean lastSeen: String } type AccountNonce { _id: ID nonce: String transactionNonce: String } input AccountThreadsFilterInput { isAccepted: Boolean } type Account { _id: ID email: String username: String location: String bio: Content profileImage: Image address: AccountAddress relationship(to: ID): AccountRelationship nonces: AccountNonce sections: [AccountSection] activities: AccountActivity accountExp: AccountExp accountThreads(limit: Int, offset: Int, filters: AccountThreadsFilterInput): [AccountThread] accountCommunities(limit: Int, offset: Int): [AccountCommunity] identities: AccountIdentity hasPremiumRole: Boolean } type AccountCommunityCurrentACcountPermission { canRead: Boolean canWrite: Boolean } type AccountCommunity { _id: ID account: Account community: Community joined: Boolean unseenPostsCount: Int lastSeen: String currentAccountPermissions: AccountCommunityCurrentACcountPermission } type AccountCommunityRole { _id: ID accountCommunity: AccountCommunity role: Role isManagedByIndexer: Boolean isValid: Boolean } type FarcasterIdentity { _id: ID directoryUrl: String avatarUrl: String username: String displayName: String account: Account farcasterAddress: String } type ENSIdentity { _id: ID account: Account ens: String avatarUrl: String twitter: String } type AccountIdentity { _id: ID farcaster: FarcasterIdentity ens: ENSIdentity } type Reaction { _id: ID likes: Int } union ReactionObject = Post type AccountReaction { _id: ID reactions: Reaction account: Account reactionObjectType: String reactionObject: ReactionObject } type AccountRelationship { _id: ID from: Account to: Account connection: AccountRelationship isFollowing: Boolean isBlocking: Boolean } type SectionEntry { content: Content link: String image: Image title: String _id: ID } type AccountSection { _id: ID title: String isVisible: Boolean entries: [SectionEntry] } type AccountThread { _id: ID account: Account thread: Thread isAccepted: Boolean latestMessage: ThreadMessage userLastSeen: String } type AccountAddress { _id: ID address: String! chain: Chain account: Account } type Address { _id: ID address: String! chain: Chain } enum CacheControlScope { PUBLIC PRIVATE } type Chain { chainId: Int name: String } type AccountRecipientUnion { _id: ID account: Account type: RecipientType } type RoleRecipientUnion { _id: ID role: Role type: RecipientType } type AccountChannel { _id: ID channel: Channel account: Account userLastSeen: String } union Recipient = RoleRecipientUnion | AccountRecipientUnion enum RecipientType { ACCOUNT ROLE } type ChannelRecipient { _id: ID channel: Channel recipientType: RecipientType recipient: Recipient slug: String } type ChannelCurrentAccountPermission { canRead: Boolean canWrite: Boolean } type Channel { _id: ID name: String slug: String community: Community description: Content recipients: [ChannelRecipient] color: String icon: Image permissionOverwrites: [PermissionOverwrite] createdBy: Account currentAccountChannel: AccountChannel lastPostCreatedAt: String lastPost: Post currentAccountPermissions: ChannelCurrentAccountPermission } type RentPrice { base: String premium: String } type Commitment { hash: String secret: String } type CommunityCurrentACcountPermission { canAdmin: Boolean canRead: Boolean canWrite: Boolean } type Community { _id: ID description: String bio: Content name: String host: String image: Image bannerImage: Image membersCount: Int bebdomain: String socialLinks: SocialLinks accountCommunity: AccountCommunity members(limit: Int, offset: Int, sort: String): [AccountCommunity] owner: Account tokenOwnerAddress: String permissions: [Permission] roles(limit: Int, offset: Int, sort: String): [Role] channels: [Channel] tokenId: ID tld: String available: Boolean expiresAt: String rentPrice(duration: String): RentPrice commitment(address: String, duration: String): Commitment currentAccountPermissions: CommunityCurrentACcountPermission } type Content { raw: String json: String html: String } type Image { _id: ID src: String name: String isVerified: Boolean verificationOrigin: String verificationExternalUrl: String } type Permission { _id: ID community: Community description: Content name: String editable: Boolean bitwiseFlag: String bitwisePosition: Int } union PermissionOverwriteObject = Role | Account type PermissionOverwrite { _id: ID object: PermissionOverwriteObject allowedPermissionString: String objectType: Int } type PostCurrentAccountPermissions { _id: ID canHide: Boolean canRead(channelId: String): Boolean } type Post { _id: ID richContent: RichContent channel: Channel account: Account parent: Post replies(limit: Int, offset: Int): [Post] createdAt: String reactionCount: Int commentCount: Int rootCommentCount: Int community: Community isHidden: Boolean currentAccountPermissions: PostCurrentAccountPermissions } input PostFilter { account: ID post: ID community: ID channel: ID communities: [ID] excludeComments: Boolean excludeChannels: Boolean explore: Boolean } input AccountRelationshipFilter { from: ID to: ID isFollowing: Boolean excludeNotConnected: Boolean } input CommunityAssetFilter { communityId: ID type: CommunityAssetType } input AccountChannelFilter { communityId: ID } type NotificationQuery { _id: ID getAccountNotifications(limit: Int, offset: Int): [Notification] counUnseenNotifications: Int } type ChannelRecipientQuery { _id: ID getAccountChannelRecipients(limit: Int, offset: Int): [ChannelRecipient] } type SearchQuery { searchAccountByUsernameOrAddressOrEns(query: String): [Account] } type AccountQuery { _id: ID searchAccountByUsernameOrAddressOrEns(query: String): [Account] searchAccountByIdentity(query: String): [Account] getAccountSigninMessage(address: String!, chainId: Int!): String } type CommunityQuery { _id: ID getCommunityByDomainOrTokenId(bebdomain: String, tokenId: String, tld: String): Community getCommunityById(id: ID): Community searchCommunityByDomainOrName(query: String): [Community] } type RoleQuery { _id: ID getRoleById(id: ID): Role canClaimRole(roleId: ID!): Boolean } type QuestQuery { getQuests(limit: Int, offset: Int): [Quest] } type CommunityQuestQuery { getCommunityQuestStatus(questId: ID!, communityId: ID!): CommunityQuestStatus getCommunityQuest(questId: ID!, communityId: ID!): CommunityQuest } type CommunityAssetQuery { getCommunityAssets(limit: Int, offset: Int, filters: CommunityAssetFilter): [CommunityAsset] } type ChannelQuery { _id: ID getChannelById(id: ID!): Channel getPermissionOverwritesFor(channelId: ID!, objectId: ID!, objectType: Int!): [PermissionOverwrite] getFinalPermissionFor(channelId: ID!, objectId: ID!, objectType: Int): String getAccountChannels(limit: Int, offset: Int, filters: AccountChannelFilter): [Channel] } type Query { findAccountByAddressAndChain(address: String!, chainId: Int!): Account findAccountByFarcasterUsername(username: String!): Account getCurrentAccount: Account getThread(threadId: ID!): Thread getPostFeed(limit: Int, offset: Int, filters: PostFilter, sort: String): [Post] getAccountRelationships(limit: Int, offset: Int, filters: AccountRelationshipFilter): [AccountRelationship] getPost(id: ID!): Post getReactionsByPostId(limit: Int, offset: Int, postId: ID!): [AccountReaction] getReactionByAccountAndObjectId(reactionObjectType: String!, reactionObjectTypeId: ID!): AccountReaction getCurrentAccountAvailableRoles(communityId: ID!): [Role] getAccountNotifications: [Notification] getCommunities(limit: Int, offset: Int, sort: String): [Community] NotificationQuery: NotificationQuery SearchQuery: SearchQuery CommunityQuery: CommunityQuery RoleQuery: RoleQuery AccountQuery: AccountQuery CommunityAssetQuery: CommunityAssetQuery QuestQuery: QuestQuery CommunityQuestQuery: CommunityQuestQuery ChannelRecipientQuery: ChannelRecipientQuery ChannelQuery: ChannelQuery } type ImageUnion { _id: ID image: Image type: String } type LinkUnion { _id: ID link: Link type: String } type RichEmbedUnion { _id: ID richEmbed: RichEmbed type: String } type QuestUnion { _id: ID quest: Quest type: String } type ScriptableActionUnion { _id: ID scriptableAction: ScriptableAction type: String } union RichBlock = ImageUnion | LinkUnion | RichEmbedUnion | QuestUnion | ScriptableActionUnion type RichContentBlock { id: ID blockType: String block: RichBlock } type RichContent { _id: ID content: Content blocks: [RichContentBlock] } type RichEmbed { _id: ID title: String description: Content timestamp: String image: Image thumbnail: Image color: String url: String fields: KeyValueFields } type Role { _id: ID name: String description: Content community: Community slug: String position: Int editable: Boolean icon: Image isManagedByIndexer: Boolean permissionString: String indexerRules: [IndexerRule] membersCount: Int members(limit: Int, offset: Int, sort: String): [AccountCommunityRole] accountCommunityRole: AccountCommunityRole } type CommunityQuest { _id: ID quest: Quest community: Community isArchived: Boolean status: CommunityQuestStatus completedCount: Int } enum CommunityQuestStatus { COMPLETED IN_PROGRESS CAN_CLAIM_REWARD CAN_COMPLETE CHECKED_IN } enum QuestScheduleType { DAILY WEEKLY MONTHLY ONCE } enum QuestRequirementType { COMMUNITY_PARTICIPATION } enum QuestRewardType { ASSET_3D } union QuestRewardItem = Asset3DUnion type QuestRequirement { _id: ID title: String type: QuestRequirementType data: [KeyValueFields] } type QuestReward { _id: ID title: String type: QuestRewardType quantity: Int reward: QuestRewardItem } type Quest { _id: ID description: Content title: String schedule: QuestScheduleType imageUrl: String requirements: [QuestRequirement] rewards: [QuestReward] } type Modification3D { _id: ID transition: Vector3D rotation: Vector3D scale: Vector3D } type Vector3D { _id: ID x: Int y: Int z: Int } ```