SDK Cheatsheet
Here is a collection of the most commonly used methods within Subsocial SDK. For more in-depth look into this library, please reference the TypeDocs.
Setup
Install
yarn add @subsocial/api
Add utils library:
yarn add @subsocial/utils
Import
import { SubsocialApi } from "@subsocial/api";
Configuration
- TestNet
- MainNet
- xSocial
- LocalNet
const config = {
substrateNodeUrl: "wss://para.f3joule.space",
ipfsNodeUrl: "https://ipfs.subsocial.network",
};
Read more about Subsocial mainnet here.
const config = {
substrateNodeUrl: "wss://rco-para.subsocial.network",
ipfsNodeUrl: "https://gw.crustfiles.app",
};
Read more about Subsocial testnet here.
const config = {
substrateNodeUrl: "wss://xsocial.subsocial.network",
ipfsNodeUrl: "https://gw.crustfiles.app",
};
Read more about xSocial chain here.
const config = {
substrateNodeUrl: "http://127.0.0.1:9944",
ipfsNodeUrl: "http://127.0.0.1:8080",
};
Make sure to run local Subsocial & IPFS node before using these configs in your project.
const api = await SubsocialApi.create(config);
Signing and sending transactions
import { Keyring } from "@polkadot/keyring";
const keyring = new Keyring({ type: "sr25519" });
const accountPair = keyring.addFromMnemonic("add your mnemonic here");
tx.signAndSend(accountPair, async (result) => {
const { status } = result;
if (!result || !status) {
return;
}
if (status.isFinalized || status.isInBlock) {
const blockHash = status.isFinalized
? status.asFinalized
: status.asInBlock;
console.log(`✅ Tx finalized. Block hash: ${blockHash.toString()}`);
} else if (result.isError) {
console.log(JSON.stringify(result));
} else {
console.log(`⏱ Current tx status: ${status.type}`);
}
});
Read more about signing & sending transactions here.
Reading Data
Space
Space is the place where all content on SubSocial lives. It holds multiple posts from different people depending upon the permission. Read More
- By Id
- By Owner
const spaceId = 1;
const space = await api.findSpace({ id: spaceId });
const ownerAccountId = "<owner_account_public_key>";
// Fetching ids of all the spaces by owner.
const spaceIds = await api.blockchain.spaceIdsByOwner(ownerAccountId);
// Fetching space data from all ids.
const spaces = await api.base.findSpaces({ ids: spaceIds });
Check full docs here.
Post
Post is the piece of content that provides value for the readers. It can be some written text, an image, or a video. Read More
- By Id
- By Space Id
const postId = 1;
const post = await api.findPost({ id: postId });
const spaceId = 1;
const postIds = await api.blockchain.postIdsBySpaceId(spaceId);
const posts = await api.base.findPosts({ ids: postIds });
Check full docs here.
Profile
Profile is linked to your Subsocial account address, and is an overview of your activity on Subsocial. You can set a profile picture and a username for your account, as well as a personal website link. Read More
- Single Account
- Multiple Accounts
const accountId = "<account_public_key>";
const profile = await api.base.findProfileSpace(accountId);
const accountIds = ["<account_public_key_1>", "<account_public_key_2>"];
const profiles = await api.base.findProfileSpaces(accountIds);
Check full docs here.
Writing Data
Note
To store data on IPFS, it is necessary to set up a CRUST IPFS account and push the data from your account.
You set authHeader and setup with Subsocial SDK like this:
This is only required for the Testnet. On the Mainnet, this will not work.
const authHeader = 'c3ViLTVGQTluUURWZzI2N0RFZDhtMVp5cFhMQm52TjdTRnhZd1Y3bmRxU1lHaU45VFRwdToweDEwMmQ3ZmJhYWQwZGUwNzFjNDFmM2NjYzQzYmQ0NzIxNzFkZGFiYWM0MzEzZTc5YTY3ZWExOWM0OWFlNjgyZjY0YWUxMmRlY2YyNzhjNTEwZGY4YzZjZTZhYzdlZTEwNzY2N2YzYTBjZjM5OGUxN2VhMzAyMmRkNmEyYjc1OTBi';
api.ipfs.setWriteHeaders({
authorization: "Basic " + authHeader,
});
Space
Add following import statement:
import { IpfsContent, OptionBool } from "@subsocial/api/substrate/wrappers";
Storing space details in IPFS, and generating a CID.
const ipfsImageCid = await api.ipfs.saveFile(file);
const cid = await ipfs.saveContent({
about:
"Subsocial is an open protocol for decentralized social networks and marketplaces. It`s built with Substrate and IPFS",
image: ipfsImageCid,
name: "Subsocial",
tags: ["subsocial"],
});
Creating a Space transaction object
- Create Space
- Update Space
const substrateApi = await api.substrateApi;
const spaceTransaction = substrateApi.tx.spaces.createSpace(
IpfsContent(cid),
null // Permissions config (optional)
);
const substrateApi = await api.substrateApi;
const update = {
content: IpfsContent(cid),
hidden: new OptionBool(true),
};
const spaceTransaction = substrateApi.tx.spaces.updateSpace("1", update);
Sign and send the transaction, Check Here
Check the full docs here.
Post
Add following import statement:
import { IpfsContent, OptionBool } from "@subsocial/api/substrate/wrappers";
Storing post details in IPFS, and generating a CID.
const ipfsImageCid = await api.ipfs.saveFile(file);
const cid = await ipfs.saveContent({
title: "What is Subsocial?",
image: ipfsImageCid,
tags: ["Hello world", "FAQ"],
body: "Subsocial is an open protocol for decentralized social networks and marketplaces. It`s built with Substrate and IPFS.",
});
Creating a post transaction object
- Regular Post
- Shared Post
- Update Post
const spaceId = "1"; // The space in which you're posting.
const substrateApi = await api.substrateApi;
const postTransaction = substrateApi.tx.posts.createPost(
spaceId,
{ RegularPost: null }, // Creates a regular post.
IpfsContent(cid)
);
const spaceId = "1"; // The space in which you're posting.
const parentPostId = "2"; // The original post you want to share.
// Creating new sharedPostCid having shared message.
const sharedPostCid = await ipfs.saveContent({
body: "Keep up the good work!",
});
const substrateApi = await api.substrateApi;
const postTransaction = substrateApi.tx.posts.createPost(
spaceId,
{ SharedPost: parentPostId }, // Creates a shared post.
IpfsContent(sharedPostCid)
);
const postId = "7"; // Id of post which you want to update.
const substrateApi = await api.substrateApi;
const update = {
content: IpfsContent(cid),
hidden: new OptionBool(true),
};
const postTransaction = substrateApi.tx.posts.updatePost(postId, update);
Sign and send the transaction, Check Here
Check the full docs here.
Profile
Add the following import statement:
import { IpfsContent } from "@subsocial/api/substrate/wrappers";
Storing profile details in IPFS, and generating a CID to add on blockchain:
const ipfsImageCid = await api.ipfs.saveFile(file);
const cid = await ipfs.saveContent({
about: "Subsocial official account.",
avatar: ipfsImageCid,
name: "Subsocial",
});
Profiles in Subsocial is a simple space with it's Id marked on the blockchain to represent as profile.
Now, create a new space as mentioned here, so we can mark it as a profile.
Creating a profile object:
- Create Profile
- Reset Profile
const substrateApi = await api.substrateApi;
const spaceId = 3232; // The Id of space you want to mark as profile.
const profileTransaction = substrateApi.tx.profiles.setProfile(spaceId);
const profileTransaction = substrateApi.tx.profiles.resetProfile();
To change profile data, update the profile space from it's id.
Sign and send the transaction, Check Here
Check the full docs here.
Comments
Comments are replies to a post that are visible below a post.
Reading Comments
import { idToBn } from "@subsocial/utils";
const postId = "1";
// Get reply ids (comments) by parent post id and fetch posts by ids
const replyIds = await api.blockchain.getReplyIdsByPostId(idToBn(postId));
// For getting comments use posts functions
const replies = await api.findPublicPosts(replyIds);
Writing Comments
- Create
- Update
import { IpfsContent } from "@subsocial/api/substrate/wrappers";
const spaceId = "1"; // Optional.
const rootPostId = "1";
const cid = await ipfs.saveContent({
body: "Keep up the good work!",
});
const substrateApi = await api.substrateApi;
const tx = substrateApi.tx.posts.createPost(
spaceId,
{ Comment: { parentId: null, rootPostId } },
IpfsContent(cid)
);
import { IpfsContent } from "@subsocial/api/substrate/wrappers";
const spaceId = "1"; // Optional.
const parentId = "2"; // Parent comment id.
const rootPostId = "1";
const cid = await ipfs.saveContent({
body: "Agree", // Reply message.
});
const substrateApi = await api.substrateApi;
const tx = substrateApi.tx.posts.createPost(
spaceId,
{ Comment: { parentId, rootPostId } },
IpfsContent(cid)
);
Check the full docs here.
Follows
Check if follower
This checks if an account is following a particular space.
- Is Space Follower
- Is Account Follower
const accountId = "<any_public_key>";
const spaceId = "1";
const isFollower = await api.blockchain.isSpaceFollower(accountId, spaceId);
const yourAccountId = "<any_public_key>";
const otherAccountId = "<any_public_key>";
const isFollower = await api.blockchain.isAccountFollower(
yourAccountId,
otherAccountId
);
Fetch list of followers
For Spaces
- By Space Id
- Followed by Account Id
const spaceId = "1";
const substrateApi = await api.substrateApi;
const res = await substrateApi.query.spaceFollows.spaceFollowers(spaceId);
const followersSpaceIds = res;
const accountId = "<any_public_key>";
const substrateApi = await api.substrateApi;
const res = await substrateApi.query.spaceFollows.spacesFollowedByAccount(
accountId
);
const followedSpaceIds = res;
For Accounts
- Followers
- Following
const accountId = "<any_public_key>";
const substrateApi = await api.substrateApi;
const res = await substrateApi.query.accountFollows.accountFollowers(accountId);
const followersOfAccount = res;
const accountId = "<any_public_key>";
const substrateApi = await api.substrateApi;
const res = await substrateApi.query.accountFollows.accountsFollowedByAccount(
accountId
);
const followingOfAccount = res;
Check the full docs here.
Follow / Unfollow
For Spaces
- Follow
- Unfollow
const spaceId = "1";
const substrateApi = await api.substrateApi;
const tx = substrateApi.tx.spaceFollows.followSpace(spaceId);
const spaceId = "1";
const substrateApi = await api.substrateApi;
const tx = substrateApi.tx.spaceFollows.unfollowSpace(spaceId);
Sign and send the transaction, Check Here
For Accounts
- Follow
- Unfollow
const accountIdToFollow = "<any_public_key>";
const substrateApi = await api.substrateApi;
const tx = substrateApi.tx.accountFollows.followAccount(accountIdToFollow);
const accountIdToFollow = "<any_public_key>";
const substrateApi = await api.substrateApi;
const tx = substrateApi.tx.accountFollows.followAccount(accountIdToFollow);
Sign and send the transaction, Check Here
Check the full docs here.
Reactions
Reactions are your signs to Upvote
or Downvote
a post.
Get all reactions
- Single Reaction
- Multiple Reactions
const myAccount = "<any_account_public_key>";
const reaction = await api.blockchain.getPostReactionIdByAccount(
myAccount,
"1"
);
import { ReactionId } from "@subsocial/api/types/substrate";
const myAccount = "<any_account_public_key>";
const substrateApi = await api.substrateApi;
const tuples = ["1", "2", "3"].map((postId) => [myAccount, postId]);
const reactionIds =
await substrateApi.query.reactions.postReactionIdByAccount.multi(tuples);
const reactions = await api.blockchain.findReactions(
reactionIds as ReactionId[]
);
Reacting to a post
- Create
- Update
- Delete
const postId = "1"; // Post Id you want to react on.
const substrateApi = await api.substrateApi;
const reactionTx = substrateApi.tx.reactions.createPostReaction(
postId,
"Upvote"
);
const postId = "1"; // Post Id you want to update reaction on.
const reactionId = "2"; // Reaction Id to update.
const substrateApi = await api.substrateApi;
const reactionTx = substrateApi.tx.reactions.updatePostReaction(
postId,
reactionId,
"Downvote"
);
const postId = "1"; // Post Id on which reaction you want to delete reaction.
const reactionId = "2"; // Reaction Id to delete.
const substrateApi = await api.substrateApi;
const reactionTx = substrateApi.tx.reactions.deletePostReaction(
postId,
reactionId
);
Sign and send the transaction, Check Here
Check the full docs here.