Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • hive/wax
1 result
Show changes
Showing
with 90 additions and 245 deletions
import { IsDateString, IsNumber, IsString, Validate } from "class-validator";
import { IsPublicKey } from "../../decorators/is_public_key";
import type { TPublicKey } from "../../interfaces";
export class ApiWitness {
@IsNumber()
public id!: number;
@IsString()
public owner!: string;
@IsDateString()
public created!: string;
@Validate(IsPublicKey)
public signing_key!: TPublicKey;
export interface ApiWitness {
id: number;
owner: string;
created: string;
signing_key: TPublicKey;
};
......@@ -16,8 +16,6 @@ import Long from "long";
import { WaxFormatter } from "./formatters/waxify.js";
import { isNaiAsset } from "./util/asset_util.js";
import { plainToInstance } from "class-transformer";
import { validateSync } from "class-validator";
import type { AccountAuthorityUpdateOperation } from "./complex_operations"; // only for TypeDoc purposes :-(
import { ISignatureProvider } from "./extensions/signatures";
......@@ -181,11 +179,6 @@ export class WaxBaseApi implements IWaxBaseInterface {
}
public convertTransactionToBinaryForm(transaction: ApiTransaction, stripToUnsignedTransaction: boolean = false): THexString {
const validationErrors = validateSync(plainToInstance(ApiTransaction, transaction));
if(validationErrors.length > 0)
throw new WaxError(`Transaction validation failed: ${validationErrors.join(", ")}`);
const tx = this.createTransactionFromJson(transaction);
const conversionResult = safeWasmCall(() => this.proto.cpp_serialize_transaction(tx.toString(), stripToUnsignedTransaction));
......@@ -196,11 +189,6 @@ export class WaxBaseApi implements IWaxBaseInterface {
public convertTransactionFromBinaryForm(transaction: THexString): ApiTransaction {
const conversionResult = safeWasmCall(() => this.protocol.cpp_deserialize_transaction(transaction));
const validationErrors = validateSync(plainToInstance(ApiTransaction, JSON.parse(this.extract(conversionResult))));
if(validationErrors.length > 0)
throw new WaxError(`Transaction validation failed: ${validationErrors.join(", ")}`);
return JSON.parse(this.extract(conversionResult));
}
......
import type { IHiveChainInterface, IManabarData, ITransaction, IOnlineTransaction, TTimestamp, TPublicKey, TWaxExtended, TBlockHash, TWaxRestExtended, TDeepWaxApiRequestPartial } from "./interfaces";
import type { MainModule, MapStringUInt16, wax_authority, wax_authorities } from "../build_wasm/wax.common";
import { ApiAuthority, ApiWitness, BroadcastTransactionRequest, type ApiAccount, type ApiManabar, type ApiTransaction, type RcAccount } from "./api";
import { ApiAuthority, ApiWitness, type ApiAccount, type ApiManabar, type ApiTransaction, type RcAccount } from "./api";
import { WaxError } from "./errors.js";
import { safeWasmCall } from './util/wasm_errors.js';
......@@ -94,10 +94,10 @@ export class HiveChainApi extends WaxBaseApi implements IHiveChainInterface {
if ("performOnChainVerification" in transaction)
await transaction.performOnChainVerification();
const request = new BroadcastTransactionRequest();
request.trx = toBroadcast as ApiTransaction;
await this.api.network_broadcast_api.broadcast_transaction(request);
await this.api.network_broadcast_api.broadcast_transaction({
max_block_age: -1,
trx: toBroadcast as ApiTransaction
});
}
public withProxy(requestInterceptor: TRequestInterceptor, responseInterceptor: TResponseInterceptor): HiveChainApi {
......@@ -166,7 +166,7 @@ export class HiveChainApi extends WaxBaseApi implements IHiveChainInterface {
}
private async findAccountsNoThrow(...accountNames: string[]): Promise<Array<ApiAccount>> {
const { accounts } = await this.api.database_api.find_accounts({ accounts: accountNames });
const { accounts } = await this.api.database_api.find_accounts({ accounts: accountNames, delayed_votes_active: true });
return accounts;
}
......@@ -182,7 +182,7 @@ export class HiveChainApi extends WaxBaseApi implements IHiveChainInterface {
}
private async findWitnessAccountsNoThrow(...witnessNames: string[]): Promise<Array<ApiWitness>> {
const { witnesses } = await this.api.database_api.find_witnesses({ owners: witnessNames });
const { witnesses } = await this.api.database_api.find_witnesses({ owners: witnessNames, delayed_votes_active: true });
return witnesses;
}
......
......@@ -13,7 +13,7 @@ import { OperationTypeCountsRequest, OperationTypeCountsResponse } from "./rest-
import { GetWitnessesByNameRequest, SingleWitnessResponse } from "./rest-api/hafbe/witnesses/by-name.js";
import { GetAllWitnessesRequest } from "./rest-api/hafbe/witnesses/all.js";
export const HiveRestApiTypes = {
export type HiveRestApiTypes = {
'hafbe-api': {
witnesses: {
params: GetAllWitnessesRequest,
......@@ -34,7 +34,22 @@ export const HiveRestApiTypes = {
}
};
export const HiveApiTypes = {
export const HiveRestApiTypes = {
'hafbe-api': {
witnesses: {
responseArray: true,
accountName: {
urlPath: "{accountName}"
}
},
operationTypeCounts: {
responseArray: true,
urlPath: 'operation-type-counts'
}
}
} as HiveRestApiTypes;
export type HiveApiTypes = {
account_by_key_api: {
get_key_references: {
params: GetKeyReferencesRequest,
......@@ -86,3 +101,5 @@ export const HiveApiTypes = {
}
}
};
export const HiveApiTypes = {} as HiveApiTypes;
......@@ -3,6 +3,7 @@ import { TAccountName } from "../../../../hive_apps_operations/index.js";
import { WaxError } from "../../../../errors.js";
import { LevelBase } from "../../level_base.js";
import type { TPublicKey } from "../../../../interfaces";
import { structuredClone } from "../../../../shims/structuredclone.js";
export class HiveRoleAuthorityDefinition<TRole extends string> extends LevelBase<TRole> {
public constructor(
......
......@@ -34,7 +34,7 @@ export class HiveAccountCategory extends RoleCategoryBase<THiveRoles> {
this.HIVE_MAX_AUTHORITY_MEMBERSHIP = Number.parseInt(chain.config.HIVE_MAX_AUTHORITY_MEMBERSHIP);
const { accounts: [chainAccount] } = await chain.api.database_api.find_accounts({ accounts: [account] });
const { accounts: [chainAccount] } = await chain.api.database_api.find_accounts({ accounts: [account], delayed_votes_active: true });
const checkOwnerTimeDiff = (time: string): boolean => { // owner_update_limit_mgr.cpp
return Date.now() - new Date(`${time}Z`).getTime() > Number.parseInt(chain.config.HIVE_OWNER_UPDATE_LIMIT) / 1000;
......
import { defineMetadata } from "reflect-metadata/no-conflict";
export interface IWaxFormatterDecoratorOptions<T = any> {
/**
* Property to match. If not specified defaults to the formatter method name
......@@ -61,14 +63,14 @@ export const WaxFormattable = (options?: IWaxFormatterDecoratorOptions | string)
const requireDefined = (options as IWaxFormatterDecoratorOptions | undefined)?.requireDefined as boolean | undefined ?? false;
const matchInstanceOf = (options as IWaxFormatterDecoratorOptions | undefined)?.matchInstanceOf as { new(...args: any[]): any } | undefined;
Reflect.defineMetadata("wax:formatter:prop", matchProperty ?? propertyKey, target, propertyKey);
Reflect.defineMetadata("wax:formatter:explicitprop", typeof matchProperty === "string", target, propertyKey);
Reflect.defineMetadata("wax:formatter:requiredefined", requireDefined, target, propertyKey);
defineMetadata("wax:formatter:prop", matchProperty ?? propertyKey, target, propertyKey);
defineMetadata("wax:formatter:explicitprop", typeof matchProperty === "string", target, propertyKey);
defineMetadata("wax:formatter:requiredefined", requireDefined, target, propertyKey);
if(typeof matchValue !== "undefined")
Reflect.defineMetadata("wax:formatter:propvalue", matchValue, target, propertyKey);
defineMetadata("wax:formatter:propvalue", matchValue, target, propertyKey);
if(typeof matchInstanceOf !== "undefined")
Reflect.defineMetadata("wax:formatter:instanceof", matchInstanceOf, target, propertyKey);
defineMetadata("wax:formatter:instanceof", matchInstanceOf, target, propertyKey);
};
};
import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments, registerDecorator } from 'class-validator';
@ValidatorConstraint({ name: "isAuth", async: false })
export class IsAuthValidator implements ValidatorConstraintInterface {
public validate(value: any, _args: ValidationArguments) {
const isAuth = (what: any) => {
return typeof what === "object" && typeof what[0] === "string" && typeof what[1] === "number";
};
if (Array.isArray(value))
return value.some(isAuth);
return isAuth(value);
}
public defaultMessage(_args: ValidationArguments) {
return "The value must be a valid authority object.";
}
}
export const IsAuth = () => {
return (object: Record<string, any>, propertyName: string) => {
registerDecorator({
name: 'isAuth',
target: object.constructor,
propertyName: propertyName,
constraints: [],
validator: IsAuthValidator
});
};
}
import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments, registerDecorator } from 'class-validator';
@ValidatorConstraint({ name: "isNaiString", async: false })
export class IsNaiStringValidator implements ValidatorConstraintInterface {
public validate(value: any, _args: ValidationArguments) {
if (typeof value !== "string")
return false;
return /@@\d{9}/.test(value);
}
public defaultMessage(_args: ValidationArguments) {
return "The value must be a valid nai asset string - start with '@@' and ends with a number.";
}
}
export const IsNaiString = () => {
return (object: Record<string, any>, propertyName: string) => {
registerDecorator({
name: 'isNaiString',
target: object.constructor,
propertyName: propertyName,
constraints: [],
validator: IsNaiStringValidator
});
};
}
import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments, registerDecorator } from 'class-validator';
@ValidatorConstraint({ name: "isNumberOrNumberString", async: false })
export class IsNumberOrStringNumberValidator implements ValidatorConstraintInterface {
public validate(value: any, _args: ValidationArguments) {
return typeof value === 'number' || (typeof value === 'string' && !Number.isNaN(Number.parseFloat(value)));
}
public defaultMessage(_args: ValidationArguments) {
return "The value must be a valid number or number string.";
}
}
export const IsNumberOrStringNumber = () => {
return (object: Record<string, any>, propertyName: string) => {
registerDecorator({
name: 'isNumberOrNumberString',
target: object.constructor,
propertyName: propertyName,
constraints: [],
validator: IsNumberOrStringNumberValidator
});
};
}
import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments, registerDecorator } from 'class-validator';
export const isPublicKey = (value: string) => {
if (typeof value !== "string")
return false;
......@@ -12,25 +10,3 @@ export const isPublicKey = (value: string) => {
return base58Regex.test(value.slice(3));
};
@ValidatorConstraint({ name: "isPublicKey", async: false })
export class IsPublicKeyValidator implements ValidatorConstraintInterface {
public validate(value: any, _args: ValidationArguments) {
return isPublicKey(value);
}
public defaultMessage(_args: ValidationArguments) {
return "The value must be a valid public key - start with 'STM' and be base58 encoded.";
}
}
export const IsPublicKey = () => {
return (object: Record<string, any>, propertyName: string) => {
registerDecorator({
name: 'isPublicKey',
target: object.constructor,
propertyName: propertyName,
constraints: [],
validator: IsPublicKeyValidator
});
};
}
import { DeepPartial, DeepReadonly, IWaxFormatter, IWaxFormatterOptions } from "./types";
import { structuredClone } from "../shims/structuredclone.js";
export const DEFAULT_FORMATTER_OPTIONS: IWaxFormatterOptions = {
asset: {
......
......@@ -4,6 +4,8 @@ import type { IWaxBaseInterface } from "../interfaces";
import { WaxFormatterBase } from "./base";
import { DefaultFormatters } from "./default_formatters";
import Long from "long";
import { getMetadata } from "reflect-metadata/no-conflict";
import { structuredClone } from "../shims/structuredclone.js";
export interface IMatchersData {
matchValues: Map<string, TFormatFunction>;
......@@ -100,11 +102,11 @@ export class WaxFormatter extends WaxFormatterBase implements IWaxExtendableForm
const formatter = new formatterConstructor(this.wax);
for(const key of Object.getOwnPropertyNames(formatterConstructor.prototype)) {
const matchedProperty = Reflect.getMetadata("wax:formatter:prop", formatter, key) as string | undefined;
const explicitProp = Reflect.getMetadata("wax:formatter:explicitprop", formatter, key) as boolean | undefined;
const requireDefined = Reflect.getMetadata("wax:formatter:requiredefined", formatter, key) as boolean;
const matchedPropertyValue = Reflect.getMetadata("wax:formatter:propvalue", formatter, key) as any | undefined;
const matchInstanceOf = Reflect.getMetadata("wax:formatter:instanceof", formatter, key) as { new(...args: any[]): any } | undefined;
const matchedProperty = getMetadata("wax:formatter:prop", formatter, key) as string | undefined;
const explicitProp = getMetadata("wax:formatter:explicitprop", formatter, key) as boolean | undefined;
const requireDefined = getMetadata("wax:formatter:requiredefined", formatter, key) as boolean;
const matchedPropertyValue = getMetadata("wax:formatter:propvalue", formatter, key) as any | undefined;
const matchInstanceOf = getMetadata("wax:formatter:instanceof", formatter, key) as { new(...args: any[]): any } | undefined;
if(!explicitProp && typeof matchInstanceOf === "function") { // Match only by the instance if requested
const pred = newFormatter.instances.find(obj => obj.matchInstanceOf === matchInstanceOf);
......
import "reflect-metadata";
export { EAssetName } from "./base_api.js";
export { EManabarType } from './chain_api.js';
export { isPublicKey } from "./decorators/is_public_key.js";
......
import { Type } from "class-transformer";
import { IsArray, IsNumber, IsString, ValidateNested } from "class-validator";
export class OperationTypeCountsRequest {
@IsNumber()
public 'result-limit'!: number;
export interface OperationTypeCountsRequest {
'result-limit': number;
}
export class OpsCount {
@IsNumber()
public count!: number;
@IsNumber()
public op_type_id!: number;
export interface OpsCount {
count: number;
op_type_id: number;
}
export class OperationTypeCountsResponse {
@IsNumber()
public block_num!: number;
@IsString()
public witness!: string;
@Type(() => OpsCount)
@ValidateNested({ each: true })
@IsArray()
public ops_count!: OpsCount[];
export interface OperationTypeCountsResponse {
block_num: number;
witness: string;
ops_count: OpsCount[];
}
import { IsIn, IsNumber } from "class-validator";
const witnessSortKeys = ['witness', 'rank', 'url', 'votes', 'votes_daily_change', 'voters_num',
'voters_num_daily_change', 'price_feed', 'bias', 'block_size', 'signing_key', 'version'] as const;
......@@ -9,16 +7,12 @@ const directionKeys = ['asc', 'desc'] as const;
type TDirectionKeys = typeof directionKeys[number];
export class GetAllWitnessesRequest {
@IsNumber()
public 'result-limit'?: number = 100;
export interface GetAllWitnessesRequest {
'result-limit'?: number;
@IsNumber()
public 'offset'?: number = 0;
'offset'?: number;
@IsIn(witnessSortKeys)
public sort?: TWitnessSortKeys = 'votes';
sort?: TWitnessSortKeys;
@IsIn(directionKeys)
public direction?: TDirectionKeys = 'desc';
direction?: TDirectionKeys;
}
import { IsDateString, IsNumber, IsSemVer, IsString } from "class-validator";
import { IsPublicKey } from "../../../decorators/is_public_key.js";
export class GetWitnessesByNameRequest {
@IsString()
public accountName!: string;
export interface GetWitnessesByNameRequest {
accountName: string;
}
export class SingleWitnessResponse {
@IsString()
public witnes!: string;
@IsNumber()
public rank!: number;
@IsString()
public url!: string;
@IsString()
public vests!: string;
@IsNumber()
public vests_hive_power!: number;
@IsString()
public votes_daily_change!: string;
@IsString()
public votes_daily_change_hive_power!: string;
@IsNumber()
public voters_num!: number;
@IsNumber()
public voters_num_daily_change!: number;
@IsNumber()
public price_feed!: number;
@IsNumber()
public bias!: number;
@IsDateString()
public feed_updated_at!: string;
@IsNumber()
public block_size!: number;
@IsPublicKey()
public signing_key!: string;
@IsSemVer()
public version!: string;
@IsNumber()
public missed_blocks!: number;
@IsNumber()
public hbd_interest_rate!: number;
export interface SingleWitnessResponse {
witnes: string;
rank: number;
url: string;
vests: string;
vests_hive_power: number;
votes_daily_change: string;
votes_daily_change_hive_power: string;
voters_num: number;
voters_num_daily_change: number;
price_feed: number;
bias: number;
feed_updated_at: string;
block_size: number;
signing_key: string;
version: string;
missed_blocks: number;
hbd_interest_rate: number;
}
export const structuredClone = (value: any) => {
if (typeof globalThis.structuredClone === "undefined")
return JSON.parse(JSON.stringify(value));
return globalThis.structuredClone(value);
};
......@@ -10,6 +10,7 @@ import type { ApiTransaction } from "./api";
import { safeWasmCall } from "./util/wasm_errors";
import type { TAccountName } from "./hive_apps_operations";
import { ISignatureProvider } from "./extensions/signatures";
import { structuredClone } from "./shims/structuredclone.js";
type TIndexBeginEncryption = {
mainEncryptionKey: TPublicKey;
......
......@@ -3,6 +3,7 @@ import { TAccountName } from "../hive_apps_operations";
import type { TPublicKey } from "../interfaces";
import { WaxError } from "../errors";
import { ClassHandle, IAccountAuthorityProvider, wax_authority } from "wasm/lib/build_wasm/wax.common";
import { structuredClone } from "../shims/structuredclone.js";
/**
* Helper class used during traced authority verification process.
......