Browse Source

api-examples

Mokhtar Naamani 4 years ago
parent
commit
d19c507eb2

+ 48 - 0
api-examples/README.md

@@ -0,0 +1,48 @@
+# Joystream API Examples
+
+Repo with examples on how to use the @joystream/types package along with @polkadot/api to communicate with a joystream full node.
+
+
+## Examples
+
+```
+yarn && yarn build
+yarn run status
+```
+
+## Example code
+
+```javascript
+import { registerJoystreamTypes } from '@joystream/types';
+import { ApiPromise, WsProvider } from '@polkadot/api';
+
+async function main () {
+  // Initialise the provider to connect to the local node
+  const provider = new WsProvider('ws://127.0.0.1:9944');
+
+  // Register types before creating the API
+  registerJoystreamTypes();
+
+  // Create the API and wait until ready
+  const api = await ApiPromise.create({ provider });
+
+  // Retrieve the chain & node information information via rpc calls
+  const [chain, nodeName, nodeVersion] = await Promise.all([
+    api.rpc.system.chain(),
+    api.rpc.system.name(),
+    api.rpc.system.version()
+  ]);
+
+  console.log(`Chain ${chain} using ${nodeName} v${nodeVersion}`);
+}
+
+main();
+```
+
+### Scripts
+
+You can run scripts that are found in the [./scripts/](./scripts) folder:
+
+```sh
+yarn script example
+```

+ 25 - 0
api-examples/package.json

@@ -0,0 +1,25 @@
+{
+  "name": "api-examples",
+  "private": true,
+  "version": "0.1.0",
+  "license": "GPL-3.0-only",
+  "scripts": {
+    "status": "ts-node src/status",
+    "script": "ts-node src/script"
+  },
+  "dependencies": {
+    "@joystream/types": "^0.13.0",
+    "@polkadot/api": "^1.26.1",
+    "@polkadot/types": "^1.26.1",
+    "@polkadot/keyring": "^3.0.1",
+    "@polkadot/util": "^3.0.1",
+    "@polkadot/util-crypto": "^3.0.1",
+    "@types/bn.js": "^4.11.5",
+    "bn.js": "^4.11.8"
+  },
+  "devDependencies": {
+    "@polkadot/ts": "^0.1.56",
+    "typescript": "^3.9.7",
+    "ts-node": "^8.6.2"
+  }
+}

+ 32 - 0
api-examples/scripts/example.js

@@ -0,0 +1,32 @@
+/* global api, hashing, keyring, types, util, window, joy */
+
+// run this script with:
+// yarn script example
+//
+// or copy and paste the code into the pioneer javascript toolbox at:
+// https://testnet.joystream.org/#/js
+// 
+// Example works on nicaea release+
+
+const script = async ({ api, hashing, keyring, types, util, joy }) => {
+  // Retrieve the chain & node information information via rpc calls
+  const [chain, nodeName, nodeVersion, runtimeVersion] = await Promise.all([
+    api.rpc.system.chain(),
+    api.rpc.system.name(),
+    api.rpc.system.version(),
+    api.runtimeVersion,
+  ]);
+
+  console.log(`Chain: ${chain}`)
+  console.log(`Software: ${nodeName} v${nodeVersion}`)
+  console.log(`Runtime specVersion: ${runtimeVersion.specVersion}`)
+}
+
+if (typeof module === 'undefined') {
+  // Pioneer js-toolbox
+  // Available globals [api, hashing, keyring, types, util]
+  script({ api, hashing, keyring, types, util, joy })
+} else {
+  // Node
+  module.exports = script
+}

+ 48 - 0
api-examples/scripts/export-data-directory.js

@@ -0,0 +1,48 @@
+/* global api, hashing, keyring, types, util */
+
+// run this script with:
+// yarn script exportDataDirectory
+//
+// or copy and paste the code into the pioneer javascript toolbox at:
+// https://testnet.joystream.org/#/js
+
+const script = async ({ api, hashing, keyring, types, util }) => {
+  const runtimeSpecVersion = api.runtimeVersion.specVersion
+
+  const ownerAccountToMemberId = async (accountId) => {
+    const memberIds = await api.query.members.memberIdsByRootAccountId(accountId)
+    return memberIds[0] || null
+  }
+
+  const ids = await api.query.dataDirectory.knownContentIds()
+
+  // When a BTreeMap is constructed for injection the node will fail to decode
+  // it if its not sorted.
+  ids.sort()
+
+  let transformed = await Promise.all(ids.map(async (id) => {
+    let obj = await api.query.dataDirectory.dataObjectByContentId(id)
+    if (obj.isNone) { return null }
+    obj = obj.unwrap()
+
+    return [id, {
+      owner: runtimeSpecVersion <= 15 ? await ownerAccountToMemberId(obj.owner) : obj.owner,
+      added_at: obj.added_at,
+      type_id: obj.type_id,
+      size: obj.size_in_bytes,
+      liaison: runtimeSpecVersion <= 15 ? new types.u64(0) : obj.liaison,
+      liaison_judgement: obj.liaison_judgement,
+      ipfs_content_id: obj.ipfs_content_id }]
+  }))
+
+  console.log(JSON.stringify(transformed))
+  console.error(`Exported ${transformed.length} objects`)
+}
+
+if (typeof module === 'undefined') {
+  // Pioneer js-toolbox
+  script({ api, hashing, keyring, types, util })
+} else {
+  // Node
+  module.exports = script
+}

+ 10 - 0
api-examples/scripts/index.js

@@ -0,0 +1,10 @@
+const typesVersion = require('@joystream/types/package.json')
+
+const exportedScripts = {}
+
+exportedScripts.example = require('./example.js')
+exportedScripts.exportDataDirectory = require('./export-data-directory.js')
+exportedScripts.injectDataObjects = require('./inject-data-objects.js')
+exportedScripts.listDataDirectory = require('./list-data-directory.js')
+
+module.exports = exportedScripts

File diff suppressed because it is too large
+ 17 - 0
api-examples/scripts/inject-data-objects.js


+ 29 - 0
api-examples/scripts/list-data-directory.js

@@ -0,0 +1,29 @@
+/* global api, hashing, keyring, types, util */
+
+// run this script with:
+// yarn script listDataDirectory
+//
+// or copy and paste the code into the pioneer javascript toolbox at:
+// https://testnet.joystream.org/#/js
+// requires nicaea release+
+
+const script = async ({ api, joy }) => {
+  const ids = await api.query.dataDirectory.knownContentIds()
+
+  await Promise.all(ids.map(async (id) => {
+    let obj = await api.query.dataDirectory.dataObjectByContentId(id)
+    if (obj.isNone) { return }
+    obj = obj.unwrap()
+    console.log(`contentId: ${new joy.media.ContentId(id).encode()}, ipfs: ${obj.ipfs_content_id}`)
+  }))
+
+  console.error(`Data Directory contains ${ids.length} objects`)
+}
+
+if (typeof module === 'undefined') {
+  // Pioneer js-toolbox
+  script({ api, hashing, keyring, types, util, joy })
+} else {
+  // Node
+  module.exports = script
+}

+ 21 - 0
api-examples/src/get-code.ts

@@ -0,0 +1,21 @@
+import { ApiPromise, WsProvider } from '@polkadot/api';
+import { types } from '@joystream/types'
+
+async function main () {
+  const provider = new WsProvider('ws://127.0.0.1:9944');
+
+  const api = await ApiPromise.create({ provider, types })
+
+  let current_block_hash = await api.rpc.chain.getBlockHash();
+
+  console.log('getting code as of block hash', current_block_hash.toString())
+
+  const substrateWasm = await api.query.substrate.code.at(current_block_hash.toString());
+  // const substrateWasm = await api.rpc.state.getStorage('0x'+Buffer.from(':code').toString('hex'), current_block_hash);
+
+  console.log(substrateWasm.toHex());
+
+  api.disconnect();
+}
+
+main()

+ 54 - 0
api-examples/src/script.ts

@@ -0,0 +1,54 @@
+// @ts-check
+
+import { ApiPromise, WsProvider } from '@polkadot/api'
+import * as types from '@polkadot/types'
+import * as util from '@polkadot/util'
+import { types as joyTypes } from '@joystream/types'
+import * as joy from '@joystream/types'
+import * as hashing from '@polkadot/util-crypto'
+import { Keyring } from '@polkadot/keyring'
+
+const scripts = require('../scripts')
+
+async function main () {
+  
+
+  const scriptArg = process.argv[2]
+  const script = scripts[scriptArg]
+
+  if (!scriptArg || !script) {
+    console.error('Please specify valid script name.')
+    console.error('Available scripts:', Object.keys(scripts))
+    return
+  }
+
+  const provider = new WsProvider('ws://127.0.0.1:9944')
+
+  const api = await ApiPromise.create({ provider, types: joyTypes })
+
+  // We don't pass a custom signer to the api so we must use a keyPair
+  // when calling signAndSend on transactions
+  const keyring = new Keyring()
+
+  // Optional last argument is a SURI for account to use for signing transactions
+  const suri = process.argv[3]
+  if (suri) {
+    keyring.addFromUri(suri, undefined, 'sr25519')
+  }
+
+  // Add development well known keys to keyring
+  if ((await api.rpc.system.chain()).toString() === 'Development') {
+    keyring.addFromUri('//Alice', undefined, 'sr25519')
+    keyring.addFromUri('//Bob', undefined, 'sr25519')
+  }
+
+  try {
+    await script({ api, types, util, hashing, keyring, joy })
+  } catch (err) {
+    console.error(err)
+  }
+
+  api.disconnect();
+}
+
+main()

+ 60 - 0
api-examples/src/status.ts

@@ -0,0 +1,60 @@
+// @ts-check
+
+import { ApiPromise, WsProvider } from '@polkadot/api';
+import { types } from '@joystream/types'
+import { Seat } from '@joystream/types/council';
+// import { SubscriptionResult, QueryableStorageFunction } from '@polkadot/api/promise/types';
+// import { GenericAccountId } from '@polkadot/types';
+import { ValidatorId } from '@polkadot/types/interfaces';
+
+// import BN from 'bn.js';
+const BN = require('bn.js');
+
+async function main () {
+  // Initialise the provider to connect to the local node
+  const provider = new WsProvider('ws://127.0.0.1:9944');
+
+  // Create the API and wait until ready
+  const api = await ApiPromise.create({ provider, types })
+
+  // Retrieve the chain & node information information via rpc calls
+  const [chain, nodeName, nodeVersion] = await Promise.all([
+    api.rpc.system.chain(),
+    api.rpc.system.name(),
+    api.rpc.system.version()
+  ]);
+
+  console.log(`Chain ${chain} using ${nodeName} v${nodeVersion}`);
+
+  let council = await api.query.council.activeCouncil() as unknown as Seat[];
+  let validators = await api.query.session.validators() as unknown as ValidatorId[];
+  let version  = await api.rpc.state.getRuntimeVersion() as any;
+
+  console.log(`Runtime Version: ${version.authoringVersion}.${version.specVersion}.${version.implVersion}`);
+
+  // let council: QueryableStorageFunction<Seat[], SubscriptionResult> = (await api.query.council.activeCouncil()) as unknown as Seat[]
+  // let council = (await api.query.council.activeCouncil()) as unknown as Seat[];
+
+  // number of council members
+  console.log('Council size:', council.length)
+
+  console.log('Validator count:', validators.length);
+
+  if (validators && validators.length > 0) {
+    // Retrieve the free balances for all validators
+    const validatorBalances = await Promise.all(
+      validators.map(authorityId => api.query.balances.account(authorityId))
+    );
+
+    let totalValidatorBalances =
+      validatorBalances.reduce((total, value) => total.add(value.free), new BN(0))
+
+    // TODO: to get the staked amounts we need to read the account lock information.
+    
+    console.log('Total Validator Free Balance:', totalValidatorBalances.toString());
+  }
+
+  api.disconnect();
+}
+
+main()

+ 33 - 0
api-examples/src/tohex.ts

@@ -0,0 +1,33 @@
+import { ApiPromise, WsProvider } from '@polkadot/api';
+import { CuratorApplicationId } from '@joystream/types/content-working-group';
+import { BTreeSet } from '@polkadot/types';
+import { types } from '@joystream/types'
+
+async function main() {
+    const provider = new WsProvider('ws://127.0.0.1:9944');
+    const api = await ApiPromise.create({ provider, types })
+
+    let wgId = [1, 2]
+
+    let set = new BTreeSet<CuratorApplicationId>(api.registry, CuratorApplicationId, []);
+    
+    wgId.forEach((id) => {
+        set.add(new CuratorApplicationId(api.registry, id))
+    })
+    
+    /*
+    Replace the integers inside the bracket in:
+    let wgId:number[] = [1, 2];
+    With the "WG ID"s of the curators you wish to hire, in ascending order.
+
+    To hire "WG ID" 18 21 and 16:
+    let wgId:number[] = [16, 18, 21];
+    */
+
+    console.log('copy/paste the output below to hire curator applicant(s) with WG IDs:', wgId )
+    console.log(set.toHex())
+
+    api.disconnect()
+}
+
+main()

+ 17 - 0
api-examples/tsconfig.json

@@ -0,0 +1,17 @@
+{
+  "compilerOptions": {
+    "declaration": true,
+    "importHelpers": true,
+    "module": "commonjs",
+    "outDir": "lib",
+    "rootDir": "src",
+    "strict": true,
+    "target": "es2017",
+    "esModuleInterop": true,
+    "types" : [ "node" ],
+    "noUnusedLocals": true
+  },
+  "include": [
+    "src/**/*"
+  ]
+}

+ 2 - 1
package.json

@@ -20,7 +20,8 @@
     "storage-node",
     "storage-node/packages/*",
     "devops/eslint-config",
-    "devops/prettier-config"
+    "devops/prettier-config",
+    "api-examples"
   ],
   "resolutions": {
     "@polkadot/api": "^1.26.1",

File diff suppressed because it is too large
+ 420 - 206
yarn.lock


Some files were not shown because too many files changed in this diff