diff --git a/.github/workflows/joystream-cli.yml b/.github/workflows/joystream-cli.yml index 5e56c70913..71537074c1 100644 --- a/.github/workflows/joystream-cli.yml +++ b/.github/workflows/joystream-cli.yml @@ -18,12 +18,11 @@ jobs: run: | yarn install --frozen-lockfile yarn workspace @joystream/cli checks - - name: npm pack test + - name: yarn pack test run: | - cd cli - npm pack | tail -1 | xargs tar xzf - cd package && npm link - joystream-cli help + yarn workspace @joystream/cli pack --filename cli-pack-test.tgz + tar zxvf ./cli/cli-pack-test.tgz -C cli + cd ./cli/package && yarn link cli_build_osx: name: MacOS Checks @@ -41,9 +40,8 @@ jobs: run: | yarn install --frozen-lockfile --network-timeout 120000 yarn workspace @joystream/cli checks - - name: npm pack test + - name: yarn pack test run: | - cd cli - npm pack | tail -1 | xargs tar xzf - cd package && npm link - joystream-cli help + yarn workspace @joystream/cli pack --filename cli-pack-test.tgz + tar zxvf ./cli/cli-pack-test.tgz -C cli + cd ./cli/package && yarn link diff --git a/cli/README.md b/cli/README.md index 8dba9c5114..974725a1dc 100644 --- a/cli/README.md +++ b/cli/README.md @@ -244,9 +244,9 @@ EXAMPLES $ api:inspect $ api:inspect -t=query $ api:inspect -t=query -M=members - $ api:inspect -t=query -M=members -m=memberProfile - $ api:inspect -t=query -M=members -m=memberProfile -e - $ api:inspect -t=query -M=members -m=memberProfile -e -a=1 + $ api:inspect -t=query -M=members -m=membershipById + $ api:inspect -t=query -M=members -m=membershipById -e + $ 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)_ diff --git a/cli/package.json b/cli/package.json index e8181b8539..608346669f 100644 --- a/cli/package.json +++ b/cli/package.json @@ -8,7 +8,7 @@ }, "bugs": "https://github.com/Joystream/joystream/issues", "dependencies": { - "@joystream/types": "^0.12.0", + "@joystream/types": "^0.13.0", "@oclif/command": "^1.5.19", "@oclif/config": "^1.14.0", "@oclif/plugin-autocomplete": "^0.2.0", diff --git a/cli/src/Api.ts b/cli/src/Api.ts index c33261e15c..e14aaac095 100644 --- a/cli/src/Api.ts +++ b/cli/src/Api.ts @@ -43,7 +43,7 @@ import { OpeningId, StakingPolicy, } from '@joystream/types/hiring' -import { MemberId, Profile } from '@joystream/types/members' +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' @@ -193,10 +193,11 @@ export default class Api { return this._api.query[module] } - protected async memberProfileById(memberId: MemberId): Promise { - const profile = (await this._api.query.members.memberProfile(memberId)) as Option + protected async membershipById(memberId: MemberId): Promise { + const profile = (await this._api.query.members.membershipById(memberId)) as Membership - return profile.unwrapOr(null) + // Can't just use profile.isEmpty because profile.suspended is Bool (which isEmpty method always returns false) + return profile.handle.isEmpty ? null : profile } async groupLead(group: WorkingGroups): Promise { @@ -238,7 +239,7 @@ export default class Api { const roleAccount = worker.role_account_id const memberId = worker.member_id - const profile = await this.memberProfileById(memberId) + const profile = await this.membershipById(memberId) if (!profile) { throw new Error(`Group member profile not found! (member id: ${memberId.toNumber()})`) @@ -358,7 +359,7 @@ export default class Api { wgApplicationId, applicationId: appId.toNumber(), wgOpeningId: wgApplication.opening_id.toNumber(), - member: await this.memberProfileById(wgApplication.member_id), + member: await this.membershipById(wgApplication.member_id), roleAccout: wgApplication.role_account_id, stakes: { application: appStakingId.isSome ? (await this.stakeValue(appStakingId.unwrap())).toNumber() : 0, diff --git a/cli/src/Types.ts b/cli/src/Types.ts index 6418b405bc..f82174d038 100644 --- a/cli/src/Types.ts +++ b/cli/src/Types.ts @@ -8,7 +8,7 @@ import { BlockNumber, Balance, AccountId } from '@polkadot/types/interfaces' import { DerivedBalances } from '@polkadot/api-derive/types' import { KeyringPair } from '@polkadot/keyring/types' import { WorkerId, OpeningType } from '@joystream/types/working-group' -import { Profile, MemberId } from '@joystream/types/members' +import { Membership, MemberId } from '@joystream/types/members' import { GenericJoyStreamRoleSchema, JobSpecifics, @@ -103,7 +103,7 @@ export type GroupMember = { workerId: WorkerId memberId: MemberId roleAccount: AccountId - profile: Profile + profile: Membership stake?: Balance reward?: Reward } @@ -112,7 +112,7 @@ export type GroupApplication = { wgApplicationId: number applicationId: number wgOpeningId: number - member: Profile | null + member: Membership | null roleAccout: AccountId stakes: { application: number diff --git a/cli/src/commands/api/inspect.ts b/cli/src/commands/api/inspect.ts index 8925c0de3c..7ee1dcf887 100644 --- a/cli/src/commands/api/inspect.ts +++ b/cli/src/commands/api/inspect.ts @@ -35,9 +35,9 @@ export default class ApiInspect extends ApiCommandBase { '$ api:inspect', '$ api:inspect -t=query', '$ api:inspect -t=query -M=members', - '$ api:inspect -t=query -M=members -m=memberProfile', - '$ api:inspect -t=query -M=members -m=memberProfile -e', - '$ api:inspect -t=query -M=members -m=memberProfile -e -a=1', + '$ api:inspect -t=query -M=members -m=membershipById', + '$ api:inspect -t=query -M=members -m=membershipById -e', + '$ api:inspect -t=query -M=members -m=membershipById -e -a=1', ] static flags = { diff --git a/pioneer/packages/apps-routing/src/joy-members.ts b/pioneer/packages/apps-routing/src/joy-members.ts index 159d0df398..8e2ba10029 100644 --- a/pioneer/packages/apps-routing/src/joy-members.ts +++ b/pioneer/packages/apps-routing/src/joy-members.ts @@ -6,7 +6,7 @@ export default [ { Component: Members, display: { - needsApi: ['query.members.membersCreated'] + needsApi: ['query.members.nextMemberId'] }, i18n: { defaultValue: 'Membership' diff --git a/pioneer/packages/joy-members/src/Dashboard.tsx b/pioneer/packages/joy-members/src/Dashboard.tsx index 0ffcd587f1..3c2bcc78d1 100644 --- a/pioneer/packages/joy-members/src/Dashboard.tsx +++ b/pioneer/packages/joy-members/src/Dashboard.tsx @@ -16,7 +16,7 @@ import { FIRST_MEMBER_ID } from './constants'; type Props = ApiProps & I18nProps & { newMembershipsAllowed?: Bool; - membersCreated?: BN; + nextMemberId?: BN; minHandleLength?: BN; maxHandleLength?: BN; maxAvatarUriLength?: BN; @@ -36,7 +36,7 @@ class Dashboard extends React.PureComponent { {isAllowed && (isAllowed.eq(true) ? 'Yes' : 'No')} - {formatNumber(p.membersCreated)} + {formatNumber(p.nextMemberId)} {formatNumber(FIRST_MEMBER_ID)} @@ -75,7 +75,7 @@ class Dashboard extends React.PureComponent { export default translate( withCalls( queryMembershipToProp('newMembershipsAllowed'), - queryMembershipToProp('membersCreated'), + queryMembershipToProp('nextMemberId'), queryMembershipToProp('minHandleLength'), queryMembershipToProp('maxHandleLength'), queryMembershipToProp('maxAvatarUriLength'), diff --git a/pioneer/packages/joy-members/src/Details.tsx b/pioneer/packages/joy-members/src/Details.tsx index 9b5d66487d..3e694ad437 100644 --- a/pioneer/packages/joy-members/src/Details.tsx +++ b/pioneer/packages/joy-members/src/Details.tsx @@ -12,7 +12,7 @@ import AddressMini from '@polkadot/react-components/AddressMiniJoy'; import { formatNumber } from '@polkadot/util'; import translate from './translate'; -import { MemberId, Profile, EntryMethod, Paid, Screening, Genesis, SubscriptionId } from '@joystream/types/members'; +import { MemberId, Membership, EntryMethod, Paid, Screening, Genesis, SubscriptionId } from '@joystream/types/members'; import { queryMembershipToProp } from './utils'; import { Seat } from '@joystream/types/council'; import { nonEmptyStr, queryToProp } from '@polkadot/joy-utils/index'; @@ -21,17 +21,15 @@ import { MyAccountProps, withMyAccount } from '@polkadot/joy-utils/MyAccount'; type Props = ApiProps & I18nProps & MyAccountProps & { preview?: boolean; memberId: MemberId; - // This cannot be named just "memberProfile", since it will conflict with "withAccount's" memberProfile - // (which holds member profile associated with currently selected account) - detailsMemberProfile?: Option; // TODO refactor to Option + membership?: Membership; activeCouncil?: Seat[]; }; class Component extends React.PureComponent { render () { - const { detailsMemberProfile } = this.props; - return detailsMemberProfile - ? this.renderProfile(detailsMemberProfile.unwrap() as Profile) + const { membership } = this.props; + return membership && !membership.handle.isEmpty + ? this.renderProfile(membership) : (
@@ -39,7 +37,7 @@ class Component extends React.PureComponent { ); } - private renderProfile (memberProfile: Profile) { + private renderProfile (membership: Membership) { const { preview = false, myAddress, @@ -51,7 +49,7 @@ class Component extends React.PureComponent { avatar_uri, root_account, controller_account - } = memberProfile; + } = membership; const hasAvatar = avatar_uri && nonEmptyStr(avatar_uri.toString()); const isMyProfile = myAddress && (myAddress === root_account.toString() || myAddress === controller_account.toString()); @@ -83,12 +81,12 @@ class Component extends React.PureComponent {
- {!preview && this.renderDetails(memberProfile, isCouncilor)} + {!preview && this.renderDetails(membership, isCouncilor)} ); } - private renderDetails (memberProfile: Profile, isCouncilor: boolean) { + private renderDetails (membership: Membership, isCouncilor: boolean) { const { about, registered_at_block, @@ -99,7 +97,7 @@ class Component extends React.PureComponent { root_account, controller_account - } = memberProfile; + } = membership; const { memberId } = this.props; @@ -173,8 +171,8 @@ export default translate(withMyAccount( withCalls( queryToProp('query.council.activeCouncil'), queryMembershipToProp( - 'memberProfile', - { paramName: 'memberId', propName: 'detailsMemberProfile' } + 'membershipById', + { paramName: 'memberId', propName: 'membership' } ) )(Component) )); diff --git a/pioneer/packages/joy-members/src/DetailsByHandle.tsx b/pioneer/packages/joy-members/src/DetailsByHandle.tsx index ba3bdbe051..652af8d9c8 100644 --- a/pioneer/packages/joy-members/src/DetailsByHandle.tsx +++ b/pioneer/packages/joy-members/src/DetailsByHandle.tsx @@ -11,11 +11,11 @@ import { queryMembershipToProp } from './utils'; type DetailsByHandleProps = { handle: string; - handles?: MemberId; + memberIdByHandle?: MemberId; }; function DetailsByHandleInner (p: DetailsByHandleProps) { - const { handles: memberId } = p; + const { memberIdByHandle: memberId } = p; return memberId !== undefined // here we can't make distinction value existing and loading ?
@@ -24,7 +24,7 @@ function DetailsByHandleInner (p: DetailsByHandleProps) { } const DetailsByHandle = withCalls( - queryMembershipToProp('handles', 'handle') + queryMembershipToProp('memberIdByHandle', 'handle') )(DetailsByHandleInner); type Props = I18nProps & { diff --git a/pioneer/packages/joy-members/src/EditForm.tsx b/pioneer/packages/joy-members/src/EditForm.tsx index a078a55df5..38cd5bbd30 100644 --- a/pioneer/packages/joy-members/src/EditForm.tsx +++ b/pioneer/packages/joy-members/src/EditForm.tsx @@ -4,12 +4,12 @@ import { Link } from 'react-router-dom'; import { Form, Field, withFormik, FormikProps } from 'formik'; import * as Yup from 'yup'; -import { Option, Vec } from '@polkadot/types'; +import { Vec } from '@polkadot/types'; import Section from '@polkadot/joy-utils/Section'; import TxButton from '@polkadot/joy-utils/TxButton'; import * as JoyForms from '@polkadot/joy-utils/forms'; import { SubmittableResult } from '@polkadot/api'; -import { MemberId, UserInfo, Profile, PaidTermId, PaidMembershipTerms } from '@joystream/types/members'; +import { MemberId, Membership, PaidTermId, PaidMembershipTerms } from '@joystream/types/members'; import { OptionText } from '@joystream/types/common'; import { MyAccountProps, withMyAccount } from '@polkadot/joy-utils/MyAccount'; import { queryMembershipToProp } from './utils'; @@ -43,7 +43,7 @@ type ValidationProps = { }; type OuterProps = ValidationProps & { - profile?: Profile; + profile?: Membership; paidTerms: PaidMembershipTerms; paidTermId: PaidTermId; memberId?: MemberId; @@ -108,18 +108,18 @@ const InnerForm = (props: FormProps) => { const buildTxParams = () => { if (!isValid) return []; - const userInfo = new UserInfo({ - handle: fieldToTextOption('handle'), - avatar_uri: fieldToTextOption('avatar'), - about: fieldToTextOption('about') - }); + const userInfo = [ + fieldToTextOption('handle'), + fieldToTextOption('avatar'), + fieldToTextOption('about') + ]; if (profile) { // update profile - return [memberId, userInfo]; + return [memberId, ...userInfo]; } else { // register as new member - return [paidTermId, userInfo]; + return [paidTermId, ...userInfo]; } }; @@ -171,7 +171,7 @@ const InnerForm = (props: FormProps) => { label={profile ? 'Update my profile' : 'Register'} isDisabled={!dirty || isSubmitting} params={buildTxParams()} - tx={profile ? 'members.updateProfile' : 'members.buyMembership'} + tx={profile ? 'members.updateMembership' : 'members.buyMembership'} onClick={onSubmit} txFailedCb={onTxFailed} txSuccessCb={onTxSuccess} @@ -207,19 +207,19 @@ const EditForm = withFormik({ } })(InnerForm); -type WithMyProfileProps = { +type WithMembershipDataProps = { memberId?: MemberId; - memberProfile?: Option; // TODO refactor to Option + membership?: Membership; paidTermsId: PaidTermId; - paidTerms?: Option; + paidTerms?: PaidMembershipTerms; minHandleLength?: BN; maxHandleLength?: BN; maxAvatarUriLength?: BN; maxAboutTextLength?: BN; }; -function WithMyProfileInner (p: WithMyProfileProps) { - const triedToFindProfile = !p.memberId || p.memberProfile; +function WithMembershipDataInner (p: WithMembershipDataProps) { + const triedToFindProfile = !p.memberId || p.membership; if ( triedToFindProfile && p.paidTerms && @@ -228,9 +228,9 @@ function WithMyProfileInner (p: WithMyProfileProps) { p.maxAvatarUriLength && p.maxAboutTextLength ) { - const profile = p.memberProfile ? p.memberProfile.unwrapOr(undefined) : undefined; + const membership = p.membership && !p.membership.handle.isEmpty ? p.membership : undefined; - if (!profile && p.paidTerms.isNone) { + if (!membership && p.paidTerms.isEmpty) { console.error('Could not find active paid membership terms'); } @@ -240,8 +240,8 @@ function WithMyProfileInner (p: WithMyProfileProps) { maxHandleLength={p.maxHandleLength.toNumber()} maxAvatarUriLength={p.maxAvatarUriLength.toNumber()} maxAboutTextLength={p.maxAboutTextLength.toNumber()} - profile={profile as Profile} - paidTerms={p.paidTerms.unwrap()} + profile={membership} + paidTerms={p.paidTerms} paidTermId={p.paidTermsId} memberId={p.memberId} /> @@ -249,22 +249,22 @@ function WithMyProfileInner (p: WithMyProfileProps) { } else return Loading...; } -const WithMyProfile = withCalls( +const WithMembershipData = withCalls( queryMembershipToProp('minHandleLength'), queryMembershipToProp('maxHandleLength'), queryMembershipToProp('maxAvatarUriLength'), queryMembershipToProp('maxAboutTextLength'), - queryMembershipToProp('memberProfile', 'memberId'), + queryMembershipToProp('membershipById', { paramName: 'memberId', propName: 'membership' }), queryMembershipToProp('paidMembershipTermsById', { paramName: 'paidTermsId', propName: 'paidTerms' }) -)(WithMyProfileInner); +)(WithMembershipDataInner); -type WithMyMemberIdProps = MyAccountProps & { +type WithMembershipDataWrapperProps = MyAccountProps & { memberIdsByRootAccountId?: Vec; memberIdsByControllerAccountId?: Vec; paidTermsIds?: Vec; }; -function WithMyMemberIdInner (p: WithMyMemberIdProps) { +function WithMembershipDataWrapperInner (p: WithMembershipDataWrapperProps) { if (p.allAccounts && !Object.keys(p.allAccounts).length) { return ( @@ -284,7 +284,7 @@ function WithMyMemberIdInner (p: WithMyMemberIdProps) { p.memberIdsByRootAccountId.concat(p.memberIdsByControllerAccountId); const memberId = p.memberIdsByRootAccountId.length ? p.memberIdsByRootAccountId[0] : undefined; - return ; + return ; } else { console.error('Active paid membership terms is empty'); } @@ -293,12 +293,12 @@ function WithMyMemberIdInner (p: WithMyMemberIdProps) { return Loading...; } -const WithMyMemberId = withMyAccount( - withCalls( +const WithMembershipDataWrapper = withMyAccount( + withCalls( queryMembershipToProp('memberIdsByRootAccountId', 'myAddress'), queryMembershipToProp('memberIdsByControllerAccountId', 'myAddress'), queryMembershipToProp('activePaidMembershipTerms', { propName: 'paidTermsIds' }) - )(WithMyMemberIdInner) + )(WithMembershipDataWrapperInner) ); -export default WithMyMemberId; +export default WithMembershipDataWrapper; diff --git a/pioneer/packages/joy-members/src/MemberPreview.tsx b/pioneer/packages/joy-members/src/MemberPreview.tsx index 1c9a4da46a..abf91d7ed5 100644 --- a/pioneer/packages/joy-members/src/MemberPreview.tsx +++ b/pioneer/packages/joy-members/src/MemberPreview.tsx @@ -4,12 +4,12 @@ import { Link } from 'react-router-dom'; import { ApiProps } from '@polkadot/react-api/types'; import { I18nProps } from '@polkadot/react-components/types'; import { withCalls, withMulti } from '@polkadot/react-api/with'; -import { Option, Vec } from '@polkadot/types'; +import { Vec } from '@polkadot/types'; import { AccountId } from '@polkadot/types/interfaces'; import IdentityIcon from '@polkadot/react-components/IdentityIcon'; import translate from './translate'; -import { MemberId, Profile } from '@joystream/types/members'; +import { MemberId, Membership } from '@joystream/types/members'; import { queryMembershipToProp } from './utils'; import { Seat } from '@joystream/types/council'; import { nonEmptyStr, queryToProp } from '@polkadot/joy-utils/index'; @@ -22,7 +22,7 @@ const InlineAvatarSizePx = 24; type MemberPreviewProps = ApiProps & I18nProps & { accountId: AccountId; memberId?: MemberId; - memberProfile?: Option; // TODO refactor to Option + membership?: Membership; activeCouncil?: Seat[]; prefixLabel?: string; inline?: boolean; @@ -32,15 +32,15 @@ type MemberPreviewProps = ApiProps & I18nProps & { class InnerMemberPreview extends React.PureComponent { render () { - const { memberProfile } = this.props; - return memberProfile - ? this.renderProfile(memberProfile.unwrap() as Profile) + const { membership } = this.props; + return membership && !membership.handle.isEmpty + ? this.renderProfile(membership) : null; } - private renderProfile (memberProfile: Profile) { + private renderProfile (membership: Membership) { const { activeCouncil = [], accountId, prefixLabel, inline, className, style } = this.props; - const { handle, avatar_uri } = memberProfile; + const { handle, avatar_uri } = membership; const hasAvatar = avatar_uri && nonEmptyStr(avatar_uri.toString()); const isCouncilor: boolean = accountId !== undefined && activeCouncil.find(x => accountId.eq(x.member)) !== undefined; @@ -113,6 +113,6 @@ export const MemberPreview = withMulti( setMemberIdByAccountId, withCalls( queryToProp('query.council.activeCouncil'), // TODO Refactor: extract ActiveCouncilContext - queryMembershipToProp('memberProfile', 'memberId') + queryMembershipToProp('membershipById', { paramName: 'memberId', propName: 'membership' }) ) ); diff --git a/pioneer/packages/joy-members/src/index.tsx b/pioneer/packages/joy-members/src/index.tsx index d744ba4680..7b6339c10b 100644 --- a/pioneer/packages/joy-members/src/index.tsx +++ b/pioneer/packages/joy-members/src/index.tsx @@ -22,12 +22,12 @@ import { RouteComponentProps } from 'react-router-dom'; // define out internal types type Props = AppProps & ApiProps & I18nProps & MyAccountProps & { - membersCreated?: BN; + nextMemberId?: BN; }; class App extends React.PureComponent { private buildTabs (): TabItem[] { - const { t, membersCreated: memberCount, iAmMember } = this.props; + const { t, nextMemberId: memberCount, iAmMember } = this.props; return [ { @@ -47,9 +47,9 @@ class App extends React.PureComponent { } private renderList (routeProps: RouteComponentProps) { - const { membersCreated, ...otherProps } = this.props; - return membersCreated - ? + const { nextMemberId, ...otherProps } = this.props; + return nextMemberId + ? : Loading...; } @@ -79,6 +79,6 @@ export default withMulti( translate, withMyAccount, withCalls( - queryMembershipToProp('membersCreated') + queryMembershipToProp('nextMemberId') ) ); diff --git a/pioneer/packages/joy-proposals/src/Proposal/Body.tsx b/pioneer/packages/joy-proposals/src/Proposal/Body.tsx index 3875b0f0db..1989d2b698 100644 --- a/pioneer/packages/joy-proposals/src/Proposal/Body.tsx +++ b/pioneer/packages/joy-proposals/src/Proposal/Body.tsx @@ -7,7 +7,7 @@ import styled from 'styled-components'; import AddressMini from '@polkadot/react-components/AddressMiniJoy'; import TxButton from '@polkadot/joy-utils/TxButton'; import { ProposalId, TerminateRoleParameters } from '@joystream/types/proposals'; -import { MemberId, Profile } from '@joystream/types/members'; +import { MemberId, Membership } from '@joystream/types/members'; import ProfilePreview from '@polkadot/joy-utils/MemberProfilePreview'; import { useTransport, usePromise } from '@polkadot/joy-utils/react/hooks'; import { Option, Bytes } from '@polkadot/types/'; @@ -55,20 +55,18 @@ function ProposedMember (props: { memberId?: MemberId | number | null }) { const memberId: MemberId | number = props.memberId; const transport = useTransport(); - const [member, error, loading] = usePromise | null>( - () => transport.members.memberProfile(memberId), + const [member, error, loading] = usePromise( + () => transport.members.membershipById(memberId), null ); - const profile = member && member.unwrapOr(null); - return ( - { profile ? ( + { (member && !member.handle.isEmpty) ? ( ) : 'Profile not found' } diff --git a/pioneer/packages/joy-proposals/src/forms/AddWorkingGroupOpeningForm.tsx b/pioneer/packages/joy-proposals/src/forms/AddWorkingGroupOpeningForm.tsx index a464959b3e..e65d0e628e 100644 --- a/pioneer/packages/joy-proposals/src/forms/AddWorkingGroupOpeningForm.tsx +++ b/pioneer/packages/joy-proposals/src/forms/AddWorkingGroupOpeningForm.tsx @@ -188,15 +188,15 @@ const valuesToAddOpeningParams = (values: FormValues): SimplifiedTypeInterface = props => { - const { handleChange, errors, touched, values, setFieldValue, myMemberId, memberProfile } = props; + const { handleChange, errors, touched, values, setFieldValue, myMemberId, myMembership } = props; useEffect(() => { - if (memberProfile?.isSome && !touched.humanReadableText) { + if (myMembership && !touched.humanReadableText) { setFieldValue( 'humanReadableText', - JSON.stringify(HRTDefault(memberProfile.unwrap().handle.toString(), values.workingGroup), undefined, 4) + JSON.stringify(HRTDefault(myMembership.handle.toString(), values.workingGroup), undefined, 4) ); } - }, [values.workingGroup, memberProfile]); + }, [values.workingGroup, myMembership]); const errorLabelsProps = getFormErrorLabelsProps(errors, touched); return ( diff --git a/pioneer/packages/joy-proposals/src/forms/SetContentWorkingGroupLeadForm.tsx b/pioneer/packages/joy-proposals/src/forms/SetContentWorkingGroupLeadForm.tsx index 3b897539d9..17bb481874 100644 --- a/pioneer/packages/joy-proposals/src/forms/SetContentWorkingGroupLeadForm.tsx +++ b/pioneer/packages/joy-proposals/src/forms/SetContentWorkingGroupLeadForm.tsx @@ -16,7 +16,7 @@ import Validation from '../validationSchema'; import { FormField } from './FormFields'; import { withFormContainer } from './FormContainer'; import { useTransport, usePromise } from '@polkadot/joy-utils/react/hooks'; -import { Profile } from '@joystream/types/members'; +import { Membership } from '@joystream/types/members'; import { PromiseComponent } from '@polkadot/joy-utils/react/components'; import _ from 'lodash'; import './forms.css'; @@ -35,7 +35,7 @@ type ExportComponentProps = ProposalFormExportProps; type FormInnerProps = ProposalFormInnerProps; -function memberOptionKey (id: number, profile: Profile) { +function memberOptionKey (id: number, profile: Membership) { return `${id}:${profile.root_account.toString()}`; } @@ -46,7 +46,7 @@ const MEMBERS_NONE_OPTION: DropdownItemProps = { value: 'none' }; -function membersToOptions (members: { id: number; profile: Profile }[]) { +function membersToOptions (members: { id: number; profile: Membership }[]) { return [MEMBERS_NONE_OPTION].concat( members .map(({ id, profile }) => ({ @@ -66,7 +66,7 @@ function filterMembers (options: DropdownItemProps[], query: string) { return options.filter((opt) => regexp.test((opt.text || '').toString())); } -type MemberWithId = { id: number; profile: Profile }; +type MemberWithId = { id: number; profile: Membership }; const SetContentWorkingGroupsLeadForm: React.FunctionComponent = props => { const { handleChange, errors, touched, values } = props; diff --git a/pioneer/packages/joy-proposals/src/stories/data/ProposalDetails.mock.ts b/pioneer/packages/joy-proposals/src/stories/data/ProposalDetails.mock.ts index 49a73b85e9..474db8c862 100644 --- a/pioneer/packages/joy-proposals/src/stories/data/ProposalDetails.mock.ts +++ b/pioneer/packages/joy-proposals/src/stories/data/ProposalDetails.mock.ts @@ -31,7 +31,6 @@ const mockedProposal: ParsedProposal = { handle: 'bob55', registered_at_block: 18, registered_at_time: 1588087314000, - roles: [], entry: { Paid: 0 }, diff --git a/pioneer/packages/joy-roles/src/elements.tsx b/pioneer/packages/joy-roles/src/elements.tsx index 12cbb0b34e..5af9089c51 100644 --- a/pioneer/packages/joy-roles/src/elements.tsx +++ b/pioneer/packages/joy-roles/src/elements.tsx @@ -6,7 +6,7 @@ import { Link } from 'react-router-dom'; import { Balance } from '@polkadot/types/interfaces'; import { formatBalance } from '@polkadot/util'; import Identicon from '@polkadot/react-identicon'; -import { IProfile, MemberId } from '@joystream/types/members'; +import { IMembership, MemberId } from '@joystream/types/members'; import { GenericAccountId } from '@polkadot/types'; import { LeadRoleState } from '@joystream/types/content-working-group'; import { WorkerId } from '@joystream/types/working-group'; @@ -28,7 +28,7 @@ export function BalanceView (props: BalanceProps) { } type ProfileProps = { - profile: IProfile; + profile: IMembership; } export function HandleView (props: ProfileProps) { @@ -46,7 +46,7 @@ export type GroupMember = { group: WorkingGroups; workerId: number; roleAccount: GenericAccountId; - profile: IProfile; + profile: IMembership; title: string; stake?: Balance; rewardRelationship?: RewardRelationship; @@ -56,7 +56,7 @@ export type GroupLead = { memberId: MemberId; workerId?: WorkerId; // In case of "working-group" module roleAccount: GenericAccountId; - profile: IProfile; + profile: IMembership; title: string; stage?: LeadRoleState; stake?: Balance; diff --git a/pioneer/packages/joy-roles/src/mocks.ts b/pioneer/packages/joy-roles/src/mocks.ts index 2dc8bc31a0..1ec3ac28da 100644 --- a/pioneer/packages/joy-roles/src/mocks.ts +++ b/pioneer/packages/joy-roles/src/mocks.ts @@ -1,7 +1,7 @@ import { bool, Option, Text, u32, u64, Vec } from '@polkadot/types'; import AccountId from '@polkadot/types/primitive/Generic/AccountId'; -import { ActorInRole, IProfile, EntryMethod } from '@joystream/types/members'; +import { IMembership, EntryMethod } from '@joystream/types/members'; import { AcceptingApplications, @@ -11,7 +11,7 @@ import { ApplicationId } from '@joystream/types/hiring'; -export function mockProfile (name: string, avatar_uri = ''): IProfile { +export function mockProfile (name: string, avatar_uri = ''): IMembership { return { handle: new Text(name), avatar_uri: new Text(avatar_uri), @@ -22,8 +22,7 @@ export function mockProfile (name: string, avatar_uri = ''): IProfile { suspended: new bool(false), subscription: new Option(u64), root_account: new AccountId('5HZ6GtaeyxagLynPryM7ZnmLzoWFePKuDrkb4AT8rT4pU1fp'), - controller_account: new AccountId('5HZ6GtaeyxagLynPryM7ZnmLzoWFePKuDrkb4AT8rT4pU1fp'), - roles: new Vec(ActorInRole) + controller_account: new AccountId('5HZ6GtaeyxagLynPryM7ZnmLzoWFePKuDrkb4AT8rT4pU1fp') }; } diff --git a/pioneer/packages/joy-roles/src/tabs/Admin.controller.tsx b/pioneer/packages/joy-roles/src/tabs/Admin.controller.tsx index 90e2ed83f3..5a5d40a5cd 100644 --- a/pioneer/packages/joy-roles/src/tabs/Admin.controller.tsx +++ b/pioneer/packages/joy-roles/src/tabs/Admin.controller.tsx @@ -45,7 +45,7 @@ import { } from '@joystream/types/hiring'; import { - Profile, + Membership, MemberId } from '@joystream/types/members'; @@ -77,7 +77,7 @@ type ids = { type application = ids & { account: string; memberId: number; - profile: Profile; + profile: Membership; stage: ApplicationStage; applicationStake: Balance; roleStake: Balance; @@ -430,8 +430,12 @@ export class AdminController extends Controller { this.queueExtrinsic({ extrinsic: tx, txSuccessCb: this.onTxSuccess, accountId }); } - protected async profile (id: MemberId): Promise> { - return (await this.api.query.members.memberProfile(id)) as Option; + protected async profile (id: MemberId): Promise { + const member = (await this.api.query.members.membershipById(id)) as Membership; + if (member.handle.isEmpty) { + throw new Error(`Expected member profile not found! (id: ${id.toString()}`); + } + return member; } protected async stakeValue (stakeId: StakeId): Promise { @@ -517,7 +521,7 @@ export class AdminController extends Controller { stage: baseApplications.value.stage, account: cApplication.value.role_account_id.toString(), memberId: cApplication.value.member_id.toNumber(), - profile: (await this.profile(cApplication.value.member_id)).unwrap(), + profile: (await this.profile(cApplication.value.member_id)), applicationStake: await this.applicationStake(baseApplications.value), roleStake: await this.roleStake(baseApplications.value), application: baseApplications.value diff --git a/pioneer/packages/joy-roles/src/transport.mock.ts b/pioneer/packages/joy-roles/src/transport.mock.ts index 53bb1d14d3..c66cf19a40 100644 --- a/pioneer/packages/joy-roles/src/transport.mock.ts +++ b/pioneer/packages/joy-roles/src/transport.mock.ts @@ -6,7 +6,7 @@ import { Subscribable, Transport as TransportBase } from '@polkadot/joy-utils/in import { ITransport } from './transport'; -import { Role, MemberId } from '@joystream/types/members'; +import { MemberId } from '@joystream/types/members'; import { Opening, ApplicationRationingPolicy, @@ -36,14 +36,6 @@ export class Transport extends TransportBase implements ITransport { return Math.random() * (max - min) + min; } - roles (): Promise> { - return this.promise>( - [ - new Role('StorageProvider') - ] - ); - } - groupLeadStatus (group: WorkingGroups = WorkingGroups.ContentCurators): Promise { return this.simulateApiResponse({ loaded: true diff --git a/pioneer/packages/joy-roles/src/transport.substrate.ts b/pioneer/packages/joy-roles/src/transport.substrate.ts index 4801bf9ea3..4a0ca9aebc 100644 --- a/pioneer/packages/joy-roles/src/transport.substrate.ts +++ b/pioneer/packages/joy-roles/src/transport.substrate.ts @@ -32,7 +32,7 @@ import { import { Application, Opening, OpeningId, ApplicationId, ActiveApplicationStage } from '@joystream/types/hiring'; import { Stake, StakeId } from '@joystream/types/stake'; import { RewardRelationship, RewardRelationshipId } from '@joystream/types/recurring-rewards'; -import { ActorInRole, Profile, MemberId, Role, RoleKeys, ActorId } from '@joystream/types/members'; +import { Membership, MemberId, ActorId } from '@joystream/types/members'; import { createAccount, generateSeed } from '@polkadot/joy-utils/accounts'; import { WorkingGroupMembership, GroupLeadStatus } from './tabs/WorkingGroup'; @@ -176,11 +176,6 @@ export class Transport extends TransportBase implements ITransport { this.cachedApi.unsubscribe(); } - async roles (): Promise> { - const roles: any = await this.cachedApi.query.actors.availableRoles(); - return this.promise>(roles.map((role: Role) => role)); - } - protected async stakeValue (stakeId: StakeId): Promise { const stake = new SingleLinkedMapEntry( Stake, @@ -209,31 +204,14 @@ export class Transport extends TransportBase implements ITransport { return relationship?.total_reward_received || new u128(0); } - protected async memberIdFromRoleAndActorId (role: Role, id: ActorId): Promise { - const memberId = ( - await this.cachedApi.query.members.membershipIdByActorInRole( - new ActorInRole({ - role: role, - actor_id: id - }) - ) - ) as MemberId; - - return memberId; - } - - protected memberIdFromCuratorId (curatorId: CuratorId): Promise { - return this.memberIdFromRoleAndActorId( - new Role(RoleKeys.Curator), - curatorId - ); - } + protected async curatorMemberId (curator: Curator): Promise { + const curatorApplicationId = curator.induction.curator_application_id; + const curatorApplication = new SingleLinkedMapEntry( + CuratorApplication, + await this.cachedApi.query.contentWorkingGroup.curatorApplicationById(curatorApplicationId) + ).value; - protected memberIdFromLeadId (leadId: LeadId): Promise { - return this.memberIdFromRoleAndActorId( - new Role(RoleKeys.CuratorLead), - leadId - ); + return curatorApplication.member_id; } protected async workerRewardRelationship (worker: GroupWorker): Promise { @@ -250,12 +228,12 @@ export class Transport extends TransportBase implements ITransport { ): Promise { const roleAccount = worker.role_account_id; const memberId = group === WorkingGroups.ContentCurators - ? await this.memberIdFromCuratorId(id) + ? await this.curatorMemberId(worker as Curator) : (worker as Worker).member_id; - const profile = await this.cachedApi.query.members.memberProfile(memberId) as Option; - if (profile.isNone) { - throw new Error('no profile found'); + const profile = await this.cachedApi.query.members.membershipById(memberId) as Membership; + if (profile.handle.isEmpty) { + throw new Error('No group member profile found!'); } let stakeValue: Balance = new u128(0); @@ -270,7 +248,7 @@ export class Transport extends TransportBase implements ITransport { group, memberId, workerId: id.toNumber(), - profile: profile.unwrap(), + profile, title: workerRoleNameByGroup[group], stake: stakeValue, rewardRelationship @@ -321,7 +299,7 @@ export class Transport extends TransportBase implements ITransport { await this.cachedApi.query.contentWorkingGroup.leadById(leadId) ); - const memberId = await this.memberIdFromLeadId(leadId); + const memberId = lead.value.member_id; return { lead: lead.value, @@ -360,9 +338,9 @@ export class Transport extends TransportBase implements ITransport { : await this.currentStorageLead(); if (currentLead !== null) { - const profile = await this.cachedApi.query.members.memberProfile(currentLead.memberId) as Option; + const profile = await this.cachedApi.query.members.membershipById(currentLead.memberId) as Membership; - if (profile.isNone) { + if (profile.handle.isEmpty) { throw new Error(`${group} lead profile not found!`); } @@ -379,7 +357,7 @@ export class Transport extends TransportBase implements ITransport { memberId: currentLead.memberId, workerId: currentLead.workerId, roleAccount: currentLead.lead.role_account_id, - profile: profile.unwrap(), + profile, title: _.startCase(group) + ' Lead', stage: group === WorkingGroups.ContentCurators ? (currentLead.lead as Lead).stage : undefined, stake, diff --git a/pioneer/packages/joy-roles/src/transport.ts b/pioneer/packages/joy-roles/src/transport.ts index f2a473bf71..66c5bb0429 100644 --- a/pioneer/packages/joy-roles/src/transport.ts +++ b/pioneer/packages/joy-roles/src/transport.ts @@ -1,8 +1,6 @@ import { Subscribable } from '@polkadot/joy-utils/index'; import { Balance } from '@polkadot/types/interfaces'; -import { Role } from '@joystream/types/members'; - import { WorkingGroupMembership, GroupLeadStatus } from './tabs/WorkingGroup'; import { WorkingGroupOpening } from './tabs/Opportunities'; import { keyPairDetails } from './flows/apply'; @@ -10,7 +8,6 @@ import { ActiveRole, OpeningApplication } from './tabs/MyRoles'; import { WorkingGroups } from './working_groups'; export interface ITransport { - roles: () => Promise>; groupLeadStatus: (group: WorkingGroups) => Promise; curationGroup: () => Promise; storageGroup: () => Promise; diff --git a/pioneer/packages/joy-utils/src/MemberProfilePreview.tsx b/pioneer/packages/joy-utils/src/MemberProfilePreview.tsx index bdf232f4c3..af503bc575 100644 --- a/pioneer/packages/joy-utils/src/MemberProfilePreview.tsx +++ b/pioneer/packages/joy-utils/src/MemberProfilePreview.tsx @@ -4,7 +4,7 @@ import { IdentityIcon } from '@polkadot/react-components'; import { Link } from 'react-router-dom'; import { Text } from '@polkadot/types'; import { AccountId } from '@polkadot/types/interfaces'; -import { MemberId, Profile } from '@joystream/types/members'; +import { MemberId, Membership } from '@joystream/types/members'; import styled from 'styled-components'; type ProfileItemProps = { @@ -68,7 +68,7 @@ export default function ProfilePreview ( } type ProfilePreviewFromStructProps = { - profile: Profile; + profile: Membership; link?: boolean; id?: number | MemberId; }; diff --git a/pioneer/packages/joy-utils/src/MembersDropdown.tsx b/pioneer/packages/joy-utils/src/MembersDropdown.tsx index ee10e82e85..a547bbd406 100644 --- a/pioneer/packages/joy-utils/src/MembersDropdown.tsx +++ b/pioneer/packages/joy-utils/src/MembersDropdown.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState, useContext } from 'react'; import { Dropdown, DropdownItemProps, DropdownProps } from 'semantic-ui-react'; -import { Profile } from '@joystream/types/members'; +import { Membership } from '@joystream/types/members'; import { memberFromAccount, MemberFromAccount } from './accounts'; import { AccountId } from '@polkadot/types/interfaces'; import { ApiContext } from '@polkadot/react-api'; @@ -14,7 +14,7 @@ const StyledMembersDropdown = styled(Dropdown)` `; function membersToOptions (members: MemberFromAccount[]) { - const validMembers = members.filter(m => m.profile !== undefined) as (MemberFromAccount & { profile: Profile })[]; + const validMembers = members.filter(m => m.profile !== undefined) as (MemberFromAccount & { profile: Membership })[]; return validMembers .map(({ id, profile, account }) => ({ key: profile.handle, diff --git a/pioneer/packages/joy-utils/src/MyAccount.tsx b/pioneer/packages/joy-utils/src/MyAccount.tsx index e60f6c5c8d..32adcab82d 100644 --- a/pioneer/packages/joy-utils/src/MyAccount.tsx +++ b/pioneer/packages/joy-utils/src/MyAccount.tsx @@ -8,7 +8,7 @@ import accountObservable from '@polkadot/ui-keyring/observable/accounts'; import { withCalls, withMulti, withObservable } from '@polkadot/react-api/index'; import { SubjectInfo } from '@polkadot/ui-keyring/observable/types'; -import { MemberId, Profile } from '@joystream/types/members'; +import { MemberId, Membership } from '@joystream/types/members'; import { CuratorId, LeadId, Lead, CurationActor, Curator } from '@joystream/types/content-working-group'; import { queryMembershipToProp } from '@polkadot/joy-members/utils'; @@ -29,7 +29,7 @@ export type MyAccountProps = MyAddressProps & { memberIdsByControllerAccountId?: Vec; myMemberIdChecked?: boolean; iAmMember?: boolean; - memberProfile?: Option; + myMembership?: Membership | null; // Content Working Group curatorEntries?: any; // entire linked_map: CuratorId => Curator @@ -37,12 +37,6 @@ export type MyAccountProps = MyAddressProps & { contentLeadId?: LeadId; contentLeadEntry?: any; // linked_map value - // From member's roles - myContentLeadId?: LeadId; - myCuratorIds?: CuratorId[]; - memberIsCurator?: boolean; - memberIsContentLead?: boolean; - curationActor?: any; allAccounts?: SubjectInfo; }; @@ -92,7 +86,23 @@ function withMyMembership

(Component: React.ComponentT return ResultComponent; } -const withMyProfile = withCalls(queryMembershipToProp('memberProfile', 'myMemberId')); +function resolveMyProfile

(Component: React.ComponentType

) { + const ResultComponent: React.FunctionComponent

= (props: P) => { + let { myMembership } = props; + myMembership = (!myMembership || myMembership.handle.isEmpty) ? null : myMembership; + return ; + }; + ResultComponent.displayName = `resolveMyProfile(${componentName(Component)})`; + return ResultComponent; +} + +const withMyProfileCall = withCalls(queryMembershipToProp('membershipById', { + paramName: 'myMemberId', + propName: 'myMembership' +})); + +const withMyProfile =

(Component: React.ComponentType

) => + withMulti(Component, withMyProfileCall, resolveMyProfile); const withContentWorkingGroupDetails = withCalls( queryToProp('query.contentWorkingGroup.currentLeadId', { propName: 'isLeadSet' }), @@ -126,146 +136,73 @@ const resolveLeadEntry = withCalls( const withContentWorkingGroup =

(Component: React.ComponentType

) => withMulti(Component, withContentWorkingGroupDetails, resolveLead, resolveLeadEntry); -function withMyRoles

(Component: React.ComponentType

) { - const ResultComponent: React.FunctionComponent

= (props: P) => { - const { iAmMember, memberProfile } = props; - - let myContentLeadId; - const myCuratorIds: Array = []; - - if (iAmMember && memberProfile && memberProfile.isSome) { - const profile = memberProfile.unwrap(); - profile.roles.forEach(role => { - if (role.isContentLead) { - myContentLeadId = role.actor_id; - } else if (role.isCurator) { - myCuratorIds.push(role.actor_id); - } - }); - } - - const memberIsContentLead = myContentLeadId !== undefined; - const memberIsCurator = myCuratorIds.length > 0; - - const newProps = { - memberIsContentLead, - memberIsCurator, - myContentLeadId, - myCuratorIds - }; - - return ; - }; - ResultComponent.displayName = `withMyRoles(${componentName(Component)})`; - return ResultComponent; -} - -const canUseAccount = (account: AccountId, allAccounts: SubjectInfo | undefined) => { - if (!allAccounts || !Object.keys(allAccounts).length) { - return false; - } - - const ix = Object.keys(allAccounts).findIndex(key => { - return account.eq(allAccounts[key].json.address); - }); - - return ix !== -1; -}; - function withCurationActor

(Component: React.ComponentType

) { const ResultComponent: React.FunctionComponent

= (props: P) => { const { myAccountId, isLeadSet, contentLeadEntry, - myCuratorIds, curatorEntries, - allAccounts, - memberIsContentLead, - memberIsCurator + allAccounts } = props; if (!myAccountId || !isLeadSet || !contentLeadEntry || !curatorEntries || !allAccounts) { return ; } - const leadRoleAccount = isLeadSet.isSome - ? new SingleLinkedMapEntry(Lead, contentLeadEntry).value.role_account + let lead = isLeadSet.isSome + ? new SingleLinkedMapEntry(Lead, contentLeadEntry).value : null; - // Is current key the content lead key? - if (leadRoleAccount && leadRoleAccount.eq(myAccountId)) { - return ; + // Ignore lead if he's not active + // TODO: Does if ever happen if we query currentLeadById? + if (!(lead?.stage.isOfType('Active'))) { + lead = null; } - const curators = new MultipleLinkedMapEntry(CuratorId, Curator, curatorEntries); + const curators = new MultipleLinkedMapEntry(CuratorId, Curator, curatorEntries); + + const curationActorByAccount = (accountId: AccountId | string) => { + if (lead && lead.role_account.toString() === accountId.toString()) { + return new CurationActor({ Lead: null }); + } - const correspondingCurationActor = (accountId: AccountId, curators: MultipleLinkedMapEntry) => { - const ix = curators.linked_values.findIndex(curator => myAccountId.eq(curator.role_account) && curator.is_active); + const matchingCuratorIndex = curators.linked_values.findIndex(curator => + curator.is_active && accountId.toString() === curator.role_account.toString() + ); - return ix >= 0 + return matchingCuratorIndex >= 0 ? new CurationActor({ - Curator: curators.linked_keys[ix] + Curator: curators.linked_keys[matchingCuratorIndex] }) : null; }; - const firstMatchingCurationActor = correspondingCurationActor(myAccountId, curators); - - // Is the current key corresponding to an active curator role key? - if (firstMatchingCurationActor) { - return ; - } - - // See if we have the member's lead role account - if (leadRoleAccount && memberIsContentLead && canUseAccount(leadRoleAccount, allAccounts)) { - return ; - } - - // See if we have one of the member's curator role accounts - if (memberIsCurator && myCuratorIds && curators.linked_keys.length) { - for (let i = 0; i < myCuratorIds.length; i++) { - const curator_id = myCuratorIds[i]; - const ix = curators.linked_keys.findIndex(id => id.eq(curator_id)); - - if (ix >= 0) { - const curator = curators.linked_values[ix]; - if (curator.is_active && canUseAccount(curator.role_account, allAccounts)) { - return ( - - ); - } - } + // First priority - currently selected account + let actor = curationActorByAccount(myAccountId); + let actorKey: AccountId | null = myAccountId; + // Second priority - check other keys and find best role + // TODO: Prioritize current member? + // TODO: Perhaps just don't do that at all and force the user to select the correct key to avoid confision? + if (!actor) { + const allActorsWithKeys = Object.keys(allAccounts).map(accKey => ({ + actor: curationActorByAccount(allAccounts[accKey].json.address), + key: new GenericAccountId(allAccounts[accKey].json.address) + })); + let actorWithKey = allActorsWithKeys.find(({ actor }) => actor?.isOfType('Lead')); + if (!actorWithKey) { + actorWithKey = allActorsWithKeys.find(({ actor }) => actor?.isOfType('Curator')); } + actor = actorWithKey?.actor || null; + actorKey = actorWithKey?.key || null; } - // selected key doesn't have any special role, check other available keys.. - - // Use lead role key if available - if (leadRoleAccount && canUseAccount(leadRoleAccount, allAccounts)) { - return ; - } - - // Use first available active curator role key if available - if (curators.linked_keys.length) { - for (let i = 0; i < curators.linked_keys.length; i++) { - const curator = curators.linked_values[i]; - if (curator.is_active && canUseAccount(curator.role_account, allAccounts)) { - return ( - - ); - } - } + if (actor && actorKey) { + return ; + } else { + // we don't have any key that can fulfill a curation action + return ; } - - // we don't have any key that can fulfill a curation action - return ; }; ResultComponent.displayName = `withCurationActor(${componentName(Component)})`; return ResultComponent; @@ -280,7 +217,6 @@ export const withMyAccount =

(Component: React.Compone withMyMembership, withMyProfile, withContentWorkingGroup, - withMyRoles, withCurationActor ); diff --git a/pioneer/packages/joy-utils/src/accounts.ts b/pioneer/packages/joy-utils/src/accounts.ts index 492a4e096b..ece7d35c8c 100644 --- a/pioneer/packages/joy-utils/src/accounts.ts +++ b/pioneer/packages/joy-utils/src/accounts.ts @@ -10,8 +10,7 @@ import { isHex, u8aToHex } from '@polkadot/util'; import { keyExtractSuri, mnemonicGenerate, mnemonicValidate, randomAsU8a } from '@polkadot/util-crypto'; import { ApiPromise } from '@polkadot/api'; -import { MemberId, Profile } from '@joystream/types/members'; -import { Option } from '@polkadot/types'; +import { MemberId, Membership } from '@joystream/types/members'; import { AccountId } from '@polkadot/types/interfaces'; import { Vec } from '@polkadot/types/codec'; @@ -142,17 +141,18 @@ export function isPasswordValid (password: string): boolean { return password.length === 0 || keyring.isPassValid(password); } -export type MemberFromAccount = { account: string; id: number; profile?: Profile }; +export type MemberFromAccount = { account: string; id: number; profile?: Membership }; +// TODO: Use transport instead (now that it's available in joy-utils) export async function memberFromAccount (api: ApiPromise, accountId: AccountId | string): Promise { const [memberId] = ((await api.query.members.memberIdsByRootAccountId(accountId)) as Vec) .concat((await api.query.members.memberIdsByControllerAccountId(accountId)) as Vec); - const member = (await api.query.members.memberProfile(memberId)) as Option; + const member = (await api.query.members.membershipById(memberId)) as Membership; return { account: accountId.toString(), id: memberId.toNumber(), - profile: member.unwrapOr(undefined) + profile: member.handle.isEmpty ? undefined : member }; } diff --git a/pioneer/packages/joy-utils/src/transport/contentWorkingGroup.ts b/pioneer/packages/joy-utils/src/transport/contentWorkingGroup.ts index a7ea0c032f..b6500c3d95 100644 --- a/pioneer/packages/joy-utils/src/transport/contentWorkingGroup.ts +++ b/pioneer/packages/joy-utils/src/transport/contentWorkingGroup.ts @@ -1,11 +1,12 @@ -import { MemberId, Profile, ActorInRole, RoleKeys, Role } from '@joystream/types/members'; +import { Membership } from '@joystream/types/members'; import { u128, Vec, Option } from '@polkadot/types/'; import BaseTransport from './base'; import { MintId, Mint } from '@joystream/types/mint'; -import { LeadId } from '@joystream/types/content-working-group'; +import { LeadId, Lead } from '@joystream/types/content-working-group'; import { ApiPromise } from '@polkadot/api'; import MembersTransport from './members'; import { APIQueryCache } from '../APIQueryCache'; +import { SingleLinkedMapEntry } from '..'; export default class ContentWorkingGroupTransport extends BaseTransport { private membersT: MembersTransport; @@ -21,19 +22,20 @@ export default class ContentWorkingGroupTransport extends BaseTransport { return (WGMint[0].get('capacity') as u128).toNumber(); } - async currentLead (): Promise<{ id: number; profile: Profile } | null> { + async currentLead (): Promise<{ id: number; profile: Membership } | null> { const optLeadId = (await this.contentWorkingGroup.currentLeadId()) as Option; const leadId = optLeadId.unwrapOr(null); if (!leadId) return null; - const actorInRole = new ActorInRole({ - role: new Role(RoleKeys.CuratorLead), - actor_id: leadId - }); - const memberId = (await this.members.membershipIdByActorInRole(actorInRole)) as MemberId; - const profile = (await this.membersT.memberProfile(memberId)).unwrapOr(null); + const lead = new SingleLinkedMapEntry(Lead, await this.contentWorkingGroup.leadById(leadId)).value; - return profile && { id: memberId.toNumber(), profile }; + if (!lead.stage.isOfType('Active')) { + return null; + } + + const profile = await this.membersT.expectedMembership(lead.member_id); + + return profile && { id: lead.member_id.toNumber(), profile }; } } diff --git a/pioneer/packages/joy-utils/src/transport/council.ts b/pioneer/packages/joy-utils/src/transport/council.ts index e465819b71..f962450f20 100644 --- a/pioneer/packages/joy-utils/src/transport/council.ts +++ b/pioneer/packages/joy-utils/src/transport/council.ts @@ -1,7 +1,7 @@ import { ParsedMember } from '../types/members'; import BaseTransport from './base'; import { Seats, ElectionParameters } from '@joystream/types/council'; -import { MemberId, Profile } from '@joystream/types/members'; +import { MemberId, Membership } from '@joystream/types/members'; import { u32, Vec } from '@polkadot/types/'; import { Balance, BlockNumber } from '@polkadot/types/interfaces'; import { FIRST_MEMBER_ID } from '../consts/members'; @@ -34,7 +34,7 @@ export default class CouncilTransport extends BaseTransport { return Promise.all( council.map(async seat => { const memberIds = (await this.members.memberIdsByControllerAccountId(seat.member)) as Vec; - const member = (await this.membersT.memberProfile(memberIds[0])).toJSON() as ParsedMember; + const member = (await this.membersT.expectedMembership(memberIds[0])).toJSON() as ParsedMember; return { ...member, memberId: memberIds[0] @@ -43,13 +43,13 @@ export default class CouncilTransport extends BaseTransport { ); } - async membersExceptCouncil (): Promise<{ id: number; profile: Profile }[]> { + async membersExceptCouncil (): Promise<{ id: number; profile: Membership }[]> { // Council members to filter out const activeCouncil = (await this.council.activeCouncil()) as Seats; - const membersCount = ((await this.members.membersCreated()) as MemberId).toNumber(); - const profiles: { id: number; profile: Profile }[] = []; + const membersCount = ((await this.members.nextMemberId()) as MemberId).toNumber(); + const profiles: { id: number; profile: Membership }[] = []; for (let id = FIRST_MEMBER_ID.toNumber(); id < membersCount; ++id) { - const profile = (await this.membersT.memberProfile(new MemberId(id))).unwrapOr(null); + const profile = (await this.membersT.membershipById(new MemberId(id))); if ( !profile || // Filter out council members diff --git a/pioneer/packages/joy-utils/src/transport/index.ts b/pioneer/packages/joy-utils/src/transport/index.ts index 03080061ad..a4296adc40 100644 --- a/pioneer/packages/joy-utils/src/transport/index.ts +++ b/pioneer/packages/joy-utils/src/transport/index.ts @@ -4,7 +4,6 @@ import ContentWorkingGroupTransport from './contentWorkingGroup'; import ProposalsTransport from './proposals'; import MembersTransport from './members'; import CouncilTransport from './council'; -import StorageProvidersTransport from './storageProviders'; import ValidatorsTransport from './validators'; import WorkingGroupsTransport from './workingGroups'; import { APIQueryCache } from '../APIQueryCache'; @@ -18,7 +17,6 @@ export default class Transport { public council: CouncilTransport; public proposals: ProposalsTransport; public contentWorkingGroup: ContentWorkingGroupTransport; - public storageProviders: StorageProvidersTransport; public validators: ValidatorsTransport; public workingGroups: WorkingGroupsTransport; @@ -27,7 +25,6 @@ export default class Transport { this.cacheApi = new APIQueryCache(api); this.chain = new ChainTransport(api, this.cacheApi); this.members = new MembersTransport(api, this.cacheApi); - this.storageProviders = new StorageProvidersTransport(api, this.cacheApi); this.validators = new ValidatorsTransport(api, this.cacheApi); this.council = new CouncilTransport(api, this.cacheApi, this.members, this.chain); this.contentWorkingGroup = new ContentWorkingGroupTransport(api, this.cacheApi, this.members); diff --git a/pioneer/packages/joy-utils/src/transport/members.ts b/pioneer/packages/joy-utils/src/transport/members.ts index 1bd61fb946..8263d87d59 100644 --- a/pioneer/packages/joy-utils/src/transport/members.ts +++ b/pioneer/packages/joy-utils/src/transport/members.ts @@ -1,18 +1,24 @@ import BaseTransport from './base'; -import { MemberId, Profile } from '@joystream/types/members'; -import { Option } from '@polkadot/types/'; +import { MemberId, Membership } from '@joystream/types/members'; export default class MembersTransport extends BaseTransport { - memberProfile (id: MemberId | number): Promise> { - return this.members.memberProfile(id) as Promise>; + async membershipById (id: MemberId | number): Promise { + const member = (await this.members.membershipById(id)) as Membership; + // Can't just use member.isEmpty because member.suspended is Bool (which isEmpty method always returns false) + return member.handle.isEmpty ? null : member; } // Throws if profile not found - async expectedMemberProfile (id: MemberId | number): Promise { - return (await this.memberProfile(id)).unwrap(); + async expectedMembership (id: MemberId | number): Promise { + const member = await this.membershipById(id); + if (!member) { + throw new Error(`Expected member profile not found! ID: ${id.toString()}`); + } + + return member; } - async membersCreated (): Promise { - return (await this.members.membersCreated() as MemberId).toNumber(); + async nextMemberId (): Promise { + return (await this.members.nextMemberId() as MemberId).toNumber(); } } diff --git a/pioneer/packages/joy-utils/src/transport/proposals.ts b/pioneer/packages/joy-utils/src/transport/proposals.ts index a738e845de..d3e088ee37 100644 --- a/pioneer/packages/joy-utils/src/transport/proposals.ts +++ b/pioneer/packages/joy-utils/src/transport/proposals.ts @@ -108,7 +108,7 @@ export default class ProposalsTransport extends BaseTransport { if (!rawProposal) { rawProposal = await this.rawProposalById(id); } - const proposer = (await this.membersT.memberProfile(rawProposal.proposerId)).toJSON() as ParsedMember; + const proposer = (await this.membersT.expectedMembership(rawProposal.proposerId)).toJSON() as ParsedMember; const proposal = rawProposal.toJSON() as { title: string; description: string; @@ -193,7 +193,7 @@ export default class ProposalsTransport extends BaseTransport { 'proposalsEngine.voteExistsByProposalByVoter', // Double map of intrest proposalId, // First double-map key value (v) => new VoteKind(v), // Converter from hex - async () => (await this.membersT.membersCreated()), // A function that returns the number of iterations to go through when chekcing possible values for the second double-map key (memberId) + async () => (await this.membersT.nextMemberId()), // A function that returns the number of iterations to go through when chekcing possible values for the second double-map key (memberId) FIRST_MEMBER_ID.toNumber() // Min. possible value for second double-map key (memberId) ); @@ -201,7 +201,7 @@ export default class ProposalsTransport extends BaseTransport { for (const voteEntry of voteEntries) { const memberId = voteEntry.secondKey; const vote = voteEntry.value; - const parsedMember = (await this.membersT.memberProfile(memberId)).toJSON() as ParsedMember; + const parsedMember = (await this.membersT.expectedMembership(memberId)).toJSON() as ParsedMember; votesWithMembers.push({ vote, member: { @@ -270,7 +270,7 @@ export default class ProposalsTransport extends BaseTransport { updatedAt: await this.chainT.blockTimestamp(post.updated_at.toNumber()), updatedAtBlock: post.updated_at.toNumber(), authorId: post.author_id, - author: (await this.membersT.memberProfile(post.author_id)).unwrapOr(null), + author: (await this.membersT.expectedMembership(post.author_id)), editsCount: post.edition_number.toNumber() }); } diff --git a/pioneer/packages/joy-utils/src/transport/storageProviders.ts b/pioneer/packages/joy-utils/src/transport/storageProviders.ts deleted file mode 100644 index c09a0413b0..0000000000 --- a/pioneer/packages/joy-utils/src/transport/storageProviders.ts +++ /dev/null @@ -1,19 +0,0 @@ -import BaseTransport from './base'; -import { IStorageRoleParameters } from '../types/storageProviders'; -import { RoleKeys } from '@joystream/types/members'; -import { Vec } from '@polkadot/types/'; -import { AccountId } from '@polkadot/types/interfaces'; - -export default class StorageProvidersTransport extends BaseTransport { - async roleParameters (): Promise { - const params = ( - await this.api.query.actors.parameters(RoleKeys.StorageProvider) - ).toJSON() as IStorageRoleParameters; - return params; - } - - async providers (): Promise { - const providers = (await this.actors.accountIdsByRole(RoleKeys.StorageProvider)) as Vec; - return providers.toArray(); - } -} diff --git a/pioneer/packages/joy-utils/src/transport/workingGroups.ts b/pioneer/packages/joy-utils/src/transport/workingGroups.ts index 31ed1ae954..afeaad6590 100644 --- a/pioneer/packages/joy-utils/src/transport/workingGroups.ts +++ b/pioneer/packages/joy-utils/src/transport/workingGroups.ts @@ -46,7 +46,7 @@ export default class WorkingGroupsTransport extends BaseTransport { ? (await this.rewardRelationship(worker.reward_relationship.unwrap())) : undefined; - const profile = await this.membersT.expectedMemberProfile(worker.member_id); + const profile = await this.membersT.expectedMembership(worker.member_id); return { group, workerId, worker, profile, stake, reward }; } @@ -135,7 +135,7 @@ export default class WorkingGroupsTransport extends BaseTransport { return { wgApplicationId, applicationId: appId.toNumber(), - member: await this.membersT.expectedMemberProfile(wgApplication.member_id), + member: await this.membersT.expectedMembership(wgApplication.member_id), roleAccout: wgApplication.role_account_id, stakes: { application: appStakingId.isSome ? (await this.stakeValue(appStakingId.unwrap())).toNumber() : 0, diff --git a/pioneer/packages/joy-utils/src/types/members.ts b/pioneer/packages/joy-utils/src/types/members.ts index c223484b1a..76f5882de1 100644 --- a/pioneer/packages/joy-utils/src/types/members.ts +++ b/pioneer/packages/joy-utils/src/types/members.ts @@ -4,7 +4,6 @@ export type ParsedMember = { handle: string; registered_at_block: number; registered_at_time: number; - roles: any[]; entry: { [k: string]: any }; root_account: string; controller_account: string; diff --git a/pioneer/packages/joy-utils/src/types/proposals.ts b/pioneer/packages/joy-utils/src/types/proposals.ts index 01aca9056c..c6d9f44110 100644 --- a/pioneer/packages/joy-utils/src/types/proposals.ts +++ b/pioneer/packages/joy-utils/src/types/proposals.ts @@ -1,5 +1,5 @@ import { ProposalId, VoteKind } from '@joystream/types/proposals'; -import { MemberId, Profile } from '@joystream/types/members'; +import { MemberId, Membership } from '@joystream/types/members'; import { ThreadId, PostId } from '@joystream/types/common'; import { ParsedMember } from './members'; @@ -98,7 +98,7 @@ export type ParsedPost = { createdAtBlock: number; updatedAt: Date; updatedAtBlock: number; - author: Profile | null; + author: Membership | null; authorId: MemberId; editsCount: number; }; diff --git a/pioneer/packages/joy-utils/src/types/workingGroups.ts b/pioneer/packages/joy-utils/src/types/workingGroups.ts index b317e82ba8..25f0cfbf82 100644 --- a/pioneer/packages/joy-utils/src/types/workingGroups.ts +++ b/pioneer/packages/joy-utils/src/types/workingGroups.ts @@ -1,5 +1,5 @@ import { Worker, Opening as WGOpening } from '@joystream/types/working-group'; -import { Profile } from '@joystream/types/members'; +import { Membership } from '@joystream/types/members'; import { OpeningId, Opening, ApplicationStage } from '@joystream/types/hiring'; import { AccountId } from '@polkadot/types/interfaces'; import { WorkingGroupKey } from '@joystream/types/common'; @@ -8,7 +8,7 @@ import { RewardRelationship } from '@joystream/types/recurring-rewards'; export type WorkerData = { workerId: number; worker: Worker; - profile: Profile; + profile: Membership; stake?: number; reward?: RewardRelationship; group: WorkingGroupKey; @@ -23,7 +23,7 @@ export type OpeningData = { export type ParsedApplication = { wgApplicationId: number; applicationId: number; - member: Profile; + member: Membership; roleAccout: AccountId; stakes: { application: number; diff --git a/tests/network-tests/package.json b/tests/network-tests/package.json index 5e9ed9bd34..0f4dc91ee5 100644 --- a/tests/network-tests/package.json +++ b/tests/network-tests/package.json @@ -14,7 +14,8 @@ }, "dependencies": { "@constantinople/types@npm:@joystream/types": "^0.10.0", - "@nicaea/types": "link:../../types", + "@nicaea/types@npm:@joystream/types": "^0.12.0", + "@alexandria/types": "link:../../types", "@polkadot/api": "^0.96.1", "@polkadot/keyring": "^1.7.0-beta.5", "@rome/types@npm:@joystream/types": "^0.7.0", diff --git a/tests/network-tests/src/iznik/tests/council/electingCouncilTest.ts b/tests/network-tests/src/iznik/tests/council/electingCouncilTest.ts index a888c6cc2f..0009bf0340 100644 --- a/tests/network-tests/src/iznik/tests/council/electingCouncilTest.ts +++ b/tests/network-tests/src/iznik/tests/council/electingCouncilTest.ts @@ -4,7 +4,7 @@ import { Keyring, WsProvider } from '@polkadot/api' import { setTestTimeout } from '../../utils/setTestTimeout' import BN from 'bn.js' import tap from 'tap' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { ApiWrapper } from '../../utils/apiWrapper' import { closeApi } from '../../utils/closeApi' import { BuyMembershipHappyCaseFixture } from '../fixtures/membershipModule' diff --git a/tests/network-tests/src/iznik/tests/fixtures/councilElectionModule.ts b/tests/network-tests/src/iznik/tests/fixtures/councilElectionModule.ts index 067ac6c390..96a8961093 100644 --- a/tests/network-tests/src/iznik/tests/fixtures/councilElectionModule.ts +++ b/tests/network-tests/src/iznik/tests/fixtures/councilElectionModule.ts @@ -2,7 +2,7 @@ import { ApiWrapper } from '../../utils/apiWrapper' import { KeyringPair } from '@polkadot/keyring/types' import BN from 'bn.js' import { assert } from 'chai' -import { Seat } from '@nicaea/types/council' +import { Seat } from '@alexandria/types/council' import { v4 as uuid } from 'uuid' import { Utils } from '../../utils/utils' import { Fixture } from './interfaces/fixture' diff --git a/tests/network-tests/src/iznik/tests/fixtures/proposalsModule.ts b/tests/network-tests/src/iznik/tests/fixtures/proposalsModule.ts index ef01cddd18..1622da4502 100644 --- a/tests/network-tests/src/iznik/tests/fixtures/proposalsModule.ts +++ b/tests/network-tests/src/iznik/tests/fixtures/proposalsModule.ts @@ -2,7 +2,7 @@ import { KeyringPair } from '@polkadot/keyring/types' import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper' import { v4 as uuid } from 'uuid' import BN from 'bn.js' -import { FillOpeningParameters } from '@nicaea/types/proposals' +import { FillOpeningParameters } from '@alexandria/types/proposals' import { Fixture } from './interfaces/fixture' import { Bytes, Option, u32 } from '@polkadot/types' import { Balance, BlockNumber } from '@polkadot/types/interfaces' @@ -13,9 +13,9 @@ import { ApplicationRationingPolicy, OpeningId, StakingPolicy, -} from '@nicaea/types/hiring' -import { RewardPolicy, SlashingTerms, WorkingGroupOpeningPolicyCommitment } from '@nicaea/types/working-group' -import { WorkingGroup } from '@nicaea/types/common' +} from '@alexandria/types/hiring' +import { RewardPolicy, SlashingTerms, WorkingGroupOpeningPolicyCommitment } from '@alexandria/types/working-group' +import { WorkingGroup } from '@alexandria/types/common' export class CreateWorkingGroupLeaderOpeningFixture implements Fixture { private apiWrapper: ApiWrapper diff --git a/tests/network-tests/src/iznik/tests/fixtures/workingGroupModule.ts b/tests/network-tests/src/iznik/tests/fixtures/workingGroupModule.ts index b162fb98fc..5d793af66b 100644 --- a/tests/network-tests/src/iznik/tests/fixtures/workingGroupModule.ts +++ b/tests/network-tests/src/iznik/tests/fixtures/workingGroupModule.ts @@ -6,21 +6,21 @@ import { Balance, BlockNumber, Event } from '@polkadot/types/interfaces' import { Keyring } from '@polkadot/api' import { Option, u32 } from '@polkadot/types' import { v4 as uuid } from 'uuid' -import { RewardRelationship } from '@nicaea/types/recurring-rewards' +import { RewardRelationship } from '@alexandria/types/recurring-rewards' import { Application, ApplicationIdToWorkerIdMap, SlashingTerms, Worker, WorkingGroupOpeningPolicyCommitment, -} from '@nicaea/types/working-group' +} from '@alexandria/types/working-group' import { Utils } from '../../utils/utils' import { ActivateOpeningAt, ApplicationRationingPolicy, Opening as HiringOpening, StakingPolicy, -} from '@nicaea/types/hiring' +} from '@alexandria/types/hiring' import { Fixture } from './interfaces/fixture' export class AddWorkerOpeningFixture implements Fixture { diff --git a/tests/network-tests/src/iznik/tests/membership/membershipCreationTest.ts b/tests/network-tests/src/iznik/tests/membership/membershipCreationTest.ts index 1592f58655..fddf9c2a54 100644 --- a/tests/network-tests/src/iznik/tests/membership/membershipCreationTest.ts +++ b/tests/network-tests/src/iznik/tests/membership/membershipCreationTest.ts @@ -3,7 +3,7 @@ import { Keyring, WsProvider } from '@polkadot/api' import { initConfig } from '../../utils/config' import { setTestTimeout } from '../../utils/setTestTimeout' import tap from 'tap' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { ApiWrapper } from '../../utils/apiWrapper' import { closeApi } from '../../utils/closeApi' import { BuyMembershipHappyCaseFixture, BuyMembershipWithInsufficienFundsFixture } from '../fixtures/membershipModule' diff --git a/tests/network-tests/src/iznik/tests/proposals/contentWorkingGroupMintCapacityProposalTest.ts b/tests/network-tests/src/iznik/tests/proposals/contentWorkingGroupMintCapacityProposalTest.ts index d7d7ba3b90..6ce49c4fb0 100644 --- a/tests/network-tests/src/iznik/tests/proposals/contentWorkingGroupMintCapacityProposalTest.ts +++ b/tests/network-tests/src/iznik/tests/proposals/contentWorkingGroupMintCapacityProposalTest.ts @@ -4,7 +4,7 @@ import { Keyring, WsProvider } from '@polkadot/api' import BN from 'bn.js' import { setTestTimeout } from '../../utils/setTestTimeout' import tap from 'tap' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper } from '../../utils/apiWrapper' import { ContentWorkingGroupMintCapacityProposalFixture } from '../fixtures/proposalsModule' diff --git a/tests/network-tests/src/iznik/tests/proposals/electionParametersProposalTest.ts b/tests/network-tests/src/iznik/tests/proposals/electionParametersProposalTest.ts index 208810c924..da51d59edd 100644 --- a/tests/network-tests/src/iznik/tests/proposals/electionParametersProposalTest.ts +++ b/tests/network-tests/src/iznik/tests/proposals/electionParametersProposalTest.ts @@ -4,7 +4,7 @@ import { Keyring, WsProvider } from '@polkadot/api' import BN from 'bn.js' import { setTestTimeout } from '../../utils/setTestTimeout' import tap from 'tap' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper } from '../../utils/apiWrapper' import { BuyMembershipHappyCaseFixture } from '../fixtures/membershipModule' diff --git a/tests/network-tests/src/iznik/tests/proposals/manageLeaderRoleTest.ts b/tests/network-tests/src/iznik/tests/proposals/manageLeaderRoleTest.ts index 0c698d172d..0008dd6bf3 100644 --- a/tests/network-tests/src/iznik/tests/proposals/manageLeaderRoleTest.ts +++ b/tests/network-tests/src/iznik/tests/proposals/manageLeaderRoleTest.ts @@ -4,7 +4,7 @@ import { Keyring, WsProvider } from '@polkadot/api' import BN from 'bn.js' import { setTestTimeout } from '../../utils/setTestTimeout' import tap from 'tap' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper' import { BuyMembershipHappyCaseFixture } from '../fixtures/membershipModule' diff --git a/tests/network-tests/src/iznik/tests/proposals/setLeadProposalTest.ts b/tests/network-tests/src/iznik/tests/proposals/setLeadProposalTest.ts index 815f9edbd5..8ec8d8889c 100644 --- a/tests/network-tests/src/iznik/tests/proposals/setLeadProposalTest.ts +++ b/tests/network-tests/src/iznik/tests/proposals/setLeadProposalTest.ts @@ -4,7 +4,7 @@ import { Keyring, WsProvider } from '@polkadot/api' import BN from 'bn.js' import { setTestTimeout } from '../../utils/setTestTimeout' import tap from 'tap' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper } from '../../utils/apiWrapper' import { Utils } from '../../utils/utils' diff --git a/tests/network-tests/src/iznik/tests/proposals/spendingProposalTest.ts b/tests/network-tests/src/iznik/tests/proposals/spendingProposalTest.ts index c821575c5c..b143fd0077 100644 --- a/tests/network-tests/src/iznik/tests/proposals/spendingProposalTest.ts +++ b/tests/network-tests/src/iznik/tests/proposals/spendingProposalTest.ts @@ -4,7 +4,7 @@ import { Keyring, WsProvider } from '@polkadot/api' import BN from 'bn.js' import { setTestTimeout } from '../../utils/setTestTimeout' import tap from 'tap' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper } from '../../utils/apiWrapper' import { Utils } from '../../utils/utils' diff --git a/tests/network-tests/src/iznik/tests/proposals/textProposalTest.ts b/tests/network-tests/src/iznik/tests/proposals/textProposalTest.ts index f1a3d2b35b..87a1e02491 100644 --- a/tests/network-tests/src/iznik/tests/proposals/textProposalTest.ts +++ b/tests/network-tests/src/iznik/tests/proposals/textProposalTest.ts @@ -4,7 +4,7 @@ import { Keyring, WsProvider } from '@polkadot/api' import BN from 'bn.js' import { setTestTimeout } from '../../utils/setTestTimeout' import tap from 'tap' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper } from '../../utils/apiWrapper' import { Utils } from '../../utils/utils' diff --git a/tests/network-tests/src/iznik/tests/proposals/updateRuntime.ts b/tests/network-tests/src/iznik/tests/proposals/updateRuntime.ts index 772718f6e8..6fd24071dc 100644 --- a/tests/network-tests/src/iznik/tests/proposals/updateRuntime.ts +++ b/tests/network-tests/src/iznik/tests/proposals/updateRuntime.ts @@ -4,7 +4,7 @@ import { Keyring, WsProvider } from '@polkadot/api' import BN from 'bn.js' import { setTestTimeout } from '../../utils/setTestTimeout' import tap from 'tap' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper } from '../../utils/apiWrapper' import { Utils } from '../../utils/utils' diff --git a/tests/network-tests/src/iznik/tests/proposals/validatorCountProposalTest.ts b/tests/network-tests/src/iznik/tests/proposals/validatorCountProposalTest.ts index 9564a009cd..8a6d8fbc56 100644 --- a/tests/network-tests/src/iznik/tests/proposals/validatorCountProposalTest.ts +++ b/tests/network-tests/src/iznik/tests/proposals/validatorCountProposalTest.ts @@ -4,7 +4,7 @@ import { Keyring, WsProvider } from '@polkadot/api' import BN from 'bn.js' import { setTestTimeout } from '../../utils/setTestTimeout' import tap from 'tap' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper } from '../../utils/apiWrapper' import { Utils } from '../../utils/utils' diff --git a/tests/network-tests/src/iznik/tests/proposals/workingGroupMintCapacityProposalTest.ts b/tests/network-tests/src/iznik/tests/proposals/workingGroupMintCapacityProposalTest.ts index 9ec7bba452..4a64bcdd49 100644 --- a/tests/network-tests/src/iznik/tests/proposals/workingGroupMintCapacityProposalTest.ts +++ b/tests/network-tests/src/iznik/tests/proposals/workingGroupMintCapacityProposalTest.ts @@ -4,7 +4,7 @@ import { Keyring, WsProvider } from '@polkadot/api' import BN from 'bn.js' import { setTestTimeout } from '../../utils/setTestTimeout' import tap from 'tap' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper' import { Utils } from '../../utils/utils' diff --git a/tests/network-tests/src/iznik/tests/workingGroup/atLeastValueBugTest.ts b/tests/network-tests/src/iznik/tests/workingGroup/atLeastValueBugTest.ts index 5db5cc00c2..27b0447348 100644 --- a/tests/network-tests/src/iznik/tests/workingGroup/atLeastValueBugTest.ts +++ b/tests/network-tests/src/iznik/tests/workingGroup/atLeastValueBugTest.ts @@ -1,5 +1,5 @@ import { initConfig } from '../../utils/config' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper' import { WsProvider, Keyring } from '@polkadot/api' diff --git a/tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsLeadTest.ts b/tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsLeadTest.ts index 3df2b5d494..45c0481a1c 100644 --- a/tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsLeadTest.ts +++ b/tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsLeadTest.ts @@ -1,5 +1,5 @@ import { initConfig } from '../../utils/config' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper' import { WsProvider, Keyring } from '@polkadot/api' diff --git a/tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsWorkerTest.ts b/tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsWorkerTest.ts index 3bb4aeb698..81a9e9c771 100644 --- a/tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsWorkerTest.ts +++ b/tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsWorkerTest.ts @@ -1,5 +1,5 @@ import { initConfig } from '../../utils/config' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper' import { WsProvider, Keyring } from '@polkadot/api' diff --git a/tests/network-tests/src/iznik/tests/workingGroup/workerApplicationHappyCaseTest.ts b/tests/network-tests/src/iznik/tests/workingGroup/workerApplicationHappyCaseTest.ts index 0b9e614cb0..92cb5396da 100644 --- a/tests/network-tests/src/iznik/tests/workingGroup/workerApplicationHappyCaseTest.ts +++ b/tests/network-tests/src/iznik/tests/workingGroup/workerApplicationHappyCaseTest.ts @@ -1,5 +1,5 @@ import { initConfig } from '../../utils/config' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper' import { WsProvider, Keyring } from '@polkadot/api' diff --git a/tests/network-tests/src/iznik/tests/workingGroup/workerApplicationRejectionCaseTest.ts b/tests/network-tests/src/iznik/tests/workingGroup/workerApplicationRejectionCaseTest.ts index 8b7250bad8..7faddf1b8a 100644 --- a/tests/network-tests/src/iznik/tests/workingGroup/workerApplicationRejectionCaseTest.ts +++ b/tests/network-tests/src/iznik/tests/workingGroup/workerApplicationRejectionCaseTest.ts @@ -1,5 +1,5 @@ import { initConfig } from '../../utils/config' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper' import { WsProvider, Keyring } from '@polkadot/api' diff --git a/tests/network-tests/src/iznik/tests/workingGroup/workerPayoutTest.ts b/tests/network-tests/src/iznik/tests/workingGroup/workerPayoutTest.ts index 1c335afe10..3719b589ff 100644 --- a/tests/network-tests/src/iznik/tests/workingGroup/workerPayoutTest.ts +++ b/tests/network-tests/src/iznik/tests/workingGroup/workerPayoutTest.ts @@ -1,5 +1,5 @@ import { initConfig } from '../../utils/config' -import { registerJoystreamTypes } from '@nicaea/types' +import { registerJoystreamTypes } from '@alexandria/types' import { closeApi } from '../../utils/closeApi' import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper' import { WsProvider, Keyring } from '@polkadot/api' diff --git a/tests/network-tests/src/iznik/utils/apiWrapper.ts b/tests/network-tests/src/iznik/utils/apiWrapper.ts index 10b8a89689..25d775f9cd 100644 --- a/tests/network-tests/src/iznik/utils/apiWrapper.ts +++ b/tests/network-tests/src/iznik/utils/apiWrapper.ts @@ -2,9 +2,9 @@ import { ApiPromise, WsProvider } from '@polkadot/api' import { Bytes, Option, u32, Vec } from '@polkadot/types' import { Codec } from '@polkadot/types/types' import { KeyringPair } from '@polkadot/keyring/types' -import { MemberId, PaidMembershipTerms, UserInfo } from '@nicaea/types/members' -import { Mint, MintId } from '@nicaea/types/mint' -import { Lead, LeadId } from '@nicaea/types/content-working-group' +import { MemberId, PaidMembershipTerms } from '@alexandria/types/members' +import { Mint, MintId } from '@alexandria/types/mint' +import { Lead, LeadId } from '@alexandria/types/content-working-group' import { Application, ApplicationIdToWorkerIdMap, @@ -14,16 +14,16 @@ import { Worker, WorkerId, WorkingGroupOpeningPolicyCommitment, -} from '@nicaea/types/working-group' -import { RoleParameters } from '@nicaea/types/roles' -import { Seat } from '@nicaea/types/council' +} from '@alexandria/types/working-group' +import { RoleParameters } from '@alexandria/types/roles' +import { Seat } from '@alexandria/types/council' import { AccountId, Balance, BalanceOf, BlockNumber, Event, EventRecord } from '@polkadot/types/interfaces' import BN from 'bn.js' import { SubmittableExtrinsic } from '@polkadot/api/types' import { Sender } from './sender' import { Utils } from './utils' -import { Stake, StakedState } from '@nicaea/types/stake' -import { RewardRelationship } from '@nicaea/types/recurring-rewards' +import { Stake, StakedState } from '@alexandria/types/stake' +import { RewardRelationship } from '@alexandria/types/recurring-rewards' import { ActivateOpeningAt, Application as HiringApplication, @@ -32,9 +32,9 @@ import { Opening as HiringOpening, OpeningId, StakingPolicy, -} from '@nicaea/types/hiring' -import { FillOpeningParameters } from '@nicaea/types/proposals' -import { WorkingGroup } from '@nicaea/types/common' +} from '@alexandria/types/hiring' +import { FillOpeningParameters } from '@alexandria/types/proposals' +import { WorkingGroup } from '@alexandria/types/common' export enum WorkingGroups { StorageWorkingGroup = 'storageWorkingGroup', @@ -74,7 +74,7 @@ export class ApiWrapper { expectFailure = false ): Promise { return this.sender.signAndSend( - this.api.tx.members.buyMembership(paidTermsId, new UserInfo({ 'handle': name, 'avatar_uri': '', 'about': '' })), + this.api.tx.members.buyMembership(paidTermsId, /* Handle: */ name, /* Avatar uri: */ '', /* About: */ ''), account, expectFailure ) @@ -120,7 +120,7 @@ export class ApiWrapper { public estimateBuyMembershipFee(account: KeyringPair, paidTermsId: number, name: string): BN { return this.estimateTxFee( - this.api.tx.members.buyMembership(paidTermsId, new UserInfo({ 'handle': name, 'avatar_uri': '', 'about': '' })) + this.api.tx.members.buyMembership(paidTermsId, /* Handle: */ name, /* Avatar uri: */ '', /* About: */ '') ) } diff --git a/tests/network-tests/src/iznik/utils/utils.ts b/tests/network-tests/src/iznik/utils/utils.ts index 6db1768733..5aaa6344c0 100644 --- a/tests/network-tests/src/iznik/utils/utils.ts +++ b/tests/network-tests/src/iznik/utils/utils.ts @@ -4,7 +4,7 @@ import { blake2AsHex } from '@polkadot/util-crypto' import BN from 'bn.js' import fs from 'fs' import Keyring, { decodeAddress } from '@polkadot/keyring' -import { Seat } from '@nicaea/types/council' +import { Seat } from '@alexandria/types/council' import { KeyringPair } from '@polkadot/keyring/types' import { v4 as uuid } from 'uuid' diff --git a/types/package.json b/types/package.json index cfd763c4e7..7225d95fa1 100644 --- a/types/package.json +++ b/types/package.json @@ -1,7 +1,7 @@ { "name": "@joystream/types", - "version": "0.12.0", - "description": "Types for Joystream Substrate Runtime - nicaea release", + "version": "0.13.0", + "description": "Types for Joystream Substrate Runtime - Alexandria release", "main": "index.js", "types": "index.d.ts", "scripts": { diff --git a/types/src/content-working-group/index.ts b/types/src/content-working-group/index.ts index 7ed55d6d4b..e3c5934949 100644 --- a/types/src/content-working-group/index.ts +++ b/types/src/content-working-group/index.ts @@ -20,6 +20,7 @@ import { OpeningId, ApplicationId, ApplicationRationingPolicy, StakingPolicy } f import { RewardRelationshipId } from '../recurring-rewards' import ChannelId from './ChannelId' +import { JoyEnum } from '../JoyEnum' export { ChannelId } export class CuratorId extends ActorId {} export class CuratorOpeningId extends OpeningId {} @@ -97,18 +98,10 @@ export class Channel extends JoyStruct { } } -export class CurationActor extends Enum { - constructor(value?: any, index?: number) { - super( - { - Lead: Null, - Curator: CuratorId, - }, - value, - index - ) - } -} +export class CurationActor extends JoyEnum({ + Lead: Null, + Curator: CuratorId, +}) {} export class Principal extends Enum { constructor(value?: any, index?: number) { @@ -489,20 +482,13 @@ export class ExitedLeadRole extends JoyStruct { } } -export class LeadRoleState extends Enum { - constructor(value?: any, index?: number) { - super( - { - Active: Null, - Exited: ExitedLeadRole, - }, - value, - index - ) - } -} +export class LeadRoleState extends JoyEnum({ + Active: Null, + Exited: ExitedLeadRole, +} as const) {} export type ILead = { + member_id: MemberId role_account: AccountId reward_relationship: Option inducted: BlockNumber @@ -512,6 +498,7 @@ export class Lead extends JoyStruct { constructor(value?: ILead) { super( { + member_id: MemberId, role_account: GenericAccountId, reward_relationship: Option.with(RewardRelationshipId), inducted: u32, @@ -521,6 +508,10 @@ export class Lead extends JoyStruct { ) } + get member_id(): MemberId { + return this.getField('member_id') + } + get role_account(): GenericAccountId { return this.getField('role_account') } diff --git a/types/src/members.ts b/types/src/members.ts index 914e24905d..b58ad35f0b 100644 --- a/types/src/members.ts +++ b/types/src/members.ts @@ -10,10 +10,9 @@ import { u128, Text, GenericAccountId, - Vec, } from '@polkadot/types' import { BlockNumber, Moment, BalanceOf } from '@polkadot/types/interfaces' -import { OptionText, JoyStruct } from './common' +import { JoyStruct } from './common' import AccountId from '@polkadot/types/primitive/Generic/AccountId' export class MemberId extends u64 {} @@ -38,48 +37,7 @@ export class EntryMethod extends Enum { } } -export enum RoleKeys { - StorageProvider = 'StorageProvider', - ChannelOwner = 'ChannelOwner', - CuratorLead = 'CuratorLead', - Curator = 'Curator', -} - -export class Role extends Enum { - constructor(value?: any, index?: number) { - super([RoleKeys.StorageProvider, RoleKeys.ChannelOwner, RoleKeys.CuratorLead, RoleKeys.Curator], value, index) - } -} - -export class ActorInRole extends Struct { - constructor(value?: any) { - super( - { - role: Role, - actor_id: ActorId, - }, - value - ) - } - - get role(): Role { - return this.get('role') as Role - } - - get actor_id(): ActorId { - return this.get('actor_id') as ActorId - } - - get isContentLead(): boolean { - return this.role.eq(RoleKeys.CuratorLead) - } - - get isCurator(): boolean { - return this.role.eq(RoleKeys.Curator) - } -} - -export type IProfile = { +export type IMembership = { handle: Text avatar_uri: Text about: Text @@ -90,10 +48,9 @@ export type IProfile = { subscription: Option root_account: AccountId controller_account: AccountId - roles: Vec } -export class Profile extends JoyStruct { - constructor(value?: IProfile) { +export class Membership extends JoyStruct { + constructor(value?: IMembership) { super( { handle: Text, @@ -106,7 +63,6 @@ export class Profile extends JoyStruct { subscription: Option.with(SubscriptionId), root_account: AccountId, controller_account: AccountId, - roles: Vec.with(ActorInRole), }, value ) @@ -151,29 +107,6 @@ export class Profile extends JoyStruct { get controller_account(): AccountId { return this.get('controller_account') as AccountId } - - get roles(): Vec { - return this.get('roles') as Vec - } -} - -export class UserInfo extends Struct { - constructor(value?: any) { - super( - { - handle: OptionText, - avatar_uri: OptionText, - about: OptionText, - }, - value - ) - } -} - -export type CheckedUserInfo = { - handle: Text - avatar_uri: Text - about: Text } export class PaidMembershipTerms extends Struct { @@ -204,20 +137,12 @@ export function registerMembershipTypes() { MemberId, PaidTermId, SubscriptionId, - Profile, - UserInfo, - CheckedUserInfo: { - handle: 'Text', - avatar_uri: 'Text', - about: 'Text', - }, + Membership, PaidMembershipTerms: { fee: 'BalanceOf', text: 'Text', }, - Role, ActorId, - ActorInRole, }) } catch (err) { console.error('Failed to register custom types of membership module', err) diff --git a/yarn.lock b/yarn.lock index da03e8d36c..d007779b1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,10 @@ # yarn lockfile v1 +"@alexandria/types@link:types": + version "0.0.0" + uid "" + "@babel/cli@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.7.4.tgz#38804334c8db40209f88c69a5c90998e60cca18b" @@ -1828,8 +1832,21 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@joystream/types@link:types": +"@joystream/types@^0.12.0", "@nicaea/types@npm:@joystream/types@^0.12.0": version "0.12.0" + resolved "https://registry.yarnpkg.com/@joystream/types/-/types-0.12.0.tgz#4033967ae2ac111f894fb4100e414f7cdbe95611" + integrity sha512-pHHYTbIa6V1C4k9aj+M6Fkwa2I2Br+4x7cuvREmrVh21GHjGuzoIwB74MfqFajdSTDQDZbjdixcYDES6uo3sUg== + dependencies: + "@polkadot/keyring" "^1.7.0-beta.5" + "@polkadot/types" "^0.96.1" + "@types/lodash" "^4.14.157" + "@types/vfile" "^4.0.0" + ajv "^6.11.0" + lodash "^4.17.15" + moment "^2.24.0" + +"@joystream/types@link:types": + version "0.13.0" dependencies: "@polkadot/keyring" "^1.7.0-beta.5" "@polkadot/types" "^0.96.1" @@ -2584,10 +2601,6 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" -"@nicaea/types@link:types": - version "0.0.0" - uid "" - "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b"