@oap75/api
Version:
JavaScript API for Subsocial blockchain.
291 lines (290 loc) • 13 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SubsocialSubstrateApi = void 0;
const types_1 = require("@polkadot/types");
const registry_1 = __importDefault(require("@subsocial/types/substrate/registry"));
const utils_1 = require("@subsocial/utils");
const utils_2 = require("../utils");
const filters_1 = require("../filters");
class SubsocialSubstrateApi {
// private context?: SubsocialContextProps TODO use when need
constructor({ api }) {
this.getPalletQuery = (pallet) => __awaiter(this, void 0, void 0, function* () {
const api = yield this.api;
return api.query[pallet];
});
this._api = api;
// this.context = context
logger.info('Initialized');
}
get api() {
return this._api.isReady;
}
// ---------------------------------------------------------------------
// Private utils
queryPallet(params, value) {
return __awaiter(this, void 0, void 0, function* () {
const { storage, pallet } = params;
const query = yield this.getPalletQuery(pallet);
// @ts-ignore
return query[storage](value);
});
}
queryPosts(storage, value) {
return __awaiter(this, void 0, void 0, function* () {
return this.queryPallet({ pallet: 'posts', storage }, value);
});
}
querySpaces(storage, value) {
return __awaiter(this, void 0, void 0, function* () {
return this.queryPallet({ pallet: 'spaces', storage }, value);
});
}
queryProfiles(storage, value) {
return __awaiter(this, void 0, void 0, function* () {
return this.queryPallet({ pallet: 'profiles', storage }, value);
});
}
queryPalletMulti(params, value) {
return __awaiter(this, void 0, void 0, function* () {
const { storage, pallet } = params;
const query = yield this.getPalletQuery(pallet);
// @ts-ignore
return query[storage].multi(value);
});
}
// TODO maybe pallet: 'posts' | 'spaces
isBooleanByAccount(params, accountId, subjectId) {
return __awaiter(this, void 0, void 0, function* () {
const { storage, pallet } = params;
const queryParams = new types_1.Tuple(registry_1.default, [types_1.GenericAccountId, 'u64'], [(0, utils_2.asAccountId)(accountId), subjectId]);
const isBoolean = yield this.queryPallet({ pallet, storage }, queryParams);
return isBoolean.valueOf();
});
}
getReactionIdsByAccount(accountId, structIds) {
return __awaiter(this, void 0, void 0, function* () {
const queryParams = structIds.map(id => new types_1.Tuple(registry_1.default, [types_1.GenericAccountId, 'u64'], [(0, utils_2.asAccountId)(accountId), id]));
return this.queryPalletMulti({ pallet: 'reactions', storage: 'postReactionIdByAccount' }, queryParams);
});
}
// ---------------------------------------------------------------------
// Multiple
findStructs(storageItem, ids) {
return __awaiter(this, void 0, void 0, function* () {
const storage = storageItem.storage;
try {
ids = (0, utils_2.getUniqueIds)(ids);
if ((0, utils_1.isEmptyArray)(ids)) {
logger.debug(`Nothing to load from ${storage}: no ids provided`);
return [];
}
const structs = yield this.queryPalletMulti(storageItem, ids);
const res = [];
structs.forEach((x, i) => {
if (x.isSome) {
const id = ids[i];
const item = x.unwrap();
res.push(storageItem.pallet === 'profiles'
? Object.assign({ id }, item) : item);
}
});
logger.debug(`Loaded ${(0, utils_1.pluralize)({ count: res.length, singularText: 'struct' })} from ${storage}`);
return res;
}
catch (err) {
logger.error(`Failed to load struct(s) from ${storage} by ${ids.length} id(s):`, err);
return [];
}
});
}
/**
* Find and load an array of information about spaces from Subsocial blockchain by a given array of `ids` and
* `visibility` filter.
*
* @returns An array of data about desired spaces from Subsocial blockchain. If no corresponding spaces to given array
* of `ids` and `visibility`, an empty array is returned.
*/
findSpaces(params) {
return __awaiter(this, void 0, void 0, function* () {
const { ids, visibility } = params;
const spaces = yield this.findStructs({ pallet: 'spaces', storage: 'spaceById' }, ids);
return (0, filters_1.visibilityFilter)(spaces, visibility);
});
}
/**
* Find and load an array of information about posts from Subsocial blockchain by a given array of `ids` and
* `visibility` filter.
*
* @returns An array of data about desired posts from Subsocial blockchain. If no corresponding posts to given array
* of `ids` and `visibility`, an empty array is returned.
*/
findPosts(params) {
return __awaiter(this, void 0, void 0, function* () {
const { ids, visibility } = params;
const posts = yield this.findStructs({ pallet: 'posts', storage: 'postById' }, ids);
return (0, filters_1.visibilityFilter)(posts, visibility);
});
}
/**
* Find and load an array of information about social profiles from Subsocial blockchain by a given array of account
* `ids`.
*
* @param ids - An array of account ids of desired profiles.
*
* @returns An array of data about desired profiles from Subsocial blockchain. If no corresponding profiles to given
* array of `ids`, an empty array is returned.
*/
findSocialAccounts(ids) {
return __awaiter(this, void 0, void 0, function* () {
const accountIds = ids.map(id => (0, utils_2.asAccountId)(id)).filter(x => typeof x !== 'undefined');
return this.findStructs({ pallet: 'profiles', storage: 'socialAccountById' }, accountIds);
});
}
/**
* Find and load an array of information about reactions from Subsocial blockchain by a given array of `ids`.
*
* @param ids - An array of ids of desired reactions.
*
* @returns An array of data about desired reactions from Subsocial blockchain. If no corresponding reactions to given
* array of `ids`, an empty array is returned.
*/
findReactions(ids) {
return __awaiter(this, void 0, void 0, function* () {
return this.findStructs({ pallet: 'reactions', storage: 'reactionById' }, ids);
});
}
// ---------------------------------------------------------------------
// Single
/**
* Find and load information about a space from Subsocial blockchain by a given `id` and `visibility` filter.
*
* @returns Data about desired space from Subsocial blockchain. If no corresponding space to given `id` and
* `visibility`, `undefined` is returned.
*/
findSpace(params) {
return __awaiter(this, void 0, void 0, function* () {
const { id, visibility } = params;
return (0, utils_1.getFirstOrUndefined)(yield this.findSpaces({ ids: [id], visibility }));
});
}
/**
* Find and load information about a post from Subsocial blockchain by a given `id` and `visibility` filter.
*
* @returns Data about desired post from Subsocial blockchain. If no corresponding post to given `id` and
* `visibility`, `undefined` is returned.
*/
findPost(params) {
return __awaiter(this, void 0, void 0, function* () {
const { id, visibility } = params;
return (0, utils_1.getFirstOrUndefined)(yield this.findPosts({ ids: [id], visibility }));
});
}
/**
* Find and load information about a profile from Subsocial blockchain by a given `id`.
*
* @param id - Account id of desired profile.
*
* @returns Data about desired profile from Subsocial blockchain. If no corresponding profile to given `id`,
* `undefined` is returned.
*/
findSocialAccount(id) {
return __awaiter(this, void 0, void 0, function* () {
return (0, utils_1.getFirstOrUndefined)(yield this.findSocialAccounts([id]));
});
}
/**
* Find and load information about a reaction from Subsocial blockchain by a given `id`.
*
* @param id - Id of desired reaction.
*
* @returns Data about desired reaction from Subsocial blockchain. If no corresponding reaction to given `id`,
* `undefined` is returned.
*/
findReaction(id) {
return __awaiter(this, void 0, void 0, function* () {
return (0, utils_1.getFirstOrUndefined)(yield this.findReactions([id]));
});
}
getPostReactionIdByAccount(accountId, postId) {
return __awaiter(this, void 0, void 0, function* () {
return (0, utils_1.getFirstOrUndefined)(yield this.getReactionIdsByAccount(accountId, [postId]));
});
}
getPostReactionIdsByAccount(accountId, postIds) {
return __awaiter(this, void 0, void 0, function* () {
return this.getReactionIdsByAccount(accountId, postIds);
});
}
// ---------------------------------------------------------------------
// Get id
nextSpaceId() {
return __awaiter(this, void 0, void 0, function* () {
return this.querySpaces('nextSpaceId');
});
}
nextPostId() {
return __awaiter(this, void 0, void 0, function* () {
return this.queryPosts('nextPostId');
});
}
getSpaceIdByHandle(handle) {
return __awaiter(this, void 0, void 0, function* () {
if ((0, utils_1.isEmptyStr)(handle)) {
return undefined;
}
const idOpt = yield this.querySpaces('spaceIdByHandle', handle);
return idOpt.unwrapOr(undefined);
});
}
getReplyIdsByPostId(id) {
return __awaiter(this, void 0, void 0, function* () {
return this.queryPosts('replyIdsByPostId', id);
});
}
spaceIdsByOwner(id) {
return __awaiter(this, void 0, void 0, function* () {
return this.querySpaces('spaceIdsByOwner', (0, utils_2.asAccountId)(id));
});
}
spaceIdsFollowedByAccount(id) {
return __awaiter(this, void 0, void 0, function* () {
return this.queryPallet({ pallet: 'spaceFollows', storage: 'spacesFollowedByAccount' }, (0, utils_2.asAccountId)(id));
});
}
postIdsBySpaceId(id) {
return __awaiter(this, void 0, void 0, function* () {
return this.queryPosts('postIdsBySpaceId', id);
});
}
// ---------------------------------------------------------------------
// Is boolean
isAccountFollower(myAddress, followedAddress) {
return __awaiter(this, void 0, void 0, function* () {
const followedAccountId = (0, utils_2.asAccountId)(followedAddress);
const myAccountId = (0, utils_2.asAccountId)(myAddress);
const queryParams = new types_1.Tuple(registry_1.default, [types_1.GenericAccountId, types_1.GenericAccountId], [myAccountId, followedAccountId]);
const isFollow = yield this.queryPallet({ pallet: 'profileFollows', storage: 'accountFollowedByAccount' }, queryParams);
return isFollow.valueOf();
});
}
isSpaceFollower(myAddress, spaceId) {
return __awaiter(this, void 0, void 0, function* () {
return this.isBooleanByAccount({ pallet: 'spaceFollows', storage: 'spaceFollowedByAccount' }, myAddress, spaceId);
});
}
}
exports.SubsocialSubstrateApi = SubsocialSubstrateApi;
const logger = (0, utils_1.newLogger)(SubsocialSubstrateApi.name);