Skip to content

Commit

Permalink
Merge pull request #4708 from Joystream/apps-metaprotocol
Browse files Browse the repository at this point in the history
Apps release
  • Loading branch information
mnaamani committed Mar 22, 2023
2 parents 9f882a5 + f361c5a commit 4c8ed86
Show file tree
Hide file tree
Showing 62 changed files with 1,447 additions and 191 deletions.
118 changes: 117 additions & 1 deletion cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ $ npm install -g @joystream/cli
$ joystream-cli COMMAND
running command...
$ joystream-cli (-v|--version|version)
@joystream/cli/0.10.0 darwin-x64 node-v14.16.1
@joystream/cli/1.1.0 linux-x64 node-v14.18.0
$ joystream-cli --help [COMMAND]
USAGE
$ joystream-cli COMMAND
Expand Down Expand Up @@ -101,6 +101,8 @@ When using the CLI for the first time there are a few common steps you might wan
- [`joystream-cli api:inspect`](#joystream-cli-apiinspect)
- [`joystream-cli api:setQueryNodeEndpoint [ENDPOINT]`](#joystream-cli-apisetquerynodeendpoint-endpoint)
- [`joystream-cli api:setUri [URI]`](#joystream-cli-apiseturi-uri)
- [`joystream-cli apps:createApp`](#joystream-cli-appscreateapp)
- [`joystream-cli apps:updateApp`](#joystream-cli-appsupdateapp)
- [`joystream-cli autocomplete [SHELL]`](#joystream-cli-autocomplete-shell)
- [`joystream-cli content:addCuratorToGroup [GROUPID] [CURATORID]`](#joystream-cli-contentaddcuratortogroup-groupid-curatorid)
- [`joystream-cli content:channel CHANNELID`](#joystream-cli-contentchannel-channelid)
Expand Down Expand Up @@ -163,6 +165,9 @@ When using the CLI for the first time there are a few common steps you might wan
- [`joystream-cli membership:updateAccounts`](#joystream-cli-membershipupdateaccounts)
- [`joystream-cli sign-offline:signUnsignedTx`](#joystream-cli-sign-offlinesignunsignedtx)
- [`joystream-cli staking:validate`](#joystream-cli-stakingvalidate)
- [`joystream-cli util:decodeMessage`](#joystream-cli-utildecodemessage)
- [`joystream-cli util:encodeMessage`](#joystream-cli-utilencodemessage)
- [`joystream-cli util:messageStructure`](#joystream-cli-utilmessagestructure)
- [`joystream-cli working-groups:application WGAPPLICATIONID`](#joystream-cli-working-groupsapplication-wgapplicationid)
- [`joystream-cli working-groups:apply`](#joystream-cli-working-groupsapply)
- [`joystream-cli working-groups:cancelOpening OPENINGID`](#joystream-cli-working-groupscancelopening-openingid)
Expand Down Expand Up @@ -640,6 +645,39 @@ ARGUMENTS

_See code: [src/commands/api/setUri.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/api/setUri.ts)_

## `joystream-cli apps:createApp`

Creates app for current member

```
USAGE
$ joystream-cli apps:createApp
OPTIONS
-i, --input=input Path to JSON file containing app details
-s, --skip If true command won't prompt missing fields
--useMemberId=useMemberId Try using the specified member id as context whenever possible
```

_See code: [src/commands/apps/createApp.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/apps/createApp.ts)_

## `joystream-cli apps:updateApp`

Updates app of given ID

```
USAGE
$ joystream-cli apps:updateApp
OPTIONS
-i, --input=input Path to JSON file containing app details
-s, --skip If true command won't prompt missing fields
--appId=appId (required) ID of the app to update
--useMemberId=useMemberId Try using the specified member id as context whenever possible
```

_See code: [src/commands/apps/updateApp.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/apps/updateApp.ts)_

## `joystream-cli autocomplete [SHELL]`

display autocomplete installation instructions
Expand Down Expand Up @@ -1875,6 +1913,84 @@ OPTIONS

_See code: [src/commands/staking/validate.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/staking/validate.ts)_

## `joystream-cli util:decodeMessage`

Decode a protobuf message (from hex to json)

```
USAGE
$ joystream-cli util:decodeMessage
OPTIONS
--hex=hex
(required) Hex-encoded protobuf message'
--type=(AppActionMetadata|AppAction|BountyMetadata|BountyWorkData|ChannelMetadata|CouncilCandidacyNoteMetadata|ForumPo
stMetadata|ForumThreadMetadata|MembershipMetadata|ReactVideo|ReactComment|CreateComment|EditComment|DeleteComment|PinO
rUnpinComment|ModerateComment|BanOrUnbanMemberFromChannel|VideoReactionsPreference|CreateVideoCategory|AppMetadata|Cre
ateApp|UpdateApp|MemberRemarked|ChannelModeratorRemarked|ChannelOwnerRemarked|PersonMetadata|ProposalsDiscussionPostMe
tadata|SeriesMetadata|SeasonMetadata|GeoCoordiantes|NodeLocationMetadata|StorageBucketOperatorMetadata|DistributionBuc
ketOperatorMetadata|GeographicalArea|DistributionBucketFamilyMetadata|PublishedBeforeJoystream|License|MediaType|Subti
tleMetadata|VideoMetadata|ContentMetadata|OpeningMetadata|UpcomingOpeningMetadata|ApplicationMetadata|WorkingGroupMeta
data|SetGroupMetadata|AddUpcomingOpening|RemoveUpcomingOpening|WorkingGroupMetadataAction|ModeratePost|RemarkMetadataA
ction)
Type of the message
```

_See code: [src/commands/util/decodeMessage.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/util/decodeMessage.ts)_

## `joystream-cli util:encodeMessage`

Encode a protobuf message (from json to hex)

```
USAGE
$ joystream-cli util:encodeMessage
OPTIONS
-i, --input=input
Path to a file containing a JSON-encoded message
--jsonString=jsonString
JSON-encoded message input (eg. '{"videoId":1}'
--type=(AppActionMetadata|AppAction|BountyMetadata|BountyWorkData|ChannelMetadata|CouncilCandidacyNoteMetadata|ForumPo
stMetadata|ForumThreadMetadata|MembershipMetadata|ReactVideo|ReactComment|CreateComment|EditComment|DeleteComment|PinO
rUnpinComment|ModerateComment|BanOrUnbanMemberFromChannel|VideoReactionsPreference|CreateVideoCategory|AppMetadata|Cre
ateApp|UpdateApp|MemberRemarked|ChannelModeratorRemarked|ChannelOwnerRemarked|PersonMetadata|ProposalsDiscussionPostMe
tadata|SeriesMetadata|SeasonMetadata|GeoCoordiantes|NodeLocationMetadata|StorageBucketOperatorMetadata|DistributionBuc
ketOperatorMetadata|GeographicalArea|DistributionBucketFamilyMetadata|PublishedBeforeJoystream|License|MediaType|Subti
tleMetadata|VideoMetadata|ContentMetadata|OpeningMetadata|UpcomingOpeningMetadata|ApplicationMetadata|WorkingGroupMeta
data|SetGroupMetadata|AddUpcomingOpening|RemoveUpcomingOpening|WorkingGroupMetadataAction|ModeratePost|RemarkMetadataA
ction)
Type of the message
```

_See code: [src/commands/util/encodeMessage.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/util/encodeMessage.ts)_

## `joystream-cli util:messageStructure`

Show message structure (available fields, their types and indexes)

```
USAGE
$ joystream-cli util:messageStructure
OPTIONS
--type=(AppActionMetadata|AppAction|BountyMetadata|BountyWorkData|ChannelMetadata|CouncilCandidacyNoteMetadata|ForumPo
stMetadata|ForumThreadMetadata|MembershipMetadata|ReactVideo|ReactComment|CreateComment|EditComment|DeleteComment|PinO
rUnpinComment|ModerateComment|BanOrUnbanMemberFromChannel|VideoReactionsPreference|CreateVideoCategory|AppMetadata|Cre
ateApp|UpdateApp|MemberRemarked|ChannelModeratorRemarked|ChannelOwnerRemarked|PersonMetadata|ProposalsDiscussionPostMe
tadata|SeriesMetadata|SeasonMetadata|GeoCoordiantes|NodeLocationMetadata|StorageBucketOperatorMetadata|DistributionBuc
ketOperatorMetadata|GeographicalArea|DistributionBucketFamilyMetadata|PublishedBeforeJoystream|License|MediaType|Subti
tleMetadata|VideoMetadata|ContentMetadata|OpeningMetadata|UpcomingOpeningMetadata|ApplicationMetadata|WorkingGroupMeta
data|SetGroupMetadata|AddUpcomingOpening|RemoveUpcomingOpening|WorkingGroupMetadataAction|ModeratePost|RemarkMetadataA
ction)
Type of the message
```

_See code: [src/commands/util/messageStructure.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/util/messageStructure.ts)_

## `joystream-cli working-groups:application WGAPPLICATIONID`

Shows an overview of given application by Working Group Application ID
Expand Down
9 changes: 9 additions & 0 deletions cli/examples/content/CreateApp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "Example app",
"description": "Example app description",
"category": "blockchain",
"oneLiner": "best blokchain video platform",
"platforms": [
"web", "mobile"
]
}
9 changes: 9 additions & 0 deletions cli/examples/content/UpdateApp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "Updated example app",
"description": "Updated example app description",
"category": "trading",
"oneLiner": "best trading video platform",
"platforms": [
"web"
]
}
12 changes: 9 additions & 3 deletions cli/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@joystream/cli",
"description": "Command Line Interface for Joystream community and governance activities",
"version": "0.10.0",
"version": "1.1.0",
"author": "Leszek Wiesner",
"bin": {
"joystream-cli": "./bin/run"
Expand All @@ -11,8 +11,8 @@
"@apidevtools/json-schema-ref-parser": "^9.0.6",
"@apollo/client": "^3.3.13",
"@ffprobe-installer/ffprobe": "^1.4.1",
"@joystream/metadata-protobuf": "^2.5.0",
"@joystream/types": "^0.20.5",
"@joystream/metadata-protobuf": "^2.7.0",
"@joystream/types": "^1.0.0",
"@oclif/command": "^1.5.19",
"@oclif/config": "^1.14.0",
"@oclif/plugin-autocomplete": "^0.2.0",
Expand Down Expand Up @@ -118,6 +118,9 @@
"api": {
"description": "Inspect the substrate node api, perform lower-level api calls or change the current api provider uri"
},
"apps": {
"description": "Commands for creating and updating a metaprotocol App entity"
},
"working-groups": {
"description": "Working group lead and worker actions"
},
Expand All @@ -141,6 +144,9 @@
},
"sign-offline": {
"description": "Sign unsigned transactions, created with 'advanced-transactions', offline"
},
"util": {
"description": "General Joystream utilities"
}
}
},
Expand Down
5 changes: 5 additions & 0 deletions cli/src/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
IOpeningMetadata,
IWorkingGroupMetadata,
ISubtitleMetadata,
IAppMetadata,
} from '@joystream/metadata-protobuf'
import {
MembershipFieldsFragment,
Expand Down Expand Up @@ -340,3 +341,7 @@ export type OfflineTransactionData = {
callHash: string
}
}

export interface AppInputDetails extends IAppMetadata {
name: string
}
64 changes: 64 additions & 0 deletions cli/src/base/AppCommandBase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { IAppMetadata } from '@joystream/metadata-protobuf'
import MembershipsCommandBase from './MembershipsCommandBase'
import { Bytes } from '@polkadot/types/primitive'
import { u64 } from '@polkadot/types'
import chalk from 'chalk'

export default abstract class AppCommandBase extends MembershipsCommandBase {
appMetadataForm = {
description: 'App description?',
authKey: 'App public auth key?',
websiteUrl: 'Site URL where user can learn more about the app?',
useUri: 'App URL?',
platforms: 'Platforms supported by app? Format eg.: "web,mobile,native"',
category: 'Category of the app? Format eg.: "messaging"',
oneLiner: 'Tagline for the app?',
termsOfService: 'Terms of service for the app?',
bigIcon: 'Big icon URL?',
mediumIcon: 'Medium icon URL?',
smallIcon: 'Small icon URL?',
}

async promptAppMetadata(possibleFields?: Partial<IAppMetadata>): Promise<IAppMetadata> {
this.log(chalk.green('App form initiated.'))
this.log(chalk.yellow('To skip field just prompt empty input.'))
this.log(`${chalk.yellow('To unset field prompt only: ')} ${chalk.magentaBright('"-"')}${chalk.yellow('.')}`)
return Object.keys(this.appMetadataForm).reduce(async (prevPromise, key) => {
const prev = await prevPromise
const possibleValue = possibleFields?.[key as keyof IAppMetadata]
if (possibleValue) {
prev[key] = possibleValue
return prev
}
const promptValue = await this.simplePrompt<string>({ message: this.appMetadataForm[key as keyof IAppMetadata] })
if (promptValue === '') {
return prev
}
prev[key] = this.processValue(key, promptValue)
return prev
}, Promise.resolve({} as Record<string, string | string[]>))
}

processValue(key: string, value: string): string | string[] {
if (value === '-') {
return key === 'platforms' ? [''] : ''
}
if (key === 'platforms') {
return value.split(',').map((str: string) => str.trim())
}
return value
}

async sendRemark(message: Bytes): Promise<u64> {
const {
id,
membership: { controllerAccount },
} = await this.getRequiredMemberContext(true)
const keypair = await this.getDecodedPair(controllerAccount)
const result = await this.sendAndFollowNamedTx(keypair, 'members', 'memberRemark', [id, message])

const [memberId] = this.getEvent(result, 'members', 'MemberRemarked').data

return memberId
}
}
52 changes: 52 additions & 0 deletions cli/src/base/ProtobufMessageCommandBase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { flags } from '@oclif/command'
import * as allMessages from '@joystream/metadata-protobuf'
import allMessagesJson from '@joystream/metadata-protobuf/json'
import { AnyMetadataClass } from '@joystream/metadata-protobuf/types'
import DefaultCommandBase from './DefaultCommandBase'

type MessageTypeName = keyof typeof allMessages & keyof typeof allMessagesJson & string

/**
* Abstract base class for commands that require a single protobuf message context.
*/
export default abstract class ProtobufMessageCommandBase extends DefaultCommandBase {
protected MessageClass!: AnyMetadataClass<unknown>
protected messageJson!: Record<string, unknown>
protected type!: keyof typeof allMessages

static flags = {
type: flags.enum<MessageTypeName>({
options: Object.keys(allMessages) as MessageTypeName[],
required: false,
description: 'Type of the message',
}),
}

async init(): Promise<void> {
await super.init()
let {
flags: { type },
} = this.parse(this.constructor as typeof ProtobufMessageCommandBase)

if (!type) {
type = await this.promptForMessageType()
}

this.type = type
this.messageJson = allMessagesJson[type]
this.MessageClass = allMessages[type]
}

async promptForMessageType(message = 'Choose a message type'): Promise<MessageTypeName> {
return this.simplePrompt<MessageTypeName>({
type: 'list',
choices: Object.keys(allMessages)
.sort()
.map((c) => ({
value: c,
name: c,
})),
message,
})
}
}

0 comments on commit 4c8ed86

Please sign in to comment.