diff --git a/cli/README.md b/cli/README.md index 974725a1dc..fe3253f905 100644 --- a/cli/README.md +++ b/cli/README.md @@ -108,7 +108,7 @@ OPTIONS --showSpecial Whether to show special (DEV chain) accounts ``` -_See code: [src/commands/account/choose.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/account/choose.ts)_ +_See code: [src/commands/account/choose.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/account/choose.ts)_ ## `joystream-cli account:create NAME` @@ -122,7 +122,7 @@ ARGUMENTS NAME Account name ``` -_See code: [src/commands/account/create.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/account/create.ts)_ +_See code: [src/commands/account/create.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/account/create.ts)_ ## `joystream-cli account:current` @@ -137,7 +137,7 @@ ALIASES $ joystream-cli account:default ``` -_See code: [src/commands/account/current.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/account/current.ts)_ +_See code: [src/commands/account/current.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/account/current.ts)_ ## `joystream-cli account:export PATH` @@ -154,7 +154,7 @@ OPTIONS -a, --all If provided, exports all existing accounts into "exported_accounts" folder inside given path ``` -_See code: [src/commands/account/export.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/account/export.ts)_ +_See code: [src/commands/account/export.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/account/export.ts)_ ## `joystream-cli account:forget` @@ -165,7 +165,7 @@ USAGE $ joystream-cli account:forget ``` -_See code: [src/commands/account/forget.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/account/forget.ts)_ +_See code: [src/commands/account/forget.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/account/forget.ts)_ ## `joystream-cli account:import BACKUPFILEPATH` @@ -179,7 +179,7 @@ ARGUMENTS BACKUPFILEPATH Path to account backup JSON file ``` -_See code: [src/commands/account/import.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/account/import.ts)_ +_See code: [src/commands/account/import.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/account/import.ts)_ ## `joystream-cli account:transferTokens RECIPIENT AMOUNT` @@ -194,7 +194,7 @@ ARGUMENTS AMOUNT Amount of tokens to transfer ``` -_See code: [src/commands/account/transferTokens.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/account/transferTokens.ts)_ +_See code: [src/commands/account/transferTokens.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/account/transferTokens.ts)_ ## `joystream-cli api:getUri` @@ -205,7 +205,7 @@ USAGE $ joystream-cli api:getUri ``` -_See code: [src/commands/api/getUri.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/api/getUri.ts)_ +_See code: [src/commands/api/getUri.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/api/getUri.ts)_ ## `joystream-cli api:inspect` @@ -221,15 +221,15 @@ OPTIONS If no "--method" flag is provided then all methods in that module will be listed along with the descriptions. -a, --callArgs=callArgs - Specifies the arguments to use when calling a method. Multiple arguments can be separated with a comma, ie. + Specifies the arguments to use when calling a method. Multiple arguments can be separated with a comma, ie. "-a=arg1,arg2". You can omit this flag even if the method requires some aguments. In that case you will be promted to provide value for each required argument. - Ommiting this flag is recommended when input parameters are of more complex types (and it's hard to specify them as + Ommiting this flag is recommended when input parameters are of more complex types (and it's hard to specify them as just simple comma-separated strings) -e, --exec - Provide this flag if you want to execute the actual call, instead of displaying the method description (which is + Provide this flag if you want to execute the actual call, instead of displaying the method description (which is default) -m, --method=method @@ -249,7 +249,7 @@ EXAMPLES $ api:inspect -t=query -M=members -m=membershipById -e -a=1 ``` -_See code: [src/commands/api/inspect.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/api/inspect.ts)_ +_See code: [src/commands/api/inspect.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/api/inspect.ts)_ ## `joystream-cli api:setUri [URI]` @@ -263,7 +263,7 @@ ARGUMENTS URI Uri of the node api WS provider (if skipped, a prompt will be displayed) ``` -_See code: [src/commands/api/setUri.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/api/setUri.ts)_ +_See code: [src/commands/api/setUri.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/api/setUri.ts)_ ## `joystream-cli autocomplete [SHELL]` @@ -297,7 +297,7 @@ USAGE $ joystream-cli council:info ``` -_See code: [src/commands/council/info.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/council/info.ts)_ +_See code: [src/commands/council/info.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/council/info.ts)_ ## `joystream-cli help [COMMAND]` @@ -333,7 +333,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/application.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/application.ts)_ +_See code: [src/commands/working-groups/application.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/application.ts)_ ## `joystream-cli working-groups:createOpening` @@ -359,7 +359,7 @@ OPTIONS -s, --skipPrompts Whether to skip all prompts when adding from draft (will use all default values) ``` -_See code: [src/commands/working-groups/createOpening.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/createOpening.ts)_ +_See code: [src/commands/working-groups/createOpening.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/createOpening.ts)_ ## `joystream-cli working-groups:decreaseWorkerStake WORKERID` @@ -378,7 +378,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/decreaseWorkerStake.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/decreaseWorkerStake.ts)_ +_See code: [src/commands/working-groups/decreaseWorkerStake.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/decreaseWorkerStake.ts)_ ## `joystream-cli working-groups:evictWorker WORKERID` @@ -397,7 +397,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/evictWorker.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/evictWorker.ts)_ +_See code: [src/commands/working-groups/evictWorker.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/evictWorker.ts)_ ## `joystream-cli working-groups:fillOpening WGOPENINGID` @@ -416,7 +416,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/fillOpening.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/fillOpening.ts)_ +_See code: [src/commands/working-groups/fillOpening.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/fillOpening.ts)_ ## `joystream-cli working-groups:increaseStake` @@ -432,7 +432,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/increaseStake.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/increaseStake.ts)_ +_See code: [src/commands/working-groups/increaseStake.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/increaseStake.ts)_ ## `joystream-cli working-groups:leaveRole` @@ -448,7 +448,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/leaveRole.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/leaveRole.ts)_ +_See code: [src/commands/working-groups/leaveRole.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/leaveRole.ts)_ ## `joystream-cli working-groups:opening WGOPENINGID` @@ -467,7 +467,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/opening.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/opening.ts)_ +_See code: [src/commands/working-groups/opening.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/opening.ts)_ ## `joystream-cli working-groups:openings` @@ -483,7 +483,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/openings.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/openings.ts)_ +_See code: [src/commands/working-groups/openings.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/openings.ts)_ ## `joystream-cli working-groups:overview` @@ -499,7 +499,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/overview.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/overview.ts)_ +_See code: [src/commands/working-groups/overview.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/overview.ts)_ ## `joystream-cli working-groups:slashWorker WORKERID` @@ -518,7 +518,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/slashWorker.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/slashWorker.ts)_ +_See code: [src/commands/working-groups/slashWorker.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/slashWorker.ts)_ ## `joystream-cli working-groups:startAcceptingApplications WGOPENINGID` @@ -537,7 +537,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/startAcceptingApplications.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/startAcceptingApplications.ts)_ +_See code: [src/commands/working-groups/startAcceptingApplications.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/startAcceptingApplications.ts)_ ## `joystream-cli working-groups:startReviewPeriod WGOPENINGID` @@ -556,7 +556,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/startReviewPeriod.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/startReviewPeriod.ts)_ +_See code: [src/commands/working-groups/startReviewPeriod.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/startReviewPeriod.ts)_ ## `joystream-cli working-groups:terminateApplication WGAPPLICATIONID` @@ -575,7 +575,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/terminateApplication.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/terminateApplication.ts)_ +_See code: [src/commands/working-groups/terminateApplication.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/terminateApplication.ts)_ ## `joystream-cli working-groups:updateRewardAccount [ACCOUNTADDRESS]` @@ -594,7 +594,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/updateRewardAccount.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/updateRewardAccount.ts)_ +_See code: [src/commands/working-groups/updateRewardAccount.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/updateRewardAccount.ts)_ ## `joystream-cli working-groups:updateRoleAccount [ACCOUNTADDRESS]` @@ -613,7 +613,7 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/updateRoleAccount.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/updateRoleAccount.ts)_ +_See code: [src/commands/working-groups/updateRoleAccount.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/updateRoleAccount.ts)_ ## `joystream-cli working-groups:updateWorkerReward WORKERID` @@ -632,5 +632,5 @@ OPTIONS Available values are: storageProviders. ``` -_See code: [src/commands/working-groups/updateWorkerReward.ts](https://github.com/Joystream/substrate-runtime-joystream/blob/master/cli/src/commands/working-groups/updateWorkerReward.ts)_ +_See code: [src/commands/working-groups/updateWorkerReward.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/updateWorkerReward.ts)_ diff --git a/cli/package.json b/cli/package.json index 2dbd532144..2fa72f0e03 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,7 +1,7 @@ { "name": "@joystream/cli", "description": "Command Line Interface for Joystream community and governance activities", - "version": "0.1.0", + "version": "0.2.0", "author": "Leszek Wiesner", "bin": { "joystream-cli": "./bin/run" diff --git a/cli/src/Api.ts b/cli/src/Api.ts index e14aaac095..22cbf13e69 100644 --- a/cli/src/Api.ts +++ b/cli/src/Api.ts @@ -1,13 +1,12 @@ import BN from 'bn.js' -import { registerJoystreamTypes } from '@joystream/types/' +import { types } from '@joystream/types/' import { ApiPromise, WsProvider } from '@polkadot/api' -import { QueryableStorageMultiArg } from '@polkadot/api/types' +import { QueryableStorageMultiArg, SubmittableExtrinsic, QueryableStorageEntry } from '@polkadot/api/types' import { formatBalance } from '@polkadot/util' -import { Hash, Balance, Moment, BlockNumber } from '@polkadot/types/interfaces' +import { Balance, Moment, BlockNumber } from '@polkadot/types/interfaces' import { KeyringPair } from '@polkadot/keyring/types' -import { Codec } from '@polkadot/types/types' -import { Option, Vec } from '@polkadot/types' -import { u32 } from '@polkadot/types/primitive' +import { Codec, CodecArg } from '@polkadot/types/types' +import { Option, Vec, UInt } from '@polkadot/types' import { AccountSummary, CouncilInfoObj, @@ -24,7 +23,7 @@ import { UnstakingPeriods, StakingPolicyUnstakingPeriodKey, } from './Types' -import { DerivedFees, DerivedBalances } from '@polkadot/api-derive/types' +import { DeriveBalancesAll } from '@polkadot/api-derive/types' import { CLIError } from '@oclif/errors' import ExitCodes from './ExitCodes' import { @@ -46,12 +45,11 @@ import { import { MemberId, Membership } from '@joystream/types/members' import { RewardRelationship, RewardRelationshipId } from '@joystream/types/recurring-rewards' import { Stake, StakeId } from '@joystream/types/stake' -import { LinkageResult } from '@polkadot/types/codec/Linkage' import { InputValidationLengthConstraint } from '@joystream/types/common' export const DEFAULT_API_URI = 'ws://localhost:9944/' -const DEFAULT_DECIMALS = new u32(12) +const DEFAULT_DECIMALS = new BN(12) // Mapping of working group to api module export const apiModuleByGroup: { [key in WorkingGroups]: string } = { @@ -72,8 +70,7 @@ export default class Api { private static async initApi(apiUri: string = DEFAULT_API_URI): Promise { const wsProvider: WsProvider = new WsProvider(apiUri) - registerJoystreamTypes() - const api = await ApiPromise.create({ provider: wsProvider }) + const api = await ApiPromise.create({ provider: wsProvider, types }) // Initializing some api params based on pioneer/packages/react-api/Api.tsx const [properties] = await Promise.all([api.rpc.system.properties()]) @@ -95,23 +92,27 @@ export default class Api { return new Api(originalApi) } - private async queryMultiOnce(queries: Parameters[0]): Promise { - let results: Codec[] = [] - - const unsub = await this._api.queryMulti(queries, (res) => { - results = res + private queryMultiOnce(queries: Parameters[0]): Promise { + return new Promise((resolve, reject) => { + let unsub: () => void + this._api + .queryMulti(queries, (res) => { + // unsub should already be set at this point + if (!unsub) { + reject(new CLIError('API queryMulti issue - unsub method not set!', { exit: ExitCodes.ApiError })) + } + unsub() + resolve(res) + }) + .then((unsubscribe) => (unsub = unsubscribe)) + .catch((e) => reject(e)) }) - unsub() - - if (!results.length || results.length !== queries.length) { - throw new CLIError('API querying issue', { exit: ExitCodes.ApiError }) - } - - return results } - async getAccountsBalancesInfo(accountAddresses: string[]): Promise { - const accountsBalances: DerivedBalances[] = await this._api.derive.balances.votingBalances(accountAddresses) + async getAccountsBalancesInfo(accountAddresses: string[]): Promise { + const accountsBalances: DeriveBalancesAll[] = await Promise.all( + accountAddresses.map((addr) => this._api.derive.balances.all(addr)) + ) return accountsBalances } @@ -119,7 +120,7 @@ export default class Api { // Get on-chain data related to given account. // For now it's just account balances async getAccountSummary(accountAddresses: string): Promise { - const balances: DerivedBalances = (await this.getAccountsBalancesInfo([accountAddresses]))[0] + const balances: DeriveBalancesAll = (await this.getAccountsBalancesInfo([accountAddresses]))[0] // TODO: Some more information can be fetched here in the future return { balances } @@ -146,34 +147,29 @@ export default class Api { return createCouncilInfoObj(...results) } - // TODO: This formula is probably not too good, so some better implementation will be required in the future - async estimateFee(account: KeyringPair, recipientAddr: string, amount: BN): Promise { - const transfer = this._api.tx.balances.transfer(recipientAddr, amount) - const signature = account.sign(transfer.toU8a()) - const transactionByteSize: BN = new BN(transfer.encodedLength + signature.length) - - const fees: DerivedFees = await this._api.derive.balances.fees() - - const estimatedFee = fees.transactionBaseFee.add(fees.transactionByteFee.mul(transactionByteSize)) - - return estimatedFee + async estimateFee(account: KeyringPair, tx: SubmittableExtrinsic<'promise'>): Promise { + const paymentInfo = await tx.paymentInfo(account) + return paymentInfo.partialFee } - async transfer(account: KeyringPair, recipientAddr: string, amount: BN): Promise { - const txHash = await this._api.tx.balances.transfer(recipientAddr, amount).signAndSend(account) - return txHash + createTransferTx(recipient: string, amount: BN) { + return this._api.tx.balances.transfer(recipient, amount) } // Working groups - // TODO: This is a lot of repeated logic from "/pioneer/joy-roles/src/transport.substrate.ts" - // (although simplified a little bit) - // Hopefully this will be refactored to "joystream-js" soon - protected singleLinkageResult(result: LinkageResult) { - return result[0] as T - } + // TODO: This is a lot of repeated logic from "/pioneer/joy-utils/transport" + // It will be refactored to "joystream-js" soon + async entriesByIds( + apiMethod: QueryableStorageEntry<'promise'>, + firstKey?: CodecArg // First key in case of double maps + ): Promise<[IDType, ValueType][]> { + const entries: [IDType, ValueType][] = (await apiMethod.entries(firstKey)).map(([storageKey, value]) => [ + // If double-map (first key is provided), we map entries by second key + storageKey.args[firstKey !== undefined ? 1 : 0] as IDType, + value, + ]) - protected multiLinkageResult(result: LinkageResult): [Vec, Vec] { - return [result[0] as Vec, result[1] as Vec] + return entries.sort((a, b) => a[0].toNumber() - b[0].toNumber()) } protected async blockHash(height: number): Promise { @@ -214,7 +210,7 @@ export default class Api { } protected async stakeValue(stakeId: StakeId): Promise { - const stake = this.singleLinkageResult((await this._api.query.stake.stakes(stakeId)) as LinkageResult) + const stake = await this._api.query.stake.stakes(stakeId) return stake.value } @@ -223,8 +219,8 @@ export default class Api { } protected async workerReward(relationshipId: RewardRelationshipId): Promise { - const rewardRelationship = this.singleLinkageResult( - (await this._api.query.recurringRewards.rewardRelationships(relationshipId)) as LinkageResult + const rewardRelationship = await this._api.query.recurringRewards.rewardRelationships( + relationshipId ) return { @@ -266,18 +262,16 @@ export default class Api { } async workerByWorkerId(group: WorkingGroups, workerId: number): Promise { - const nextId = (await this.workingGroupApiQuery(group).nextWorkerId()) as WorkerId + const nextId = await this.workingGroupApiQuery(group).nextWorkerId() // This is chain specfic, but if next id is still 0, it means no workers have been added yet if (workerId < 0 || workerId >= nextId.toNumber()) { throw new CLIError('Invalid worker id!') } - const worker = this.singleLinkageResult( - (await this.workingGroupApiQuery(group).workerById(workerId)) as LinkageResult - ) + const worker = await this.workingGroupApiQuery(group).workerById(workerId) - if (!worker.is_active) { + if (worker.isEmpty) { throw new CLIError('This worker is not active anymore') } @@ -286,67 +280,51 @@ export default class Api { async groupMember(group: WorkingGroups, workerId: number) { const worker = await this.workerByWorkerId(group, workerId) - return await this.parseGroupMember(new WorkerId(workerId), worker) + return await this.parseGroupMember(this._api.createType('WorkerId', workerId), worker) } async groupMembers(group: WorkingGroups): Promise { - const nextId = (await this.workingGroupApiQuery(group).nextWorkerId()) as WorkerId - - // This is chain specfic, but if next id is still 0, it means no workers have been added yet - if (nextId.eq(0)) { - return [] - } + const workerEntries = await this.entriesByIds(this.workingGroupApiQuery(group).workerById) - const [workerIds, workers] = this.multiLinkageResult( - (await this.workingGroupApiQuery(group).workerById()) as LinkageResult + const groupMembers: GroupMember[] = await Promise.all( + workerEntries.map(([id, worker]) => this.parseGroupMember(id, worker)) ) - const groupMembers: GroupMember[] = [] - for (const [index, worker] of Object.entries(workers.toArray())) { - const workerId = workerIds[parseInt(index)] - if (worker.is_active) { - groupMembers.push(await this.parseGroupMember(workerId, worker)) - } - } - - return groupMembers.reverse() + return groupMembers.reverse() // Sort by newest } async openingsByGroup(group: WorkingGroups): Promise { - const openings: GroupOpening[] = [] - const nextId = (await this.workingGroupApiQuery(group).nextOpeningId()) as OpeningId + let openings: GroupOpening[] = [] + const nextId = await this.workingGroupApiQuery(group).nextOpeningId() // This is chain specfic, but if next id is still 0, it means no openings have been added yet if (!nextId.eq(0)) { - const highestId = nextId.toNumber() - 1 - for (let i = highestId; i >= 0; i--) { - openings.push(await this.groupOpening(group, i)) - } + const ids = Array.from(Array(nextId.toNumber()).keys()).reverse() // Sort by newest + openings = await Promise.all(ids.map((id) => this.groupOpening(group, id))) } return openings } protected async hiringOpeningById(id: number | OpeningId): Promise { - const result = (await this._api.query.hiring.openingById(id)) as LinkageResult - return this.singleLinkageResult(result) + const result = await this._api.query.hiring.openingById(id) + return result } protected async hiringApplicationById(id: number | ApplicationId): Promise { - const result = (await this._api.query.hiring.applicationById(id)) as LinkageResult - return this.singleLinkageResult(result) + const result = await this._api.query.hiring.applicationById(id) + return result } async wgApplicationById(group: WorkingGroups, wgApplicationId: number): Promise { - const nextAppId = (await this.workingGroupApiQuery(group).nextApplicationId()) as ApplicationId + const nextAppId = await this.workingGroupApiQuery(group).nextApplicationId() if (wgApplicationId < 0 || wgApplicationId >= nextAppId.toNumber()) { throw new CLIError('Invalid working group application ID!') } - return this.singleLinkageResult( - (await this.workingGroupApiQuery(group).applicationById(wgApplicationId)) as LinkageResult - ) + const result = await this.workingGroupApiQuery(group).applicationById(wgApplicationId) + return result } protected async parseApplication(wgApplicationId: number, wgApplication: WGApplication): Promise { @@ -376,18 +354,15 @@ export default class Api { } protected async groupOpeningApplications(group: WorkingGroups, wgOpeningId: number): Promise { - const applications: GroupApplication[] = [] - - const nextAppId = (await this.workingGroupApiQuery(group).nextApplicationId()) as ApplicationId - for (let i = 0; i < nextAppId.toNumber(); i++) { - const wgApplication = await this.wgApplicationById(group, i) - if (wgApplication.opening_id.toNumber() !== wgOpeningId) { - continue - } - applications.push(await this.parseApplication(i, wgApplication)) - } + const wgApplicationEntries = await this.entriesByIds( + this.workingGroupApiQuery(group).applicationById + ) - return applications + return Promise.all( + wgApplicationEntries + .filter(([, /* id */ wgApplication]) => wgApplication.opening_id.eqn(wgOpeningId)) + .map(([id, wgApplication]) => this.parseApplication(id.toNumber(), wgApplication)) + ) } async groupOpening(group: WorkingGroups, wgOpeningId: number): Promise { @@ -397,9 +372,7 @@ export default class Api { throw new CLIError('Invalid working group opening ID!') } - const groupOpening = this.singleLinkageResult( - (await this.workingGroupApiQuery(group).openingById(wgOpeningId)) as LinkageResult - ) + const groupOpening = await this.workingGroupApiQuery(group).openingById(wgOpeningId) const openingId = groupOpening.hiring_opening_id.toNumber() const opening = await this.hiringOpeningById(openingId) @@ -417,19 +390,19 @@ export default class Api { sp.isSome ? unstakingPeriod(sp.unwrap()[key]) : 0 const unstakingPeriods: Partial = { - ['review_period_expired_application_stake_unstaking_period_length']: spUnstakingPeriod( + 'review_period_expired_application_stake_unstaking_period_length': spUnstakingPeriod( applSP, 'review_period_expired_unstaking_period_length' ), - ['crowded_out_application_stake_unstaking_period_length']: spUnstakingPeriod( + 'crowded_out_application_stake_unstaking_period_length': spUnstakingPeriod( applSP, 'crowded_out_unstaking_period_length' ), - ['review_period_expired_role_stake_unstaking_period_length']: spUnstakingPeriod( + 'review_period_expired_role_stake_unstaking_period_length': spUnstakingPeriod( roleSP, 'review_period_expired_unstaking_period_length' ), - ['crowded_out_role_stake_unstaking_period_length']: spUnstakingPeriod( + 'crowded_out_role_stake_unstaking_period_length': spUnstakingPeriod( roleSP, 'crowded_out_unstaking_period_length' ), @@ -493,11 +466,11 @@ export default class Api { } async getMemberIdsByControllerAccount(address: string): Promise { - const ids = (await this._api.query.members.memberIdsByControllerAccountId(address)) as Vec + const ids = await this._api.query.members.memberIdsByControllerAccountId>(address) return ids.toArray() } async workerExitRationaleConstraint(group: WorkingGroups): Promise { - return (await this.workingGroupApiQuery(group).workerExitRationaleText()) as InputValidationLengthConstraint + return await this.workingGroupApiQuery(group).workerExitRationaleText() } } diff --git a/cli/src/Types.ts b/cli/src/Types.ts index f82174d038..5f9b1bfa30 100644 --- a/cli/src/Types.ts +++ b/cli/src/Types.ts @@ -5,7 +5,7 @@ import { Constructor, Codec } from '@polkadot/types/types' import { Struct, Vec } from '@polkadot/types/codec' import { u32 } from '@polkadot/types/primitive' import { BlockNumber, Balance, AccountId } from '@polkadot/types/interfaces' -import { DerivedBalances } from '@polkadot/api-derive/types' +import { DeriveBalancesAll } from '@polkadot/api-derive/types' import { KeyringPair } from '@polkadot/keyring/types' import { WorkerId, OpeningType } from '@joystream/types/working-group' import { Membership, MemberId } from '@joystream/types/members' @@ -25,6 +25,7 @@ import { import ajv from 'ajv' import { Opening, StakingPolicy, ApplicationStageKeys } from '@joystream/types/hiring' import { Validator } from 'inquirer' +import { JoyStructCustom } from '@joystream/types/common' // KeyringPair type extended with mandatory "meta.name" // It's used for accounts/keys management within CLI. @@ -37,7 +38,7 @@ export type NamedKeyringPair = KeyringPair & { // Summary of the account information fetched from the api for "account:current" purposes (currently just balances) export type AccountSummary = { - balances: DerivedBalances + balances: DeriveBalancesAll } // This function allows us to easily transform the tuple into the object @@ -186,187 +187,174 @@ export type GroupOpening = { // Note those types are not part of the runtime etc., we just use them to simplify prompting for values // (since there exists functionality that handles that for substrate types like: Struct, Vec etc.) interface WithJSONable { - toJSON: () => T + toJSONObj: () => T } -export class HRTJobSpecificsStruct extends Struct implements WithJSONable { - constructor(value?: JobSpecifics) { - super( - { - title: 'Text', - description: 'Text', - }, - value - ) - } +export class HRTJobSpecificsStruct + extends JoyStructCustom({ + title: Text, + description: Text, + }) + implements WithJSONable { get title(): string { - return (this.get('title') as Text).toString() + return this.getField('title').toString() } + get description(): string { - return (this.get('description') as Text).toString() + return this.getField('description').toString() } - toJSON(): JobSpecifics { + + toJSONObj(): JobSpecifics { const { title, description } = this return { title, description } } } -export class HRTEntryInMembershipModukeStruct extends Struct implements WithJSONable { - constructor(value?: EntryInMembershipModuke) { - super( - { - handle: 'Text', - }, - value - ) - } +export class HRTEntryInMembershipModukeStruct + extends JoyStructCustom({ + handle: Text, + }) + implements WithJSONable { get handle(): string { - return (this.get('handle') as Text).toString() + return this.getField('handle').toString() } - toJSON(): EntryInMembershipModuke { + + toJSONObj(): EntryInMembershipModuke { const { handle } = this return { handle } } } -export class HRTCreatorDetailsStruct extends Struct implements WithJSONable { - constructor(value?: CreatorDetails) { - super( - { - membership: HRTEntryInMembershipModukeStruct, - }, - value - ) - } +export class HRTCreatorDetailsStruct + extends JoyStructCustom({ + membership: HRTEntryInMembershipModukeStruct, + }) + implements WithJSONable { get membership(): EntryInMembershipModuke { - return (this.get('membership') as HRTEntryInMembershipModukeStruct).toJSON() + return this.getField('membership').toJSONObj() } - toJSON(): CreatorDetails { + + toJSONObj(): CreatorDetails { const { membership } = this return { membership } } } -export class HRTHiringProcessStruct extends Struct implements WithJSONable { - constructor(value?: HiringProcess) { - super( - { - details: 'Vec', - }, - value - ) - } +export class HRTHiringProcessStruct + extends JoyStructCustom({ + details: Vec.with(Text), + }) + implements WithJSONable { get details(): AdditionalRolehiringProcessDetails { - return (this.get('details') as Vec).toArray().map((v) => v.toString()) + return this.getField('details') + .toArray() + .map((v) => v.toString()) } - toJSON(): HiringProcess { + + toJSONObj(): HiringProcess { const { details } = this return { details } } } -export class HRTQuestionFieldStruct extends Struct implements WithJSONable { - constructor(value?: QuestionField) { - super( - { - title: 'Text', - type: 'Text', - }, - value - ) - } +export class HRTQuestionFieldStruct + extends JoyStructCustom({ + title: Text, + type: Text, + }) + implements WithJSONable { get title(): string { - return (this.get('title') as Text).toString() + return this.getField('title').toString() } + get type(): string { - return (this.get('type') as Text).toString() + return this.getField('type').toString() } - toJSON(): QuestionField { + + toJSONObj(): QuestionField { const { title, type } = this return { title, type } } } class HRTQuestionsFieldsVec extends Vec.with(HRTQuestionFieldStruct) implements WithJSONable { - toJSON(): QuestionsFields { - return this.toArray().map((v) => v.toJSON()) + toJSONObj(): QuestionsFields { + return this.toArray().map((v) => v.toJSONObj()) } } -export class HRTQuestionSectionStruct extends Struct implements WithJSONable { - constructor(value?: QuestionSection) { - super( - { - title: 'Text', - questions: HRTQuestionsFieldsVec, - }, - value - ) - } +export class HRTQuestionSectionStruct + extends JoyStructCustom({ + title: Text, + questions: HRTQuestionsFieldsVec, + }) + implements WithJSONable { get title(): string { - return (this.get('title') as Text).toString() + return this.getField('title').toString() } + get questions(): QuestionsFields { - return (this.get('questions') as HRTQuestionsFieldsVec).toJSON() + return this.getField('questions').toJSONObj() } - toJSON(): QuestionSection { + + toJSONObj(): QuestionSection { const { title, questions } = this return { title, questions } } } export class HRTQuestionSectionsVec extends Vec.with(HRTQuestionSectionStruct) implements WithJSONable { - toJSON(): QuestionSections { - return this.toArray().map((v) => v.toJSON()) + toJSONObj(): QuestionSections { + return this.toArray().map((v) => v.toJSONObj()) } } -export class HRTApplicationDetailsStruct extends Struct implements WithJSONable { - constructor(value?: ApplicationDetails) { - super( - { - sections: HRTQuestionSectionsVec, - }, - value - ) - } +export class HRTApplicationDetailsStruct + extends JoyStructCustom({ + sections: HRTQuestionSectionsVec, + }) + implements WithJSONable { get sections(): QuestionSections { - return (this.get('sections') as HRTQuestionSectionsVec).toJSON() + return this.getField('sections').toJSONObj() } - toJSON(): ApplicationDetails { + + toJSONObj(): ApplicationDetails { const { sections } = this return { sections } } } -export class HRTStruct extends Struct implements WithJSONable { - constructor(value?: GenericJoyStreamRoleSchema) { - super( - { - version: 'u32', - headline: 'Text', - job: HRTJobSpecificsStruct, - application: HRTApplicationDetailsStruct, - reward: 'Text', - creator: HRTCreatorDetailsStruct, - process: HRTHiringProcessStruct, - }, - value - ) - } +export class HRTStruct + extends JoyStructCustom({ + version: u32, + headline: Text, + job: HRTJobSpecificsStruct, + application: HRTApplicationDetailsStruct, + reward: Text, + creator: HRTCreatorDetailsStruct, + process: HRTHiringProcessStruct, + }) + implements WithJSONable { get version(): number { - return (this.get('version') as u32).toNumber() + return this.getField('version').toNumber() } + get headline(): string { - return (this.get('headline') as Text).toString() + return this.getField('headline').toString() } + get job(): JobSpecifics { - return (this.get('job') as HRTJobSpecificsStruct).toJSON() + return this.getField('job').toJSONObj() } + get application(): ApplicationDetails { - return (this.get('application') as HRTApplicationDetailsStruct).toJSON() + return this.getField('application').toJSONObj() } + get reward(): string { - return (this.get('reward') as Text).toString() + return this.getField('reward').toString() } + get creator(): CreatorDetails { - return (this.get('creator') as HRTCreatorDetailsStruct).toJSON() + return this.getField('creator').toJSONObj() } + get process(): HiringProcess { - return (this.get('process') as HRTHiringProcessStruct).toJSON() + return this.getField('process').toJSONObj() } - toJSON(): GenericJoyStreamRoleSchema { + + toJSONObj(): GenericJoyStreamRoleSchema { const { version, headline, job, application, reward, creator, process } = this return { version, headline, job, application, reward, creator, process } } diff --git a/cli/src/base/AccountsCommandBase.ts b/cli/src/base/AccountsCommandBase.ts index ad172098d5..72b30e027f 100644 --- a/cli/src/base/AccountsCommandBase.ts +++ b/cli/src/base/AccountsCommandBase.ts @@ -8,7 +8,7 @@ import ApiCommandBase from './ApiCommandBase' import { Keyring } from '@polkadot/api' import { formatBalance } from '@polkadot/util' import { NamedKeyringPair } from '../Types' -import { DerivedBalances } from '@polkadot/api-derive/types' +import { DeriveBalancesAll } from '@polkadot/api-derive/types' import { toFixedLength } from '../helpers/display' const ACCOUNTS_DIRNAME = 'accounts' @@ -54,7 +54,9 @@ export default abstract class AccountsCommandBase extends ApiCommandBase { const keyring = new Keyring({ type: 'sr25519' }) keyring.addFromUri('//Alice', { name: 'Alice' }) keyring.addFromUri('//Bob', { name: 'Bob' }) - keyring.getPairs().forEach((pair) => this.saveAccount({ ...pair, meta: { name: pair.meta.name } }, '', true)) + keyring + .getPairs() + .forEach((pair) => this.saveAccount({ ...pair, meta: { name: pair.meta.name as string } }, '', true)) } fetchAccountFromJsonFile(jsonBackupFilePath: string): NamedKeyringPair { @@ -186,7 +188,7 @@ export default abstract class AccountsCommandBase extends ApiCommandBase { message = 'Select an account', showBalances = true ): Promise { - let balances: DerivedBalances[] + let balances: DeriveBalancesAll[] if (showBalances) { balances = await this.getApi().getAccountsBalancesInfo(accounts.map((acc) => acc.address)) } diff --git a/cli/src/base/ApiCommandBase.ts b/cli/src/base/ApiCommandBase.ts index 0c5166c94d..5333369d60 100644 --- a/cli/src/base/ApiCommandBase.ts +++ b/cli/src/base/ApiCommandBase.ts @@ -2,13 +2,14 @@ import ExitCodes from '../ExitCodes' import { CLIError } from '@oclif/errors' import StateAwareCommandBase from './StateAwareCommandBase' import Api from '../Api' -import { getTypeDef, createType, Option, Tuple, Bytes } from '@polkadot/types' -import { Codec, TypeDef, TypeDefInfo, Constructor } from '@polkadot/types/types' +import { getTypeDef, Option, Tuple, Bytes } from '@polkadot/types' +import { Registry, Codec, CodecArg, TypeDef, TypeDefInfo, Constructor } from '@polkadot/types/types' + import { Vec, Struct, Enum } from '@polkadot/types/codec' import { ApiPromise, WsProvider } from '@polkadot/api' import { KeyringPair } from '@polkadot/keyring/types' import chalk from 'chalk' -import { SubmittableResultImpl } from '@polkadot/api/types' +import { InterfaceTypes } from '@polkadot/types/types/registry' import ajv from 'ajv' import { ApiMethodArg, ApiMethodNamedArgs, ApiParamsOptions, ApiParamOptions } from '../Types' import { createParamOptions } from '../helpers/promptOptions' @@ -32,6 +33,14 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { return this.getApi().getOriginalApi() } + getTypesRegistry(): Registry { + return this.getOriginalApi().registry + } + + createType(typeName: K, value?: unknown): InterfaceTypes[K] { + return this.getOriginalApi().createType(typeName, value) + } + async init() { await super.init() let apiUri: string = this.getPreservedState().apiUri @@ -81,6 +90,7 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { isApiUriValid(uri: string) { try { + // eslint-disable-next-line no-new new WsProvider(uri) } catch (e) { return false @@ -90,8 +100,8 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { // This is needed to correctly handle some structs, enums etc. // Where the main typeDef doesn't provide enough information - protected getRawTypeDef(type: string) { - const instance = createType(type as any) + protected getRawTypeDef(type: keyof InterfaceTypes) { + const instance = this.createType(type) return getTypeDef(instance.toRawType()) } @@ -120,7 +130,7 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { async promptForSimple(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise { // If no default provided - get default value resulting from providing empty string const defaultValueString = - paramOptions?.value?.default?.toString() || createType(typeDef.type as any, '').toString() + paramOptions?.value?.default?.toString() || this.createType(typeDef.type as any, '').toString() const providedValue = await this.simplePrompt({ message: `Provide value for ${this.paramName(typeDef)}`, type: 'input', @@ -129,7 +139,7 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { default: (defaultValueString === '0x' ? '' : defaultValueString) || undefined, validate: paramOptions?.validator, }) - return createType(typeDef.type as any, providedValue) + return this.createType(typeDef.type as any, providedValue) } // Prompt for Option value @@ -149,10 +159,10 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { createParamOptions(subtype.name, defaultValue?.unwrapOr(undefined)) ) this.closeIndentGroup() - return new Option(subtype.type as any, value) + return this.createType(`Option<${subtype.type}>` as any, value) } - return new Option(subtype.type as any, null) + return this.createType(`Option<${subtype.type}>` as any, null) } // Prompt for Tuple @@ -173,7 +183,7 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { } this.closeIndentGroup() - return new Tuple(subtypes.map((subtype) => subtype.type) as any, result) + return new Tuple(this.getTypesRegistry(), subtypes.map((subtype) => subtype.type) as any, result) } // Prompt for Struct @@ -182,7 +192,7 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { this.openIndentGroup() const structType = typeDef.type - const rawTypeDef = this.getRawTypeDef(structType) + const rawTypeDef = this.getRawTypeDef(structType as keyof InterfaceTypes) // We assume struct typeDef always has array of typeDefs inside ".sub" const structSubtypes = rawTypeDef.sub as TypeDef[] const structDefault = paramOptions?.value?.default as Struct | undefined @@ -200,7 +210,7 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { } this.closeIndentGroup() - return createType(structType as any, structValues) + return this.createType(structType as any, structValues) } // Prompt for Vec @@ -228,12 +238,12 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { } while (addAnother) this.closeIndentGroup() - return new Vec(subtype.type as any, entries) + return this.createType(`Vec<${subtype.type}>` as any, entries) } // Prompt for Enum async promptForEnum(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise { - const enumType = typeDef.type + const enumType = typeDef.type as keyof InterfaceTypes const rawTypeDef = this.getRawTypeDef(enumType) // We assume enum always has array on TypeDefs inside ".sub" const enumSubtypes = rawTypeDef.sub as TypeDef[] @@ -253,12 +263,12 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { if (enumSubtype.type !== 'Null') { const subtypeOptions = createParamOptions(enumSubtype.name, defaultValue?.value) - return createType(enumType as any, { + return this.createType(enumType as any, { [enumSubtype.name!]: await this.promptForParam(enumSubtype.type, subtypeOptions), }) } - return createType(enumType as any, enumSubtype.name) + return this.createType(enumType as any, enumSubtype.name) } // Prompt for param based on "paramType" string (ie. Option) @@ -268,7 +278,7 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { paramOptions?: ApiParamOptions // TODO: This is not fully implemented for all types yet ): Promise { const typeDef = getTypeDef(paramType) - const rawTypeDef = this.getRawTypeDef(paramType) + const rawTypeDef = this.getRawTypeDef(paramType as keyof InterfaceTypes) if (paramOptions?.forcedName) { typeDef.name = paramOptions.forcedName @@ -309,18 +319,23 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { defaultValue?: Bytes, schemaValidator?: ajv.ValidateFunction ) { - const rawType = new jsonStruct().toRawType() + const JsonStructObject = jsonStruct + const rawType = new JsonStructObject(this.getTypesRegistry()).toRawType() const typeDef = getTypeDef(rawType) const defaultStruct = - defaultValue && new jsonStruct(JSON.parse(Buffer.from(defaultValue.toHex().replace('0x', ''), 'hex').toString())) + defaultValue && + new JsonStructObject( + this.getTypesRegistry(), + JSON.parse(Buffer.from(defaultValue.toHex().replace('0x', ''), 'hex').toString()) + ) if (argName) { typeDef.name = argName } - let isValid = true, - jsonText: string + let isValid = true + let jsonText: string do { const structVal = await this.promptForStruct(typeDef, createParamOptions(typeDef.name, defaultStruct)) jsonText = JSON.stringify(structVal.toJSON()) @@ -338,7 +353,7 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { } } while (!isValid) - return new Bytes('0x' + Buffer.from(jsonText, 'ascii').toString('hex')) + return this.createType('Bytes', '0x' + Buffer.from(jsonText, 'ascii').toString('hex')) } async promptForExtrinsicParams( @@ -364,18 +379,18 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { return values } - sendExtrinsic(account: KeyringPair, module: string, method: string, params: Codec[]) { + sendExtrinsic(account: KeyringPair, module: string, method: string, params: CodecArg[]) { return new Promise((resolve, reject) => { const extrinsicMethod = this.getOriginalApi().tx[module][method] let unsubscribe: () => void extrinsicMethod(...params) - .signAndSend(account, {}, (result: SubmittableResultImpl) => { + .signAndSend(account, {}, (result) => { // Implementation loosely based on /pioneer/packages/react-signer/src/Modal.tsx if (!result || !result.status) { return } - if (result.status.isFinalized) { + if (result.status.isInBlock) { unsubscribe() result.events .filter(({ event: { section } }): boolean => section === 'system') @@ -401,7 +416,7 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { account: KeyringPair, module: string, method: string, - params: Codec[], + params: CodecArg[], warnOnly = false // If specified - only warning will be displayed (instead of error beeing thrown) ) { try { @@ -449,7 +464,7 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase { const argName = arg.name.toString() const argType = arg.type.toString() try { - parsedArgs.push({ name: argName, value: createType(argType as any, draftJSONObj[parseInt(index)]) }) + parsedArgs.push({ name: argName, value: this.createType(argType as any, draftJSONObj[parseInt(index)]) }) } catch (e) { throw new CLIError(`Couldn't parse ${argName} value from draft at ${draftFilePath}!`, { exit: ExitCodes.InvalidFile, diff --git a/cli/src/base/WorkingGroupsCommandBase.ts b/cli/src/base/WorkingGroupsCommandBase.ts index 8a8d992dbd..4e993341f3 100644 --- a/cli/src/base/WorkingGroupsCommandBase.ts +++ b/cli/src/base/WorkingGroupsCommandBase.ts @@ -110,13 +110,13 @@ export default abstract class WorkingGroupsCommandBase extends AccountsCommandBa })), }) - return acceptedApplications + return acceptedApplications.sort() // Sort just in case, since runtime expects them to be sorted } async promptForNewOpeningDraftName() { - let draftName = '', - fileExists = false, - overrideConfirmed = false + let draftName = '' + let fileExists = false + let overrideConfirmed = false do { draftName = await this.simplePrompt({ diff --git a/cli/src/commands/account/current.ts b/cli/src/commands/account/current.ts index 93ceac8f02..2843df0974 100644 --- a/cli/src/commands/account/current.ts +++ b/cli/src/commands/account/current.ts @@ -1,6 +1,5 @@ import AccountsCommandBase from '../../base/AccountsCommandBase' import { AccountSummary, NameValueObj, NamedKeyringPair } from '../../Types' -import { DerivedBalances } from '@polkadot/api-derive/types' import { displayHeader, displayNameValueTable } from '../../helpers/display' import { formatBalance } from '@polkadot/util' import moment from 'moment' @@ -15,7 +14,7 @@ export default class AccountCurrent extends AccountsCommandBase { displayHeader('Account information') const creationDate: string = currentAccount.meta.whenCreated - ? moment(currentAccount.meta.whenCreated).format('YYYY-MM-DD HH:mm:ss') + ? moment(currentAccount.meta.whenCreated as string | number).format('YYYY-MM-DD HH:mm:ss') : '?' const accountRows: NameValueObj[] = [ { name: 'Account name:', value: currentAccount.meta.name }, @@ -25,7 +24,7 @@ export default class AccountCurrent extends AccountsCommandBase { displayNameValueTable(accountRows) displayHeader('Balances') - const balances: DerivedBalances = summary.balances + const balances = summary.balances const balancesRows: NameValueObj[] = [ { name: 'Total balance:', value: formatBalance(balances.votingBalance) }, { name: 'Transferable balance:', value: formatBalance(balances.availableBalance) }, diff --git a/cli/src/commands/account/transferTokens.ts b/cli/src/commands/account/transferTokens.ts index 95231775f6..30a47a6eb5 100644 --- a/cli/src/commands/account/transferTokens.ts +++ b/cli/src/commands/account/transferTokens.ts @@ -6,7 +6,6 @@ import { formatBalance } from '@polkadot/util' import { Hash } from '@polkadot/types/interfaces' import { NamedKeyringPair } from '../../Types' import { checkBalance, validateAddress } from '../../helpers/validation' -import { DerivedBalances } from '@polkadot/api-derive/types' type AccountTransferArgs = { recipient: string @@ -36,15 +35,16 @@ export default class AccountTransferTokens extends AccountsCommandBase { // Initial validation validateAddress(args.recipient, 'Invalid recipient address') - const accBalances: DerivedBalances = (await this.getApi().getAccountsBalancesInfo([selectedAccount.address]))[0] + const accBalances = (await this.getApi().getAccountsBalancesInfo([selectedAccount.address]))[0] checkBalance(accBalances, amountBN) await this.requestAccountDecoding(selectedAccount) this.log(chalk.white('Estimating fee...')) + const tx = await this.getApi().createTransferTx(args.recipient, amountBN) let estimatedFee: BN try { - estimatedFee = await this.getApi().estimateFee(selectedAccount, args.recipient, amountBN) + estimatedFee = await this.getApi().estimateFee(selectedAccount, tx) } catch (e) { this.error('Could not estimate the fee.', { exit: ExitCodes.UnexpectedException }) } @@ -57,7 +57,7 @@ export default class AccountTransferTokens extends AccountsCommandBase { await this.requireConfirmation('Do you confirm the transfer?') try { - const txHash: Hash = await this.getApi().transfer(selectedAccount, args.recipient, amountBN) + const txHash: Hash = await tx.signAndSend(selectedAccount) this.log(chalk.greenBright('Transaction succesfully sent!')) this.log(chalk.white('Hash:', txHash.toString())) } catch (e) { diff --git a/cli/src/commands/api/inspect.ts b/cli/src/commands/api/inspect.ts index 7ee1dcf887..41243c7970 100644 --- a/cli/src/commands/api/inspect.ts +++ b/cli/src/commands/api/inspect.ts @@ -2,9 +2,8 @@ import { flags } from '@oclif/command' import { CLIError } from '@oclif/errors' import { displayNameValueTable } from '../../helpers/display' import { ApiPromise } from '@polkadot/api' -import { Option } from '@polkadot/types' import { Codec } from '@polkadot/types/types' -import { ConstantCodec } from '@polkadot/api-metadata/consts/types' +import { ConstantCodec } from '@polkadot/metadata/Decorated/consts/types' import ExitCodes from '../../ExitCodes' import chalk from 'chalk' import { NameValueObj, ApiMethodArg } from '../../Types' @@ -99,7 +98,7 @@ export default class ApiInspect extends ApiCommandBase { return [type.asDoubleMap.key1.toString(), type.asDoubleMap.key2.toString()] } if (type.isMap) { - return type.asMap.linked.isTrue ? [`Option<${type.asMap.key.toString()}>`] : [type.asMap.key.toString()] + return [type.asMap.key.toString()] } return [] } @@ -110,14 +109,17 @@ export default class ApiInspect extends ApiCommandBase { const { meta: { type, modifier }, } = method.creator + let typeName = type.toString() if (type.isDoubleMap) { - return type.asDoubleMap.value.toString() + typeName = type.asDoubleMap.value.toString() } - if (modifier.isOptional) { - return `Option<${type.toString()}>` + if (type.isMap) { + typeName = type.asMap.value.toString() } + + return modifier.isOptional ? `Option<${typeName}>` : typeName } - // Fallback for "query" and default for "consts" + // Fallback for "consts" return this.getMethodMeta(apiType, apiModule, apiMethod).type.toString() } @@ -127,7 +129,7 @@ export default class ApiInspect extends ApiCommandBase { api: ApiPromise, flags: ApiInspectFlags ): { apiType: ApiType | undefined; apiModule: string | undefined; apiMethod: string | undefined } { - let apiType: ApiType | undefined = undefined + let apiType: ApiType | undefined const { module: apiModule, method: apiMethod } = flags if (flags.type !== undefined) { @@ -155,12 +157,7 @@ export default class ApiInspect extends ApiCommandBase { for (const [key, paramType] of Object.entries(paramTypes)) { this.log(chalk.bold.white(`Parameter no. ${parseInt(key) + 1} (${paramType}):`)) const paramValue = await this.promptForParam(paramType) - if (paramValue instanceof Option && paramValue.isSome) { - result.push(paramValue.unwrap()) - } else if (!(paramValue instanceof Option)) { - result.push(paramValue) - } - // In case of empty option we MUST NOT add anything to the array (otherwise it causes some error) + result.push(paramValue) } return result diff --git a/cli/src/commands/working-groups/application.ts b/cli/src/commands/working-groups/application.ts index bff68b9eda..89ffcc75c4 100644 --- a/cli/src/commands/working-groups/application.ts +++ b/cli/src/commands/working-groups/application.ts @@ -11,6 +11,7 @@ export default class WorkingGroupsApplication extends WorkingGroupsCommandBase { description: 'Working Group Application ID', }, ] + static flags = { ...WorkingGroupsCommandBase.flags, } diff --git a/cli/src/commands/working-groups/createOpening.ts b/cli/src/commands/working-groups/createOpening.ts index 6c11f91b0b..7c5cf43199 100644 --- a/cli/src/commands/working-groups/createOpening.ts +++ b/cli/src/commands/working-groups/createOpening.ts @@ -53,8 +53,8 @@ export default class WorkingGroupsCreateOpening extends WorkingGroupsCommandBase const module = apiModuleByGroup[this.group] const method = 'addOpening' - let saveDraft = false, - params: ApiMethodArg[] + let saveDraft = false + let params: ApiMethodArg[] if (flags.createDraftOnly) { params = await this.promptForExtrinsicParams(module, method, promptOptions) saveDraft = true diff --git a/cli/src/commands/working-groups/decreaseWorkerStake.ts b/cli/src/commands/working-groups/decreaseWorkerStake.ts index 4208bc79a2..50924bdc50 100644 --- a/cli/src/commands/working-groups/decreaseWorkerStake.ts +++ b/cli/src/commands/working-groups/decreaseWorkerStake.ts @@ -1,6 +1,5 @@ import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase' import { apiModuleByGroup } from '../../Api' -import { WorkerId } from '@joystream/types/working-group' import { Balance } from '@polkadot/types/interfaces' import { formatBalance } from '@polkadot/util' import { minMaxInt } from '../../validators/common' @@ -11,6 +10,7 @@ export default class WorkingGroupsDecreaseWorkerStake extends WorkingGroupsComma static description = 'Decreases given worker stake by an amount that will be returned to the worker role account. ' + 'Requires lead access.' + static args = [ { name: 'workerId', @@ -18,6 +18,7 @@ export default class WorkingGroupsDecreaseWorkerStake extends WorkingGroupsComma description: 'Worker ID', }, ] + static flags = { ...WorkingGroupsCommandBase.flags, } @@ -41,10 +42,7 @@ export default class WorkingGroupsDecreaseWorkerStake extends WorkingGroupsComma await this.requestAccountDecoding(account) - await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'decreaseStake', [ - new WorkerId(workerId), - balance, - ]) + await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'decreaseStake', [workerId, balance]) this.log( chalk.green( diff --git a/cli/src/commands/working-groups/evictWorker.ts b/cli/src/commands/working-groups/evictWorker.ts index 961e2618e1..0b3990310b 100644 --- a/cli/src/commands/working-groups/evictWorker.ts +++ b/cli/src/commands/working-groups/evictWorker.ts @@ -1,7 +1,5 @@ import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase' import { apiModuleByGroup } from '../../Api' -import { WorkerId } from '@joystream/types/working-group' -import { bool } from '@polkadot/types/primitive' import { formatBalance } from '@polkadot/util' import chalk from 'chalk' import { createParamOptions } from '../../helpers/promptOptions' @@ -15,6 +13,7 @@ export default class WorkingGroupsEvictWorker extends WorkingGroupsCommandBase { description: 'Worker ID', }, ] + static flags = { ...WorkingGroupsCommandBase.flags, } @@ -43,9 +42,9 @@ export default class WorkingGroupsEvictWorker extends WorkingGroupsCommandBase { await this.requestAccountDecoding(account) await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'terminateRole', [ - new WorkerId(workerId), + workerId, rationale, - new bool(shouldSlash), + shouldSlash, ]) this.log(chalk.green(`Worker ${chalk.white(workerId)} has been evicted!`)) diff --git a/cli/src/commands/working-groups/fillOpening.ts b/cli/src/commands/working-groups/fillOpening.ts index 9d3d42361c..117c19579b 100644 --- a/cli/src/commands/working-groups/fillOpening.ts +++ b/cli/src/commands/working-groups/fillOpening.ts @@ -1,8 +1,6 @@ import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase' import { OpeningStatus } from '../../Types' import { apiModuleByGroup } from '../../Api' -import { OpeningId } from '@joystream/types/hiring' -import { ApplicationIdSet, RewardPolicy } from '@joystream/types/working-group' import chalk from 'chalk' import { createParamOptions } from '../../helpers/promptOptions' @@ -15,6 +13,7 @@ export default class WorkingGroupsFillOpening extends WorkingGroupsCommandBase { description: 'Working Group Opening ID', }, ] + static flags = { ...WorkingGroupsCommandBase.flags, } @@ -30,16 +29,13 @@ export default class WorkingGroupsFillOpening extends WorkingGroupsCommandBase { const opening = await this.getOpeningForLeadAction(openingId, OpeningStatus.InReview) const applicationIds = await this.promptForApplicationsToAccept(opening) - const rewardPolicyOpt = await this.promptForParam( - `Option<${RewardPolicy.name}>`, - createParamOptions('RewardPolicy') - ) + const rewardPolicyOpt = await this.promptForParam(`Option`, createParamOptions('RewardPolicy')) await this.requestAccountDecoding(account) await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'fillOpening', [ - new OpeningId(openingId), - new ApplicationIdSet(applicationIds), + openingId, + applicationIds, rewardPolicyOpt, ]) diff --git a/cli/src/commands/working-groups/opening.ts b/cli/src/commands/working-groups/opening.ts index 3ac2411546..9dfe75d01e 100644 --- a/cli/src/commands/working-groups/opening.ts +++ b/cli/src/commands/working-groups/opening.ts @@ -15,6 +15,7 @@ export default class WorkingGroupsOpening extends WorkingGroupsCommandBase { description: 'Working Group Opening ID', }, ] + static flags = { ...WorkingGroupsCommandBase.flags, } diff --git a/cli/src/commands/working-groups/slashWorker.ts b/cli/src/commands/working-groups/slashWorker.ts index 3e7b2629c9..f14e4ed790 100644 --- a/cli/src/commands/working-groups/slashWorker.ts +++ b/cli/src/commands/working-groups/slashWorker.ts @@ -1,6 +1,5 @@ import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase' import { apiModuleByGroup } from '../../Api' -import { WorkerId } from '@joystream/types/working-group' import { Balance } from '@polkadot/types/interfaces' import { formatBalance } from '@polkadot/util' import { minMaxInt } from '../../validators/common' @@ -16,6 +15,7 @@ export default class WorkingGroupsSlashWorker extends WorkingGroupsCommandBase { description: 'Worker ID', }, ] + static flags = { ...WorkingGroupsCommandBase.flags, } @@ -39,10 +39,7 @@ export default class WorkingGroupsSlashWorker extends WorkingGroupsCommandBase { await this.requestAccountDecoding(account) - await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'slashStake', [ - new WorkerId(workerId), - balance, - ]) + await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'slashStake', [workerId, balance]) this.log( chalk.green( diff --git a/cli/src/commands/working-groups/startAcceptingApplications.ts b/cli/src/commands/working-groups/startAcceptingApplications.ts index 6dad081152..92907c4bbb 100644 --- a/cli/src/commands/working-groups/startAcceptingApplications.ts +++ b/cli/src/commands/working-groups/startAcceptingApplications.ts @@ -1,7 +1,6 @@ import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase' import { OpeningStatus } from '../../Types' import { apiModuleByGroup } from '../../Api' -import { OpeningId } from '@joystream/types/hiring' import chalk from 'chalk' export default class WorkingGroupsStartAcceptingApplications extends WorkingGroupsCommandBase { @@ -13,6 +12,7 @@ export default class WorkingGroupsStartAcceptingApplications extends WorkingGrou description: 'Working Group Opening ID', }, ] + static flags = { ...WorkingGroupsCommandBase.flags, } @@ -29,9 +29,7 @@ export default class WorkingGroupsStartAcceptingApplications extends WorkingGrou await this.requestAccountDecoding(account) - await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'acceptApplications', [ - new OpeningId(openingId), - ]) + await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'acceptApplications', [openingId]) this.log( chalk.green(`Opening ${chalk.white(openingId)} status changed to: ${chalk.white('Accepting Applications')}`) diff --git a/cli/src/commands/working-groups/startReviewPeriod.ts b/cli/src/commands/working-groups/startReviewPeriod.ts index 3245effa65..d92c824578 100644 --- a/cli/src/commands/working-groups/startReviewPeriod.ts +++ b/cli/src/commands/working-groups/startReviewPeriod.ts @@ -1,7 +1,6 @@ import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase' import { OpeningStatus } from '../../Types' import { apiModuleByGroup } from '../../Api' -import { OpeningId } from '@joystream/types/hiring' import chalk from 'chalk' export default class WorkingGroupsStartReviewPeriod extends WorkingGroupsCommandBase { @@ -13,6 +12,7 @@ export default class WorkingGroupsStartReviewPeriod extends WorkingGroupsCommand description: 'Working Group Opening ID', }, ] + static flags = { ...WorkingGroupsCommandBase.flags, } @@ -29,9 +29,7 @@ export default class WorkingGroupsStartReviewPeriod extends WorkingGroupsCommand await this.requestAccountDecoding(account) - await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'beginApplicantReview', [ - new OpeningId(openingId), - ]) + await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'beginApplicantReview', [openingId]) this.log(chalk.green(`Opening ${chalk.white(openingId)} status changed to: ${chalk.white('In Review')}`)) } diff --git a/cli/src/commands/working-groups/terminateApplication.ts b/cli/src/commands/working-groups/terminateApplication.ts index 8d33d7128c..683893fd6c 100644 --- a/cli/src/commands/working-groups/terminateApplication.ts +++ b/cli/src/commands/working-groups/terminateApplication.ts @@ -1,6 +1,6 @@ import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase' import { apiModuleByGroup } from '../../Api' -import { ApplicationStageKeys, ApplicationId } from '@joystream/types/hiring' +import { ApplicationStageKeys } from '@joystream/types/hiring' import chalk from 'chalk' export default class WorkingGroupsTerminateApplication extends WorkingGroupsCommandBase { @@ -12,6 +12,7 @@ export default class WorkingGroupsTerminateApplication extends WorkingGroupsComm description: 'Working Group Application ID', }, ] + static flags = { ...WorkingGroupsCommandBase.flags, } @@ -29,9 +30,7 @@ export default class WorkingGroupsTerminateApplication extends WorkingGroupsComm await this.requestAccountDecoding(account) - await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'terminateApplication', [ - new ApplicationId(applicationId), - ]) + await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'terminateApplication', [applicationId]) this.log(chalk.green(`Application ${chalk.white(applicationId)} has been succesfully terminated!`)) } diff --git a/cli/src/commands/working-groups/updateRewardAccount.ts b/cli/src/commands/working-groups/updateRewardAccount.ts index cb65fdd96c..cef8fc41e3 100644 --- a/cli/src/commands/working-groups/updateRewardAccount.ts +++ b/cli/src/commands/working-groups/updateRewardAccount.ts @@ -1,7 +1,6 @@ import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase' import { apiModuleByGroup } from '../../Api' import { validateAddress } from '../../helpers/validation' -import { GenericAccountId } from '@polkadot/types' import chalk from 'chalk' import ExitCodes from '../../ExitCodes' @@ -14,6 +13,7 @@ export default class WorkingGroupsUpdateRewardAccount extends WorkingGroupsComma description: 'New reward account address (if omitted, one of the existing CLI accounts can be selected)', }, ] + static flags = { ...WorkingGroupsCommandBase.flags, } @@ -40,7 +40,7 @@ export default class WorkingGroupsUpdateRewardAccount extends WorkingGroupsComma await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'updateRewardAccount', [ worker.workerId, - new GenericAccountId(newRewardAccount), + newRewardAccount, ]) this.log(chalk.green(`Succesfully updated the reward account to: ${chalk.white(newRewardAccount)})`)) diff --git a/cli/src/commands/working-groups/updateRoleAccount.ts b/cli/src/commands/working-groups/updateRoleAccount.ts index a584d21423..38ba8e9edc 100644 --- a/cli/src/commands/working-groups/updateRoleAccount.ts +++ b/cli/src/commands/working-groups/updateRoleAccount.ts @@ -1,7 +1,6 @@ import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase' import { apiModuleByGroup } from '../../Api' import { validateAddress } from '../../helpers/validation' -import { GenericAccountId } from '@polkadot/types' import chalk from 'chalk' export default class WorkingGroupsUpdateRoleAccount extends WorkingGroupsCommandBase { @@ -13,6 +12,7 @@ export default class WorkingGroupsUpdateRoleAccount extends WorkingGroupsCommand description: 'New role account address (if omitted, one of the existing CLI accounts can be selected)', }, ] + static flags = { ...WorkingGroupsCommandBase.flags, } @@ -34,7 +34,7 @@ export default class WorkingGroupsUpdateRoleAccount extends WorkingGroupsCommand await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'updateRoleAccount', [ worker.workerId, - new GenericAccountId(newRoleAccount), + newRoleAccount, ]) this.log(chalk.green(`Succesfully updated the role account to: ${chalk.white(newRoleAccount)})`)) diff --git a/cli/src/commands/working-groups/updateWorkerReward.ts b/cli/src/commands/working-groups/updateWorkerReward.ts index d6421eb5bf..ac55892611 100644 --- a/cli/src/commands/working-groups/updateWorkerReward.ts +++ b/cli/src/commands/working-groups/updateWorkerReward.ts @@ -1,6 +1,5 @@ import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase' import { apiModuleByGroup } from '../../Api' -import { WorkerId } from '@joystream/types/working-group' import { formatBalance } from '@polkadot/util' import chalk from 'chalk' import { Reward } from '../../Types' @@ -17,6 +16,7 @@ export default class WorkingGroupsUpdateWorkerReward extends WorkingGroupsComman description: 'Worker ID', }, ] + static flags = { ...WorkingGroupsCommandBase.flags, } @@ -56,7 +56,7 @@ export default class WorkingGroupsUpdateWorkerReward extends WorkingGroupsComman await this.requestAccountDecoding(account) await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'updateRewardAmount', [ - new WorkerId(workerId), + workerId, newRewardValue, ]) diff --git a/cli/src/helpers/validation.ts b/cli/src/helpers/validation.ts index 0cd9c1f67a..333b9b2c74 100644 --- a/cli/src/helpers/validation.ts +++ b/cli/src/helpers/validation.ts @@ -1,7 +1,7 @@ import BN from 'bn.js' import ExitCodes from '../ExitCodes' import { decodeAddress } from '@polkadot/util-crypto' -import { DerivedBalances } from '@polkadot/api-derive/types' +import { DeriveBalancesAll } from '@polkadot/api-derive/types' import { CLIError } from '@oclif/errors' export function validateAddress(address: string, errorMessage = 'Invalid address'): void { @@ -12,7 +12,7 @@ export function validateAddress(address: string, errorMessage = 'Invalid address } } -export function checkBalance(accBalances: DerivedBalances, requiredBalance: BN): void { +export function checkBalance(accBalances: DeriveBalancesAll, requiredBalance: BN): void { if (requiredBalance.gt(accBalances.availableBalance)) { throw new CLIError('Not enough balance available', { exit: ExitCodes.InvalidInput }) } diff --git a/cli/src/promptOptions/addWorkerOpening.ts b/cli/src/promptOptions/addWorkerOpening.ts index 4b901a01b6..505f9d2d62 100644 --- a/cli/src/promptOptions/addWorkerOpening.ts +++ b/cli/src/promptOptions/addWorkerOpening.ts @@ -1,32 +1,32 @@ import { ApiParamsOptions, ApiParamOptions, HRTStruct } from '../Types' -import { - OpeningType, - SlashingTerms, - UnslashableTerms, - OpeningType_Worker as OpeningTypeWorker, - WorkingGroupOpeningPolicyCommitment, -} from '@joystream/types/working-group' +import { OpeningType, WorkingGroupOpeningPolicyCommitment } from '@joystream/types/working-group' +import { SlashingTerms } from '@joystream/types/common' import { Bytes } from '@polkadot/types' import { schemaValidator } from '@joystream/types/hiring' +import { createMock } from '@joystream/types' class OpeningPolicyCommitmentOptions implements ApiParamsOptions { [paramName: string]: ApiParamOptions public role_slashing_terms: ApiParamOptions = { value: { - default: SlashingTerms.create('Unslashable', new UnslashableTerms()), + default: createMock('SlashingTerms', { Unslashable: null }), locked: true, }, } + // Rename fields containing "curator" (solivg minor UI issue related to flat namespace) public terminate_curator_application_stake_unstaking_period: ApiParamOptions = { forcedName: 'terminate_application_stake_unstaking_period', } + public terminate_curator_role_stake_unstaking_period: ApiParamOptions = { forcedName: 'terminate_role_stake_unstaking_period', } + public exit_curator_role_application_stake_unstaking_period: ApiParamOptions = { forcedName: 'exit_role_application_stake_unstaking_period', } + public exit_curator_role_stake_unstaking_period: ApiParamOptions = { forcedName: 'exit_role_stake_unstaking_period', } @@ -37,10 +37,11 @@ class AddWrokerOpeningOptions implements ApiParamsOptions { // Lock value for opening_type public opening_type: ApiParamOptions = { value: { - default: OpeningType.create('Worker', new OpeningTypeWorker()), + default: createMock('OpeningType', { Worker: null }), locked: true, }, } + // Json schema for human_readable_text public human_readable_text: ApiParamOptions = { jsonSchema: { @@ -48,6 +49,7 @@ class AddWrokerOpeningOptions implements ApiParamsOptions { struct: HRTStruct, }, } + // Lock value for role_slashing_terms public commitment: ApiParamOptions = { nestedOptions: new OpeningPolicyCommitmentOptions(), diff --git a/cli/tsconfig.json b/cli/tsconfig.json index 0735d6c692..5d2ca733f1 100644 --- a/cli/tsconfig.json +++ b/cli/tsconfig.json @@ -9,7 +9,11 @@ "target": "es2017", "esModuleInterop": true, "types" : [ "node" ], - "noUnusedLocals": true + "noUnusedLocals": true, + "baseUrl": ".", + "paths": { + "@polkadot/types/augment": ["../types/augment-codec/augment-types.ts"], + } }, "include": [ "src/**/*" diff --git a/types/src/index.ts b/types/src/index.ts index f934f24a33..a70817712d 100644 --- a/types/src/index.ts +++ b/types/src/index.ts @@ -15,6 +15,8 @@ import workingGroup from './working-group' import discovery from './discovery' import media from './media' import proposals from './proposals' +import { InterfaceTypes } from '@polkadot/types/types/registry' +import { createType, TypeRegistry } from '@polkadot/types' export { common, @@ -58,3 +60,14 @@ export const types: RegistryTypes = { Address: 'AccountId', LookupSource: 'AccountId', } + +// Allows creating types without api instance (it's not a recommended way though, so should be used just for mocks) +export const mockRegistry = new TypeRegistry() +mockRegistry.register(types) + +export function createMock( + type: TypeName, + value: any +): InterfaceTypes[TypeName] { + return createType(mockRegistry, type, value) +} diff --git a/yarn.lock b/yarn.lock index 6f75c9758d..07b1a722a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11565,7 +11565,7 @@ find-babel-config@^1.2.0: json5 "^0.5.1" path-exists "^3.0.0" -find-cache-dir@^2.1.0: +find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== @@ -19164,7 +19164,7 @@ pirates@^3.0.2: dependencies: node-modules-regexp "^1.0.0" -pirates@^4.0.1: +pirates@^4.0.0, pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==