@streamr/cli-tools 103.0.0-rc.0 → 103.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +13 -7
- package/dist/src/client.js +3 -2
- package/dist/src/client.js.map +1 -1
- package/dist/src/command.d.ts +1 -0
- package/dist/src/command.js +1 -0
- package/dist/src/command.js.map +1 -1
- package/dist/src/resend.js +1 -1
- package/dist/src/resend.js.map +1 -1
- package/package.json +13 -7
- package/bin/streamr-internal-node-info.ts +0 -81
- package/bin/streamr-internal-operator-delegate.ts +0 -18
- package/bin/streamr-internal-operator-stake.ts +0 -18
- package/bin/streamr-internal-operator-undelegate.ts +0 -17
- package/bin/streamr-internal-operator-unstake.ts +0 -16
- package/bin/streamr-internal-show-sdk-config.ts +0 -11
- package/bin/streamr-internal-sponsorship-sponsor.ts +0 -18
- package/bin/streamr-internal-token-mint.ts +0 -21
- package/bin/streamr-internal-visualize-topology.ts +0 -122
- package/bin/streamr-internal.ts +0 -18
- package/bin/streamr-mock-data-generate.ts +0 -51
- package/bin/streamr-mock-data.ts +0 -10
- package/bin/streamr-storage-node-add-stream.ts +0 -13
- package/bin/streamr-storage-node-list-streams.ts +0 -21
- package/bin/streamr-storage-node-list.ts +0 -23
- package/bin/streamr-storage-node-register.ts +0 -14
- package/bin/streamr-storage-node-remove-stream.ts +0 -13
- package/bin/streamr-storage-node-show.ts +0 -13
- package/bin/streamr-storage-node-unregister.ts +0 -11
- package/bin/streamr-storage-node.ts +0 -16
- package/bin/streamr-stream-create.ts +0 -30
- package/bin/streamr-stream-grant-permission.ts +0 -10
- package/bin/streamr-stream-publish.ts +0 -78
- package/bin/streamr-stream-resend-from.ts +0 -33
- package/bin/streamr-stream-resend-last.ts +0 -31
- package/bin/streamr-stream-resend-range.ts +0 -39
- package/bin/streamr-stream-resend.ts +0 -12
- package/bin/streamr-stream-revoke-permission.ts +0 -10
- package/bin/streamr-stream-search.ts +0 -62
- package/bin/streamr-stream-show.ts +0 -37
- package/bin/streamr-stream-subscribe.ts +0 -43
- package/bin/streamr-stream.ts +0 -17
- package/bin/streamr-wallet-whoami.ts +0 -11
- package/bin/streamr-wallet.ts +0 -10
- package/bin/streamr.ts +0 -14
- package/jest.config.ts +0 -1
- package/src/client.ts +0 -34
- package/src/command.ts +0 -53
- package/src/common.ts +0 -43
- package/src/config.ts +0 -56
- package/src/logLevel.ts +0 -9
- package/src/permission.ts +0 -53
- package/src/resend.ts +0 -37
- package/test/environment.test.ts +0 -32
- package/test/internal-operator.test.ts +0 -57
- package/test/internal-sponsorship-sponsor.test.ts +0 -28
- package/test/mock-data.test.ts +0 -33
- package/test/storage-node.test.ts +0 -62
- package/test/stream-create.test.ts +0 -26
- package/test/stream-permission.test.ts +0 -29
- package/test/stream-publish-subscribe.test.ts +0 -108
- package/test/stream-resend.test.ts +0 -66
- package/test/stream-search.test.ts +0 -24
- package/test/stream-show.test.ts +0 -31
- package/test/utils.ts +0 -86
- package/test/wallet.test.ts +0 -11
- package/tsconfig.json +0 -3
- package/tsconfig.node.json +0 -16
package/src/config.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import os from 'os'
|
|
3
|
-
import { readFileSync } from 'fs'
|
|
4
|
-
import { StreamrClientConfig } from '@streamr/sdk'
|
|
5
|
-
|
|
6
|
-
interface Config {
|
|
7
|
-
client: StreamrClientConfig
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/*
|
|
11
|
-
* Validate that the config contains at least one root level element: the "client" block.
|
|
12
|
-
* The values of the "client" blocks are validated by StreamrClient when the configuration
|
|
13
|
-
* is used.
|
|
14
|
-
*
|
|
15
|
-
* We don't check other root level elements. It is ok to use a Broker config file as
|
|
16
|
-
* a cli-tools config file. In that case the file contains e.g. "plugins" block,
|
|
17
|
-
* but cli-tools can just ignore that block.
|
|
18
|
-
*/
|
|
19
|
-
const validateConfig = (config: any, fileName: string): void | never => {
|
|
20
|
-
const CLIENT_CONFIG_BLOCK = 'client'
|
|
21
|
-
if (config[CLIENT_CONFIG_BLOCK] === undefined) {
|
|
22
|
-
throw new Error(`Missing root element "${CLIENT_CONFIG_BLOCK}" in ${fileName}`)
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const tryReadConfigFile = (fileName: string): Config | undefined | never => {
|
|
27
|
-
let content
|
|
28
|
-
try {
|
|
29
|
-
content = readFileSync(fileName, 'utf8')
|
|
30
|
-
} catch {
|
|
31
|
-
return undefined
|
|
32
|
-
}
|
|
33
|
-
const json = JSON.parse(content)
|
|
34
|
-
validateConfig(json, fileName)
|
|
35
|
-
return json
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export const getConfig = (id?: string): Config | undefined => {
|
|
39
|
-
const CONFIG_DIRECTORY = path.join(os.homedir(), '.streamr', 'config')
|
|
40
|
-
if (id !== undefined) {
|
|
41
|
-
const fileNames = [
|
|
42
|
-
id,
|
|
43
|
-
path.join(CONFIG_DIRECTORY, `${id}.json`),
|
|
44
|
-
]
|
|
45
|
-
for (const fileName of fileNames) {
|
|
46
|
-
const content = tryReadConfigFile(fileName)
|
|
47
|
-
if (content !== undefined) {
|
|
48
|
-
return content
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
throw new Error('Config file not found')
|
|
52
|
-
} else {
|
|
53
|
-
const fileName = path.join(CONFIG_DIRECTORY, `default.json`)
|
|
54
|
-
return tryReadConfigFile(fileName)
|
|
55
|
-
}
|
|
56
|
-
}
|
package/src/logLevel.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Minimal logging for NetworkNode and other users of Logger.ts in the network package.
|
|
3
|
-
* This file needs to be imported before any of the network package classes
|
|
4
|
-
* so that the environment variable is updated before any Logger instances are created.
|
|
5
|
-
* The import is needed for the files where network packages are used (typically
|
|
6
|
-
* the files which call createClientCommand()).
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
process.env.LOG_LEVEL = process.env.LOG_LEVEL ?? 'error'
|
package/src/permission.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { Argument } from 'commander'
|
|
2
|
-
import { PermissionAssignment, Stream, StreamPermission, StreamrClient } from '@streamr/sdk'
|
|
3
|
-
import { createClientCommand } from './command'
|
|
4
|
-
|
|
5
|
-
const PUBLIC_USER_ID = 'public'
|
|
6
|
-
|
|
7
|
-
export const PERMISSIONS = new Map<string, StreamPermission>([
|
|
8
|
-
['subscribe', StreamPermission.SUBSCRIBE],
|
|
9
|
-
['publish', StreamPermission.PUBLISH],
|
|
10
|
-
['edit', StreamPermission.EDIT],
|
|
11
|
-
['delete', StreamPermission.DELETE],
|
|
12
|
-
['grant', StreamPermission.GRANT]
|
|
13
|
-
])
|
|
14
|
-
|
|
15
|
-
export const getPermission = (id: string): StreamPermission | never => {
|
|
16
|
-
const result = PERMISSIONS.get(id)
|
|
17
|
-
if (result === undefined) {
|
|
18
|
-
throw new Error(`unknown permission: ${id}`)
|
|
19
|
-
}
|
|
20
|
-
return result
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const getPermissionId = (permission: StreamPermission): string => {
|
|
24
|
-
return Array.from(PERMISSIONS.entries()).find(([_id, p]) => p === permission)![0]
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const runModifyPermissionsCommand = (
|
|
28
|
-
modify: (stream: Stream, assignment: PermissionAssignment) => Promise<void>,
|
|
29
|
-
modification: string,
|
|
30
|
-
): void => {
|
|
31
|
-
createClientCommand(async (client: StreamrClient, streamId: string, user: string, permissionIds: string[]) => {
|
|
32
|
-
const stream = await client.getStream(streamId)
|
|
33
|
-
const permissions: StreamPermission[] = permissionIds.map((permissionId) => getPermission(permissionId))
|
|
34
|
-
let assignment: PermissionAssignment
|
|
35
|
-
if (user === PUBLIC_USER_ID) {
|
|
36
|
-
assignment = {
|
|
37
|
-
permissions,
|
|
38
|
-
public: true
|
|
39
|
-
}
|
|
40
|
-
} else {
|
|
41
|
-
assignment = {
|
|
42
|
-
permissions,
|
|
43
|
-
userId: user
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
await modify(stream, assignment)
|
|
47
|
-
})
|
|
48
|
-
.addArgument(new Argument('<streamId>'))
|
|
49
|
-
.addArgument(new Argument('<user>'))
|
|
50
|
-
.addArgument(new Argument('<permissions...>').choices(Array.from(PERMISSIONS.keys())))
|
|
51
|
-
.description(`${modification} permission: use keyword "public" as a user to ${modification} a public permission`)
|
|
52
|
-
.parseAsync(process.argv)
|
|
53
|
-
}
|
package/src/resend.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { StreamrClient, ResendOptions } from '@streamr/sdk'
|
|
2
|
-
|
|
3
|
-
export const assertBothOrNoneDefined = <T extends object>(
|
|
4
|
-
option1: keyof T,
|
|
5
|
-
option2: keyof T,
|
|
6
|
-
errorMessage: string,
|
|
7
|
-
commandOptions: T
|
|
8
|
-
): void | never => {
|
|
9
|
-
if ((option1 in commandOptions && !(option2 in commandOptions)) || (option2 in commandOptions && !(option1 in commandOptions))) {
|
|
10
|
-
console.error(`option ${errorMessage}`)
|
|
11
|
-
process.exit(1)
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const resend = async (
|
|
16
|
-
streamId: string,
|
|
17
|
-
resendOpts: ResendOptions,
|
|
18
|
-
client: StreamrClient,
|
|
19
|
-
subscribe: boolean
|
|
20
|
-
): Promise<void> => {
|
|
21
|
-
try {
|
|
22
|
-
const handler = (message: any) => {
|
|
23
|
-
console.info(JSON.stringify(message))
|
|
24
|
-
}
|
|
25
|
-
if (subscribe) {
|
|
26
|
-
await client.subscribe({
|
|
27
|
-
stream: streamId,
|
|
28
|
-
resend: resendOpts
|
|
29
|
-
}, handler)
|
|
30
|
-
} else {
|
|
31
|
-
await client.resend(streamId, resendOpts, handler)
|
|
32
|
-
}
|
|
33
|
-
} catch (err) {
|
|
34
|
-
console.error(err.message ? err.message : err)
|
|
35
|
-
process.exit(1)
|
|
36
|
-
}
|
|
37
|
-
}
|
package/test/environment.test.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { randomString } from '@streamr/utils'
|
|
2
|
-
import fs from 'fs/promises'
|
|
3
|
-
import { runCommand } from './utils'
|
|
4
|
-
import { StreamrClientConfig } from '@streamr/sdk'
|
|
5
|
-
|
|
6
|
-
const POLYGON_AMOY_CHAIN_ID = 80002
|
|
7
|
-
|
|
8
|
-
describe('env command line option', () => {
|
|
9
|
-
|
|
10
|
-
it('takes precedence over client.environment config', async () => {
|
|
11
|
-
const configFileName = `test-${randomString(10)}.json`
|
|
12
|
-
await fs.writeFile(configFileName, JSON.stringify({
|
|
13
|
-
client: {
|
|
14
|
-
environment: 'dev2'
|
|
15
|
-
}
|
|
16
|
-
}))
|
|
17
|
-
const outputLines = await runCommand(`internal show-sdk-config --env polygonAmoy --config ${configFileName}`, {
|
|
18
|
-
devEnvironment: false
|
|
19
|
-
})
|
|
20
|
-
const outputJson: StreamrClientConfig = JSON.parse(outputLines.join(''))
|
|
21
|
-
await fs.unlink(configFileName)
|
|
22
|
-
expect(outputJson.contracts!.ethereumNetwork!.chainId).toBe(POLYGON_AMOY_CHAIN_ID)
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it('invalid value', async () => {
|
|
26
|
-
const outputLines = await runCommand('stream show foobar --env invalid-environment', {
|
|
27
|
-
devEnvironment: false
|
|
28
|
-
})
|
|
29
|
-
expect(outputLines).toHaveLength(1)
|
|
30
|
-
expect(outputLines[0]).toEqual('env must be one of: "polygon", "polygonAmoy", "dev2"')
|
|
31
|
-
}, 60 * 1000)
|
|
32
|
-
})
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { _operatorContractUtils } from '@streamr/sdk'
|
|
2
|
-
import { createTestPrivateKey, createTestWallet } from '@streamr/test-utils'
|
|
3
|
-
import { wait } from '@streamr/utils'
|
|
4
|
-
import { parseEther } from 'ethers'
|
|
5
|
-
import { createTestClient, runCommand } from './utils'
|
|
6
|
-
|
|
7
|
-
const DELEGATION_AMOUNT = '20000'
|
|
8
|
-
const STAKE_AMOUNT = '10000'
|
|
9
|
-
const SELF_DELEGATION_AMOUNT = '100000'
|
|
10
|
-
const MINIMUM_DELEGATION_SECONDS = 1 // the config value defined in StreamrEnvDeployer in network-contracts repo
|
|
11
|
-
|
|
12
|
-
describe('operator', () => {
|
|
13
|
-
|
|
14
|
-
it('happy path', async () => {
|
|
15
|
-
const client = createTestClient(await createTestPrivateKey({ gas: true }))
|
|
16
|
-
const stream = await client.createStream('/test')
|
|
17
|
-
const sponsorshipContract = await _operatorContractUtils.deploySponsorshipContract({
|
|
18
|
-
streamId: stream.id,
|
|
19
|
-
deployer: await createTestWallet({ gas: true })
|
|
20
|
-
})
|
|
21
|
-
const sponsorshipAddress: string = await sponsorshipContract.getAddress()
|
|
22
|
-
const operator = await createTestWallet({ gas: true, tokens: true })
|
|
23
|
-
const operatorContract = await _operatorContractUtils.deployOperatorContract({
|
|
24
|
-
deployer: operator
|
|
25
|
-
})
|
|
26
|
-
await _operatorContractUtils.delegate(operator, await operatorContract.getAddress(), parseEther(SELF_DELEGATION_AMOUNT))
|
|
27
|
-
const delegator = await createTestWallet({ gas: true, tokens: true })
|
|
28
|
-
const operatorAddress: string = await operatorContract.getAddress()
|
|
29
|
-
|
|
30
|
-
// delegate
|
|
31
|
-
await runCommand(`internal operator-delegate ${operatorAddress} ${DELEGATION_AMOUNT}`, {
|
|
32
|
-
privateKey: delegator.privateKey
|
|
33
|
-
})
|
|
34
|
-
expect(await operatorContract.balanceInData(await delegator.getAddress())).toEqual(parseEther(DELEGATION_AMOUNT))
|
|
35
|
-
|
|
36
|
-
// stake
|
|
37
|
-
await runCommand(`internal operator-stake ${operatorAddress} ${sponsorshipAddress} ${STAKE_AMOUNT}`, {
|
|
38
|
-
privateKey: operator.privateKey
|
|
39
|
-
})
|
|
40
|
-
expect(await operatorContract.totalStakedIntoSponsorshipsWei()).toEqual(parseEther(STAKE_AMOUNT))
|
|
41
|
-
|
|
42
|
-
// unstake
|
|
43
|
-
await runCommand(`internal operator-unstake ${operatorAddress} ${sponsorshipAddress}`, {
|
|
44
|
-
privateKey: operator.privateKey
|
|
45
|
-
})
|
|
46
|
-
expect(await operatorContract.totalStakedIntoSponsorshipsWei()).toEqual(0n)
|
|
47
|
-
|
|
48
|
-
// undelegate
|
|
49
|
-
await wait(MINIMUM_DELEGATION_SECONDS)
|
|
50
|
-
await runCommand(`internal operator-undelegate ${operatorAddress} ${DELEGATION_AMOUNT}`, {
|
|
51
|
-
privateKey: delegator.privateKey
|
|
52
|
-
})
|
|
53
|
-
expect(await operatorContract.balanceInData(await delegator.getAddress())).toEqual(0n)
|
|
54
|
-
|
|
55
|
-
await client.destroy()
|
|
56
|
-
}, 30 * 1000)
|
|
57
|
-
})
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { _operatorContractUtils } from '@streamr/sdk'
|
|
2
|
-
import { createTestPrivateKey, createTestWallet } from '@streamr/test-utils'
|
|
3
|
-
import { parseEther } from 'ethers'
|
|
4
|
-
import { createTestClient, runCommand } from './utils'
|
|
5
|
-
|
|
6
|
-
const SPONSOR_AMOUNT = '12345'
|
|
7
|
-
|
|
8
|
-
describe('sponsorship-sponsor', () => {
|
|
9
|
-
|
|
10
|
-
it('happy path', async () => {
|
|
11
|
-
const client = createTestClient(await createTestPrivateKey({ gas: true }))
|
|
12
|
-
const stream = await client.createStream('/test')
|
|
13
|
-
const sponsorshipContract = await _operatorContractUtils.deploySponsorshipContract({
|
|
14
|
-
streamId: stream.id,
|
|
15
|
-
deployer: await createTestWallet({ gas: true })
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
const sponsorer = await createTestWallet({ gas: true, tokens: true })
|
|
19
|
-
const sponsorshipAddress: string = await sponsorshipContract.getAddress()
|
|
20
|
-
await runCommand(`internal sponsorship-sponsor ${sponsorshipAddress} ${SPONSOR_AMOUNT}`, {
|
|
21
|
-
privateKey: sponsorer.privateKey
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
const remainingWei = await sponsorshipContract.connect(sponsorer, _operatorContractUtils.getProvider()).remainingWei()
|
|
25
|
-
expect(remainingWei).toEqual(parseEther(SPONSOR_AMOUNT))
|
|
26
|
-
await client.destroy()
|
|
27
|
-
})
|
|
28
|
-
})
|
package/test/mock-data.test.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { collect } from '@streamr/utils'
|
|
2
|
-
import 'jest-extended'
|
|
3
|
-
import { startCommand } from './utils'
|
|
4
|
-
|
|
5
|
-
describe('mock-data', () => {
|
|
6
|
-
|
|
7
|
-
it('generate', async () => {
|
|
8
|
-
const abortController = new AbortController()
|
|
9
|
-
const outputIterable = startCommand('mock-data generate', {
|
|
10
|
-
abortSignal: abortController.signal,
|
|
11
|
-
devEnvironment: false
|
|
12
|
-
})
|
|
13
|
-
const firstLine = (await collect(outputIterable, 1))[0]
|
|
14
|
-
abortController.abort()
|
|
15
|
-
const json = JSON.parse(firstLine)
|
|
16
|
-
expect(json).toBeObject()
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
it('generate binary', async () => {
|
|
20
|
-
const abortController = new AbortController()
|
|
21
|
-
const outputIterable = startCommand('mock-data generate --binary --min-length 32 --max-length 64', {
|
|
22
|
-
abortSignal: abortController.signal,
|
|
23
|
-
devEnvironment: false
|
|
24
|
-
})
|
|
25
|
-
const firstLine = (await collect(outputIterable, 1))[0]
|
|
26
|
-
abortController.abort()
|
|
27
|
-
expect(firstLine).toMatch(/^[0-9a-f]+$/)
|
|
28
|
-
const lengthInBytes = firstLine.length / 2
|
|
29
|
-
expect(lengthInBytes).toBeGreaterThanOrEqual(32)
|
|
30
|
-
expect(lengthInBytes).toBeLessThanOrEqual(64)
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
})
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { StreamID } from '@streamr/sdk'
|
|
2
|
-
import { createTestPrivateKey, createTestWallet } from '@streamr/test-utils'
|
|
3
|
-
import { until } from '@streamr/utils'
|
|
4
|
-
import 'jest-extended'
|
|
5
|
-
import { DOCKER_DEV_STORAGE_NODE, createTestClient, runCommand } from './utils'
|
|
6
|
-
|
|
7
|
-
const isStored = async (streamId: StreamID): Promise<boolean> => {
|
|
8
|
-
const output = await runCommand(`storage-node list-streams ${DOCKER_DEV_STORAGE_NODE}`)
|
|
9
|
-
return output.join().includes(streamId)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
describe('storage node', () => {
|
|
13
|
-
|
|
14
|
-
it('add and remove stream', async () => {
|
|
15
|
-
const privateKey = await createTestPrivateKey({ gas: true })
|
|
16
|
-
const client = createTestClient(privateKey)
|
|
17
|
-
const stream = await client.createStream(`/${Date.now()}`)
|
|
18
|
-
await client.destroy()
|
|
19
|
-
await runCommand(`storage-node add-stream ${DOCKER_DEV_STORAGE_NODE} ${stream.id}`, {
|
|
20
|
-
privateKey
|
|
21
|
-
})
|
|
22
|
-
await until(async () => await isStored(stream.id) === true, 15 * 1000, 1000)
|
|
23
|
-
await runCommand(`storage-node remove-stream ${DOCKER_DEV_STORAGE_NODE} ${stream.id}`, {
|
|
24
|
-
privateKey
|
|
25
|
-
})
|
|
26
|
-
await until(async () => await isStored(stream.id) === false, 15 * 1000, 1000)
|
|
27
|
-
}, 80 * 1000)
|
|
28
|
-
|
|
29
|
-
it('list nodes', async () => {
|
|
30
|
-
const outputLines = await runCommand('storage-node list')
|
|
31
|
-
expect(outputLines.join()).toMatch(DOCKER_DEV_STORAGE_NODE.toLowerCase())
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
it('register storage node, show info, and finally unregister', async () => {
|
|
35
|
-
const { privateKey, address } = await createTestWallet({ gas: true })
|
|
36
|
-
|
|
37
|
-
const urls = 'http://foobar.com,http://foobar.org'
|
|
38
|
-
await runCommand(`storage-node register ${urls}`, {
|
|
39
|
-
privateKey
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
// account for The Graph delay
|
|
43
|
-
await until(async () => {
|
|
44
|
-
const outputLines = await runCommand('storage-node list')
|
|
45
|
-
return outputLines.join().includes(address.toLowerCase())
|
|
46
|
-
}, 10 * 1000, 500)
|
|
47
|
-
|
|
48
|
-
const outputLines = await runCommand(`storage-node show ${address}`)
|
|
49
|
-
expect(outputLines.join()).toContain('http://foobar.com')
|
|
50
|
-
expect(outputLines.join()).toContain('http://foobar.org')
|
|
51
|
-
|
|
52
|
-
await runCommand('storage-node unregister', {
|
|
53
|
-
privateKey
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
// account for The Graph delay
|
|
57
|
-
await until(async () => {
|
|
58
|
-
const outputLines = await runCommand('storage-node list')
|
|
59
|
-
return !outputLines.join().includes(address.toLowerCase())
|
|
60
|
-
}, 10 * 1000, 500)
|
|
61
|
-
}, 80 * 1000)
|
|
62
|
-
})
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { createTestPrivateKey } from '@streamr/test-utils'
|
|
2
|
-
import { Wallet } from 'ethers'
|
|
3
|
-
import { createTestClient, runCommand } from './utils'
|
|
4
|
-
|
|
5
|
-
describe('create stream', () => {
|
|
6
|
-
|
|
7
|
-
it('happy path', async () => {
|
|
8
|
-
const privateKey = await createTestPrivateKey({ gas: true })
|
|
9
|
-
const address = new Wallet(privateKey).address.toLowerCase()
|
|
10
|
-
const path = `/${Date.now()}`
|
|
11
|
-
const streamId = `${address}${path}`
|
|
12
|
-
const outputLines = await runCommand(`stream create ${path}`, {
|
|
13
|
-
privateKey
|
|
14
|
-
})
|
|
15
|
-
const outputJson = JSON.parse(outputLines.join(''))
|
|
16
|
-
expect(outputJson).toMatchObject({
|
|
17
|
-
id: streamId,
|
|
18
|
-
partitions: 1
|
|
19
|
-
})
|
|
20
|
-
const client = createTestClient()
|
|
21
|
-
const stream = await client.getStream(streamId)
|
|
22
|
-
expect(await stream.getPartitionCount()).toBe(1)
|
|
23
|
-
await client.destroy()
|
|
24
|
-
}, 20 * 1000)
|
|
25
|
-
|
|
26
|
-
})
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { StreamPermission } from '@streamr/sdk'
|
|
2
|
-
import { createTestPrivateKey, randomUserId } from '@streamr/test-utils'
|
|
3
|
-
import 'jest-extended'
|
|
4
|
-
import { createTestClient, runCommand } from './utils'
|
|
5
|
-
|
|
6
|
-
describe('permission', () => {
|
|
7
|
-
|
|
8
|
-
it('grant and revoke', async () => {
|
|
9
|
-
const privateKey = await createTestPrivateKey({ gas: true })
|
|
10
|
-
const client = createTestClient(privateKey)
|
|
11
|
-
const stream = await client.createStream(`/${Date.now()}`)
|
|
12
|
-
const otherUser = randomUserId()
|
|
13
|
-
const hasPermission = () => client.hasPermission({
|
|
14
|
-
userId: otherUser,
|
|
15
|
-
permission: StreamPermission.PUBLISH,
|
|
16
|
-
streamId: stream.id,
|
|
17
|
-
allowPublic: false
|
|
18
|
-
})
|
|
19
|
-
await runCommand(`stream grant-permission ${stream.id} ${otherUser} publish`, {
|
|
20
|
-
privateKey
|
|
21
|
-
})
|
|
22
|
-
expect(await hasPermission()).toBeTrue()
|
|
23
|
-
await runCommand(`stream revoke-permission ${stream.id} ${otherUser} publish`, {
|
|
24
|
-
privateKey
|
|
25
|
-
})
|
|
26
|
-
expect(await hasPermission()).toBeFalse()
|
|
27
|
-
await client.destroy()
|
|
28
|
-
}, 40 * 1000)
|
|
29
|
-
})
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { StreamPermission } from '@streamr/sdk'
|
|
2
|
-
import { createTestPrivateKey } from '@streamr/test-utils'
|
|
3
|
-
import { collect } from '@streamr/utils'
|
|
4
|
-
import { Wallet } from 'ethers'
|
|
5
|
-
import { createTestClient, runCommand, startCommand } from './utils'
|
|
6
|
-
|
|
7
|
-
const TIMEOUT = 30 * 1000
|
|
8
|
-
|
|
9
|
-
describe('publish and subscribe', () => {
|
|
10
|
-
|
|
11
|
-
let publisherPrivateKey: string
|
|
12
|
-
let subscriberPrivateKey: string
|
|
13
|
-
let streamId: string
|
|
14
|
-
|
|
15
|
-
beforeAll(async () => {
|
|
16
|
-
publisherPrivateKey = await createTestPrivateKey({ gas: true })
|
|
17
|
-
subscriberPrivateKey = await createTestPrivateKey({ gas: true })
|
|
18
|
-
const client = createTestClient(publisherPrivateKey)
|
|
19
|
-
const stream = await client.createStream(`/${Date.now()}`)
|
|
20
|
-
await stream.grantPermissions({
|
|
21
|
-
userId: new Wallet(subscriberPrivateKey).address,
|
|
22
|
-
permissions: [StreamPermission.SUBSCRIBE]
|
|
23
|
-
})
|
|
24
|
-
streamId = stream.id
|
|
25
|
-
await client.destroy()
|
|
26
|
-
}, TIMEOUT)
|
|
27
|
-
|
|
28
|
-
function publishViaCliCommand() {
|
|
29
|
-
setImmediate(async () => {
|
|
30
|
-
await runCommand(`stream publish ${streamId}`, {
|
|
31
|
-
inputLines: [JSON.stringify({ foo: 123 })],
|
|
32
|
-
privateKey: publisherPrivateKey
|
|
33
|
-
})
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
it('happy path', async () => {
|
|
38
|
-
const subscriberAbortController = new AbortController()
|
|
39
|
-
const subscriberOutputIterable = startCommand(`stream subscribe ${streamId}`, {
|
|
40
|
-
privateKey: subscriberPrivateKey,
|
|
41
|
-
abortSignal: subscriberAbortController.signal
|
|
42
|
-
})
|
|
43
|
-
publishViaCliCommand()
|
|
44
|
-
const receivedMessage = (await collect(subscriberOutputIterable, 1))[0]
|
|
45
|
-
subscriberAbortController.abort()
|
|
46
|
-
expect(JSON.parse(receivedMessage)).toEqual({
|
|
47
|
-
foo: 123
|
|
48
|
-
})
|
|
49
|
-
}, TIMEOUT)
|
|
50
|
-
|
|
51
|
-
it('raw subscription', async () => {
|
|
52
|
-
const subscriberAbortController = new AbortController()
|
|
53
|
-
const subscriberOutputIterable = startCommand(`stream subscribe ${streamId} --raw`, {
|
|
54
|
-
privateKey: subscriberPrivateKey,
|
|
55
|
-
abortSignal: subscriberAbortController.signal,
|
|
56
|
-
})
|
|
57
|
-
publishViaCliCommand()
|
|
58
|
-
const receivedMessage = (await collect(subscriberOutputIterable, 1))[0]
|
|
59
|
-
subscriberAbortController.abort()
|
|
60
|
-
expect(receivedMessage).toMatch(/^[0-9a-fA-F]+$/)
|
|
61
|
-
}, TIMEOUT)
|
|
62
|
-
|
|
63
|
-
it('with metadata', async () => {
|
|
64
|
-
const subscriberAbortController = new AbortController()
|
|
65
|
-
const subscriberOutputIterable = startCommand(`stream subscribe ${streamId} --with-metadata`, {
|
|
66
|
-
privateKey: subscriberPrivateKey,
|
|
67
|
-
abortSignal: subscriberAbortController.signal,
|
|
68
|
-
})
|
|
69
|
-
publishViaCliCommand()
|
|
70
|
-
const receivedMessage = (await collect(subscriberOutputIterable, 1))[0]
|
|
71
|
-
subscriberAbortController.abort()
|
|
72
|
-
expect(JSON.parse(receivedMessage)).toMatchObject({
|
|
73
|
-
content: {
|
|
74
|
-
foo: 123
|
|
75
|
-
},
|
|
76
|
-
metadata: {
|
|
77
|
-
streamId,
|
|
78
|
-
streamPartition: 0,
|
|
79
|
-
timestamp: expect.any(Number),
|
|
80
|
-
sequenceNumber: 0,
|
|
81
|
-
publisherId: new Wallet(publisherPrivateKey).address.toLowerCase(),
|
|
82
|
-
msgChainId: expect.stringMatching(/[0-9a-zA-Z]+/)
|
|
83
|
-
}
|
|
84
|
-
})
|
|
85
|
-
}, TIMEOUT)
|
|
86
|
-
|
|
87
|
-
it('with metadata and raw', async () => {
|
|
88
|
-
const subscriberAbortController = new AbortController()
|
|
89
|
-
const subscriberOutputIterable = startCommand(`stream subscribe ${streamId} --with-metadata --raw`, {
|
|
90
|
-
privateKey: subscriberPrivateKey,
|
|
91
|
-
abortSignal: subscriberAbortController.signal,
|
|
92
|
-
})
|
|
93
|
-
publishViaCliCommand()
|
|
94
|
-
const receivedMessage = (await collect(subscriberOutputIterable, 1))[0]
|
|
95
|
-
subscriberAbortController.abort()
|
|
96
|
-
expect(JSON.parse(receivedMessage)).toMatchObject({
|
|
97
|
-
content: expect.stringMatching(/^[0-9a-fA-F]+$/),
|
|
98
|
-
metadata: {
|
|
99
|
-
streamId,
|
|
100
|
-
streamPartition: 0,
|
|
101
|
-
timestamp: expect.any(Number),
|
|
102
|
-
sequenceNumber: 0,
|
|
103
|
-
publisherId: new Wallet(publisherPrivateKey).address.toLowerCase(),
|
|
104
|
-
msgChainId: expect.stringMatching(/[0-9a-zA-Z]+/)
|
|
105
|
-
}
|
|
106
|
-
})
|
|
107
|
-
}, TIMEOUT)
|
|
108
|
-
})
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { Message, Stream } from '@streamr/sdk'
|
|
2
|
-
import { createTestPrivateKey } from '@streamr/test-utils'
|
|
3
|
-
import { wait } from '@streamr/utils'
|
|
4
|
-
import range from 'lodash/range'
|
|
5
|
-
import { DOCKER_DEV_STORAGE_NODE, createTestClient, runCommand } from './utils'
|
|
6
|
-
|
|
7
|
-
const parseJSONs = (lines: string[]): any[] => {
|
|
8
|
-
return lines.map((line) => JSON.parse(line))
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
describe('resend stream', () => {
|
|
12
|
-
|
|
13
|
-
let privateKey: string
|
|
14
|
-
let stream: Stream
|
|
15
|
-
const messages: Message[] = []
|
|
16
|
-
|
|
17
|
-
beforeAll(async () => {
|
|
18
|
-
privateKey = await createTestPrivateKey({ gas: true })
|
|
19
|
-
const client = createTestClient(privateKey)
|
|
20
|
-
stream = await client.createStream(`/${Date.now()}`)
|
|
21
|
-
await stream.addToStorageNode(DOCKER_DEV_STORAGE_NODE, { wait: true })
|
|
22
|
-
for (const msgId of range(10)) {
|
|
23
|
-
await wait(10) // to prevent duplicate timestamps (to make test assertions simpler)
|
|
24
|
-
const msg = await stream.publish({ msgId })
|
|
25
|
-
messages.push(msg)
|
|
26
|
-
}
|
|
27
|
-
await wait(10000)
|
|
28
|
-
await client.destroy()
|
|
29
|
-
}, 30 * 1000)
|
|
30
|
-
|
|
31
|
-
it('last', async () => {
|
|
32
|
-
const outputLines = await runCommand(`stream resend last 3 ${stream.id}`, {
|
|
33
|
-
privateKey
|
|
34
|
-
})
|
|
35
|
-
expect(parseJSONs(outputLines)).toEqual([
|
|
36
|
-
{ msgId: 7 },
|
|
37
|
-
{ msgId: 8 },
|
|
38
|
-
{ msgId: 9 }
|
|
39
|
-
])
|
|
40
|
-
}, 20 * 1000)
|
|
41
|
-
|
|
42
|
-
it('from', async () => {
|
|
43
|
-
const minTimestamp = new Date(messages[8].timestamp).toISOString()
|
|
44
|
-
const outputLines = await runCommand(`stream resend from ${minTimestamp} ${stream.id}`, {
|
|
45
|
-
privateKey
|
|
46
|
-
})
|
|
47
|
-
expect(parseJSONs(outputLines)).toEqual([
|
|
48
|
-
{ msgId: 8 },
|
|
49
|
-
{ msgId: 9 }
|
|
50
|
-
])
|
|
51
|
-
}, 20 * 1000)
|
|
52
|
-
|
|
53
|
-
it('range', async () => {
|
|
54
|
-
const minTimestamp = new Date(messages[2].timestamp).toISOString()
|
|
55
|
-
const maxTimestamp = new Date(messages[4].timestamp).toISOString()
|
|
56
|
-
const outputLines = await runCommand(`stream resend range ${minTimestamp} ${maxTimestamp} ${stream.id}`, {
|
|
57
|
-
privateKey
|
|
58
|
-
})
|
|
59
|
-
expect(parseJSONs(outputLines)).toEqual([
|
|
60
|
-
{ msgId: 2 },
|
|
61
|
-
{ msgId: 3 },
|
|
62
|
-
{ msgId: 4 }
|
|
63
|
-
])
|
|
64
|
-
}, 20 * 1000)
|
|
65
|
-
|
|
66
|
-
})
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { createTestPrivateKey } from '@streamr/test-utils'
|
|
2
|
-
import { randomString } from '@streamr/utils'
|
|
3
|
-
import { createTestClient, runCommand, waitForTheGraphToHaveIndexed } from './utils'
|
|
4
|
-
|
|
5
|
-
describe('search streams', () => {
|
|
6
|
-
|
|
7
|
-
it('happy path', async () => {
|
|
8
|
-
const testId = randomString(10)
|
|
9
|
-
const client = createTestClient(await createTestPrivateKey({ gas: true }))
|
|
10
|
-
const stream1 = await client.createStream(`/${testId}-1`)
|
|
11
|
-
const stream2 = await client.createStream(`/${testId}-2`)
|
|
12
|
-
await Promise.all([
|
|
13
|
-
waitForTheGraphToHaveIndexed(stream1, client),
|
|
14
|
-
waitForTheGraphToHaveIndexed(stream2, client)
|
|
15
|
-
])
|
|
16
|
-
await client.destroy()
|
|
17
|
-
const outputLines = await runCommand(`stream search ${testId}`)
|
|
18
|
-
expect(outputLines).toEqual([
|
|
19
|
-
stream1.id,
|
|
20
|
-
stream2.id
|
|
21
|
-
])
|
|
22
|
-
}, 20 * 1000)
|
|
23
|
-
|
|
24
|
-
})
|
package/test/stream-show.test.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { createTestPrivateKey } from '@streamr/test-utils'
|
|
2
|
-
import { Wallet } from 'ethers'
|
|
3
|
-
import { createTestClient, runCommand, waitForTheGraphToHaveIndexed } from './utils'
|
|
4
|
-
|
|
5
|
-
describe('show stream', () => {
|
|
6
|
-
|
|
7
|
-
it('happy path', async () => {
|
|
8
|
-
const creatorPrivateKey = await createTestPrivateKey({ gas: true })
|
|
9
|
-
const client = createTestClient(creatorPrivateKey)
|
|
10
|
-
const stream = await client.createStream(`/${Date.now()}`)
|
|
11
|
-
await waitForTheGraphToHaveIndexed(stream, client)
|
|
12
|
-
await client.destroy()
|
|
13
|
-
const outputLines = await runCommand(`stream show ${stream.id} --include-permissions`)
|
|
14
|
-
const outputJson = JSON.parse(outputLines.join(''))
|
|
15
|
-
expect(outputJson).toMatchObject({
|
|
16
|
-
id: stream.id,
|
|
17
|
-
partitions: 1,
|
|
18
|
-
permissions: [{
|
|
19
|
-
permissions: [
|
|
20
|
-
'edit',
|
|
21
|
-
'delete',
|
|
22
|
-
'publish',
|
|
23
|
-
'subscribe',
|
|
24
|
-
'grant'
|
|
25
|
-
],
|
|
26
|
-
user: new Wallet(creatorPrivateKey).address.toLowerCase()
|
|
27
|
-
}]
|
|
28
|
-
})
|
|
29
|
-
}, 20 * 1000)
|
|
30
|
-
|
|
31
|
-
})
|