Bläddra i källkod

Merge pull request #1155 from mnaamani/iznik-api-examples

Add api examples to monorepo
Mokhtar Naamani 4 år sedan
förälder
incheckning
d7c2feb493

+ 2 - 1
package.json

@@ -22,7 +22,8 @@
     "pioneer",
     "pioneer/packages/apps*",
     "pioneer/packages/page*",
-    "pioneer/packages/react*"
+    "pioneer/packages/react*",
+    "utils/api-examples"
   ],
   "resolutions": {
     "@polkadot/api": "1.26.1",

+ 46 - 0
utils/api-examples/README.md

@@ -0,0 +1,46 @@
+# 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 run status
+```
+
+## Example code
+
+```javascript
+import { types } 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')
+
+  // Create the API and wait until ready
+  const api = await ApiPromise.create({ provider, types })
+
+  await api.isReady
+
+  // 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
utils/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
utils/api-examples/scripts/example.js

@@ -0,0 +1,32 @@
+/* global api, hashing, keyring, types, util, 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
+}

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

@@ -0,0 +1,49 @@
+/* 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 }) => {
+  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()
+
+  const 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: obj.owner,
+          added_at: obj.added_at,
+          type_id: obj.type_id,
+          size: obj.size_in_bytes,
+          liaison: 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
+}

+ 9 - 0
utils/api-examples/scripts/index.js

@@ -0,0 +1,9 @@
+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')
+exportedScripts.testTransfer = require('./transfer.js')
+
+module.exports = exportedScripts

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 15 - 0
utils/api-examples/scripts/inject-data-objects.js


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

@@ -0,0 +1,33 @@
+/* global api, hashing, keyring, types, util, joy */
+
+// 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: ${api.createType('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
+}

+ 31 - 0
utils/api-examples/scripts/transfer.js

@@ -0,0 +1,31 @@
+/* global api, hashing, keyring, types, util, window */
+
+// run this script with:
+// yarn script testTransfer
+//
+// or copy and paste the code into the pioneer javascript toolbox at:
+// https://testnet.joystream.org/#/js
+//
+
+const script = async ({ api, keyring }) => {
+  const sudoAddress = (await api.query.sudo.key()).toString()
+  let sudo
+  if (typeof window === 'undefined') {
+    // In node, get the keyPair if the keyring was provided
+    sudo = keyring.getPair(sudoAddress)
+  } else {
+    // Pioneer: let the UI Signer handle it
+    sudo = sudoAddress
+  }
+
+  const transfer = api.tx.balances.transfer(sudoAddress, 100)
+  await transfer.signAndSend(sudo)
+}
+
+if (typeof module === 'undefined') {
+  // Pioneer js-toolbox
+  script({ api, hashing, keyring, types, util })
+} else {
+  // Node
+  module.exports = script
+}

+ 20 - 0
utils/api-examples/src/get-code.ts

@@ -0,0 +1,20 @@
+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 })
+
+  const currentBlockHash = await api.rpc.chain.getBlockHash(1)
+
+  console.log('getting code as of block hash', currentBlockHash.toString())
+
+  const substrateWasm = await api.query.substrate.code.at(currentBlockHash)
+
+  console.log(substrateWasm.toHex())
+
+  api.disconnect()
+}
+
+main()

+ 52 - 0
utils/api-examples/src/script.ts

@@ -0,0 +1,52 @@
+// @ts-check
+
+import { ApiPromise, WsProvider } from '@polkadot/api'
+import * as types from '@polkadot/types'
+import * as util from '@polkadot/util'
+import joy, { types as joyTypes } from '@joystream/types'
+import * as hashing from '@polkadot/util-crypto'
+import { Keyring } from '@polkadot/keyring'
+
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+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()

+ 56 - 0
utils/api-examples/src/status.ts

@@ -0,0 +1,56 @@
+// @ts-check
+
+import { ApiPromise, WsProvider } from '@polkadot/api'
+import { types } from '@joystream/types'
+import { Seat } from '@joystream/types/council'
+import { ValidatorId } from '@polkadot/types/interfaces'
+
+import BN from '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}`)
+
+  const council = ((await api.query.council.activeCouncil()) as unknown) as Seat[]
+  const validators = ((await api.query.session.validators()) as unknown) as ValidatorId[]
+  const 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))
+    )
+
+    const 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()

+ 30 - 0
utils/api-examples/src/tohex.ts

@@ -0,0 +1,30 @@
+import { CuratorApplicationId } from '@joystream/types/content-working-group'
+import { BTreeSet, createType, TypeRegistry } from '@polkadot/types'
+import { types } from '@joystream/types'
+
+async function main() {
+  const wgId = [1, 2]
+
+  const registry = new TypeRegistry()
+  registry.register(types)
+
+  const set = new BTreeSet<CuratorApplicationId>(registry, CuratorApplicationId, [])
+
+  wgId.forEach((id) => {
+    set.add(createType(registry, 'CuratorApplicationId', 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())
+}
+
+main()

+ 19 - 0
utils/api-examples/tsconfig.json

@@ -0,0 +1,19 @@
+{
+  "compilerOptions": {
+    "declaration": true,
+    "importHelpers": true,
+    "module": "commonjs",
+    "outDir": "lib",
+    "rootDir": "src",
+    "strict": true,
+    "target": "es2017",
+    "esModuleInterop": true,
+    "types": ["node"],
+    "noUnusedLocals": true,
+    "baseUrl": "./",
+    "paths": {
+      "@polkadot/types/augment": ["../../types/src/definitions/augment-types.ts"]
+    }
+  },
+  "include": ["src/**/*"]
+}

+ 1 - 1
yarn.lock

@@ -3383,7 +3383,7 @@
     "@polkadot/util" "^3.0.1"
     bn.js "^5.1.2"
 
-"@polkadot/types@1.26.1", "@polkadot/types@^0.96.1":
+"@polkadot/types@1.26.1", "@polkadot/types@^0.96.1", "@polkadot/types@^1.26.1":
   version "1.26.1"
   resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-1.26.1.tgz#e58a823da22bd526b298f7d42384bf59b8994fad"
   integrity sha512-mrA3+qYyDvfOIOMkY8lg2ziCYpwOl3N1LUxKdiyBDtKM7Dl8ZWQ0nLUCDW5MhbzDlThmYjE4feBRA+2eBShfyA==

Vissa filer visades inte eftersom för många filer har ändrats