create-blocklet 0.9.6 → 0.9.7

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.
Files changed (90) hide show
  1. package/common/.prettierrc +11 -1
  2. package/common/scripts/build-clean.mjs +0 -1
  3. package/common/scripts/bump-version.mjs +33 -29
  4. package/index.js +16 -10
  5. package/package.json +1 -1
  6. package/templates/did-connect-dapp/.eslintrc.js +4 -0
  7. package/templates/did-connect-dapp/README.md +143 -0
  8. package/templates/did-connect-dapp/api/dev.js +5 -0
  9. package/templates/did-connect-dapp/api/hooks/pre-start.js +33 -0
  10. package/templates/did-connect-dapp/api/index.js +48 -0
  11. package/templates/did-connect-dapp/api/libs/auth.js +25 -0
  12. package/templates/did-connect-dapp/api/libs/env.js +9 -0
  13. package/templates/did-connect-dapp/api/libs/logger.js +3 -0
  14. package/templates/did-connect-dapp/api/libs/utils.js +70 -0
  15. package/templates/did-connect-dapp/api/routes/auth/index.js +15 -0
  16. package/templates/did-connect-dapp/api/routes/auth/request-digest-signature.js +51 -0
  17. package/templates/did-connect-dapp/api/routes/auth/request-multiple-claims.js +52 -0
  18. package/templates/did-connect-dapp/api/routes/auth/request-multiple-steps.js +57 -0
  19. package/templates/did-connect-dapp/api/routes/auth/request-nft.js +82 -0
  20. package/templates/did-connect-dapp/api/routes/auth/request-payment.js +72 -0
  21. package/templates/did-connect-dapp/api/routes/auth/request-profile.js +25 -0
  22. package/templates/did-connect-dapp/api/routes/auth/request-text-signature.js +44 -0
  23. package/templates/did-connect-dapp/api/routes/auth/request-transaction-signature.js +62 -0
  24. package/templates/did-connect-dapp/blocklet.md +5 -0
  25. package/templates/did-connect-dapp/blocklet.yml +57 -0
  26. package/templates/did-connect-dapp/index.html +17 -0
  27. package/templates/did-connect-dapp/package.json +86 -0
  28. package/templates/did-connect-dapp/src/app.jsx +20 -0
  29. package/templates/did-connect-dapp/src/assets/get_wallet_en.png +0 -0
  30. package/templates/did-connect-dapp/src/assets/get_wallet_zh.png +0 -0
  31. package/templates/did-connect-dapp/src/components/connect-item.jsx +39 -0
  32. package/templates/did-connect-dapp/src/components/connects/request-digest-signature.jsx +45 -0
  33. package/templates/did-connect-dapp/src/components/connects/request-multiple-claims.jsx +55 -0
  34. package/templates/did-connect-dapp/src/components/connects/request-multiple-steps.jsx +54 -0
  35. package/templates/did-connect-dapp/src/components/connects/request-nft.jsx +75 -0
  36. package/templates/did-connect-dapp/src/components/connects/request-payment.jsx +82 -0
  37. package/templates/did-connect-dapp/src/components/connects/request-profile.jsx +72 -0
  38. package/templates/did-connect-dapp/src/components/connects/request-text-signature.jsx +44 -0
  39. package/templates/did-connect-dapp/src/components/connects/request-transaction-signature.jsx +44 -0
  40. package/templates/did-connect-dapp/src/components/info-row.jsx +39 -0
  41. package/templates/did-connect-dapp/src/components/layout.jsx +26 -0
  42. package/templates/did-connect-dapp/src/index.jsx +6 -0
  43. package/templates/did-connect-dapp/src/libs/session.js +11 -0
  44. package/templates/did-connect-dapp/src/libs/utils.js +4 -0
  45. package/templates/did-connect-dapp/src/locales/en.js +115 -0
  46. package/templates/did-connect-dapp/src/locales/index.js +5 -0
  47. package/templates/did-connect-dapp/src/locales/zh.js +115 -0
  48. package/templates/did-connect-dapp/src/pages/main.jsx +95 -0
  49. package/templates/did-connect-dapp/template-info.json +12 -0
  50. package/templates/did-connect-dapp/vite.config.mjs +11 -0
  51. package/templates/did-wallet-dapp/blocklet.yml +1 -2
  52. package/templates/did-wallet-dapp/package.json +18 -18
  53. package/templates/express-api/blocklet.yml +0 -1
  54. package/templates/express-api/package.json +9 -8
  55. package/templates/html-static/blocklet.yml +0 -1
  56. package/templates/html-static/package.json +4 -3
  57. package/templates/monorepo/package.json +4 -3
  58. package/templates/monorepo/scripts/bump-version.mjs +36 -32
  59. package/templates/nestjs-api/blocklet.yml +0 -1
  60. package/templates/nestjs-api/package.json +16 -15
  61. package/templates/nextjs-dapp/blocklet.yml +0 -1
  62. package/templates/nextjs-dapp/package.json +7 -7
  63. package/templates/react-dapp/blocklet.yml +0 -1
  64. package/templates/react-dapp/package.json +16 -15
  65. package/templates/react-dapp-ts/blocklet.yml +0 -1
  66. package/templates/react-dapp-ts/package.json +19 -18
  67. package/templates/react-gun-dapp/blocklet.yml +0 -1
  68. package/templates/react-gun-dapp/package.json +15 -14
  69. package/templates/react-static/blocklet.yml +0 -1
  70. package/templates/react-static/package.json +11 -10
  71. package/templates/solidjs-dapp/blocklet.yml +0 -1
  72. package/templates/solidjs-dapp/package.json +14 -13
  73. package/templates/solidjs-static/blocklet.yml +0 -1
  74. package/templates/solidjs-static/package.json +9 -8
  75. package/templates/svelte-dapp/blocklet.yml +0 -1
  76. package/templates/svelte-dapp/package.json +12 -11
  77. package/templates/svelte-static/blocklet.yml +0 -1
  78. package/templates/svelte-static/package.json +8 -7
  79. package/templates/todo-list-example/blocklet.yml +0 -1
  80. package/templates/todo-list-example/package.json +11 -10
  81. package/templates/vue-dapp/blocklet.yml +0 -1
  82. package/templates/vue-dapp/package.json +16 -15
  83. package/templates/vue-static/blocklet.yml +0 -1
  84. package/templates/vue-static/package.json +11 -10
  85. package/templates/vue-ts-static/blocklet.yml +1 -2
  86. package/templates/vue-ts-static/package.json +12 -12
  87. package/templates/vue2-dapp/blocklet.yml +0 -1
  88. package/templates/vue2-dapp/package.json +13 -12
  89. package/templates/vue2-static/blocklet.yml +0 -1
  90. package/templates/vue2-static/package.json +9 -8
@@ -6,5 +6,15 @@
6
6
  "bracketSameLine": true,
7
7
  "semi": true,
8
8
  "singleQuote": true,
9
- "plugins": ["prettier-plugin-import-sort"]
9
+ "importOrder": [
10
+ "^@core/(.*)$",
11
+ "^@server/(.*)$",
12
+ "^@ui/(.*)$",
13
+ "^[./]"
14
+ ],
15
+ "importOrderSeparation": true,
16
+ "importOrderSortSpecifiers": true,
17
+ "plugins": [
18
+ "@trivago/prettier-plugin-sort-imports"
19
+ ]
10
20
  }
@@ -1,5 +1,4 @@
1
1
  /* eslint-disable no-console */
2
-
3
2
  import { rimrafSync } from 'rimraf';
4
3
 
5
4
  console.log('clean .blocklet folder');
@@ -2,34 +2,38 @@
2
2
  import { execSync } from 'child_process';
3
3
  import { $, chalk, fs } from 'zx';
4
4
 
5
- execSync('bumpp --no-tag --no-commit --no-push package.json', { stdio: 'inherit' });
6
-
7
- const { version } = await fs.readJSON('package.json');
8
- await fs.writeFileSync('version', version);
9
-
10
- console.log(chalk.greenBright(`[info]: start to modify blocklet version to ${version}`));
11
- await $`blocklet version ${version}`;
12
- console.log(chalk.greenBright('[info]: blocklet version modified.'));
13
-
14
- let newChangelog = '';
15
- try {
16
- const gitRes = await $`git log --pretty=format:"- %s" "main"...HEAD`;
17
- newChangelog = gitRes.stdout.trim();
18
- } catch {
19
- console.error(chalk.redBright('Could not get git log, please write changelog manually.'));
5
+ async function main() {
6
+ execSync('bumpp --no-tag --no-commit --no-push package.json', { stdio: 'inherit' });
7
+
8
+ const { version } = await fs.readJSON('package.json');
9
+ await fs.writeFileSync('version', version);
10
+
11
+ console.log(chalk.greenBright(`[info]: start to modify blocklet version to ${version}`));
12
+ await $`blocklet version ${version}`;
13
+ console.log(chalk.greenBright('[info]: blocklet version modified.'));
14
+
15
+ let newChangelog = '';
16
+ try {
17
+ const gitRes = await $`git log --pretty=format:"- %s" "main"...HEAD`;
18
+ newChangelog = gitRes.stdout.trim();
19
+ } catch {
20
+ console.error(chalk.redBright('Could not get git log, please write changelog manually.'));
21
+ }
22
+
23
+ const now = new Date();
24
+ const currentDate = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
25
+ const title = `## ${version} (${currentDate})`;
26
+
27
+ await fs.ensureFile('CHANGELOG.md');
28
+ const oldChangelog = await fs.readFile('CHANGELOG.md', 'utf8');
29
+ const changelog = [title, newChangelog, oldChangelog].filter((item) => !!item).join('\n\n');
30
+ await fs.writeFile('CHANGELOG.md', changelog);
31
+
32
+ console.log(`\nNow you can make adjustments to ${chalk.cyan('CHANGELOG.md')} . Then press enter to continue.`);
33
+
34
+ process.stdin.setRawMode(true);
35
+ process.stdin.resume();
36
+ process.stdin.on('data', process.exit.bind(process, 0));
20
37
  }
21
38
 
22
- const now = new Date();
23
- const currentDate = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
24
- const title = `## ${version} (${currentDate})`;
25
-
26
- await fs.ensureFile('CHANGELOG.md');
27
- const oldChangelog = await fs.readFile('CHANGELOG.md', 'utf8');
28
- const changelog = [title, newChangelog, oldChangelog].filter((item) => !!item).join('\n\n');
29
- await fs.writeFile('CHANGELOG.md', changelog);
30
-
31
- console.log(`\nNow you can make adjustments to ${chalk.cyan('CHANGELOG.md')} . Then press enter to continue.`);
32
-
33
- process.stdin.setRawMode(true);
34
- process.stdin.resume();
35
- process.stdin.on('data', process.exit.bind(process, 0));
39
+ main();
package/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  checkYarn,
27
27
  } from './lib/utils.js';
28
28
 
29
- const { yellow, red, green, cyan, blue, bold, magenta } = chalk;
29
+ const { yellow, red, green, cyan, blue, bold } = chalk;
30
30
 
31
31
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
32
32
 
@@ -54,6 +54,11 @@ const templates = [
54
54
  display: '[dapp: todo-list] react + express + typescript + DID Spaces',
55
55
  color: yellow,
56
56
  },
57
+ {
58
+ name: 'did-connect-dapp',
59
+ display: '[dapp: did-connect] Full stack app (react.js + express.js) with DID Connect integration',
60
+ color: yellow,
61
+ },
57
62
  {
58
63
  name: 'solidjs-dapp',
59
64
  display: '[dapp] solid + express.js',
@@ -62,7 +67,7 @@ const templates = [
62
67
  {
63
68
  name: 'vue-dapp',
64
69
  display: '[dapp] vue3 + express.js',
65
- color: green,
70
+ color: yellow,
66
71
  },
67
72
  // {
68
73
  // name: 'vue2-dapp',
@@ -72,7 +77,7 @@ const templates = [
72
77
  {
73
78
  name: 'svelte-dapp',
74
79
  display: '[dapp] svelte + express.js',
75
- color: magenta,
80
+ color: yellow,
76
81
  },
77
82
  // FIXME: @zhanghan add this template in the future
78
83
  // {
@@ -89,12 +94,12 @@ const templates = [
89
94
  {
90
95
  name: 'react-static',
91
96
  display: '[static] react',
92
- color: yellow,
97
+ color: green,
93
98
  },
94
99
  {
95
100
  name: 'solidjs-static',
96
101
  display: '[static] solidjs',
97
- color: yellow,
102
+ color: green,
98
103
  },
99
104
  {
100
105
  name: 'vue-static',
@@ -114,23 +119,23 @@ const templates = [
114
119
  {
115
120
  name: 'svelte-static',
116
121
  display: '[static] svelte',
117
- color: magenta,
122
+ color: green,
118
123
  },
119
124
  {
120
125
  name: 'html-static',
121
126
  display: '[static] html',
122
- color: blue,
127
+ color: green,
123
128
  },
124
129
  // api
125
130
  {
126
131
  name: 'express-api',
127
132
  display: '[api] express.js',
128
- color: yellow,
133
+ color: blue,
129
134
  },
130
135
  {
131
136
  name: 'nestjs-api',
132
137
  display: '[api] nestjs',
133
- color: yellow,
138
+ color: blue,
134
139
  },
135
140
  ];
136
141
 
@@ -461,7 +466,8 @@ async function init() {
461
466
  );
462
467
  modifyBlockletYaml(
463
468
  (yamlConfig) => {
464
- yamlConfig.name = mainBlocklet ? finalTemplateName : name;
469
+ // NOTICE: don't need set name anymore
470
+ // yamlConfig.name = mainBlocklet ? finalTemplateName : name;
465
471
  yamlConfig.title = mainBlocklet ? templateName : name;
466
472
  },
467
473
  templateDir,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-blocklet",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "exports": "./index.js",
5
5
  "type": "module",
6
6
  "repository": "git@github.com:blocklet/create-blocklet.git",
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ root: true,
3
+ extends: '@arcblock/eslint-config',
4
+ };
@@ -0,0 +1,143 @@
1
+ # Getting Started with Create Blocklet
2
+
3
+ This project was bootstrapped with [Create Blocklet](https://github.com/blocklet/create-blocklet).
4
+
5
+ This blocklet is a dapp project, which means this is a full-stack application. It's contained both `server` and `client` code.
6
+
7
+ ## File Structure
8
+
9
+ - public/ - static files
10
+ - favicon.ico - favicon
11
+ - favicon.svg - favicon
12
+ - index.html - main html file, template for react
13
+ - screenshots/ - Screenshots
14
+ - api/ - Api side code
15
+ - hooks/ - blocklet lifecycle hooks
16
+ - libs/ - Api side libraries
17
+ - middlewares/ - Api side middlewares
18
+ - routes/ - Api side routes
19
+ - routes/auth - DID Connect backend registration
20
+ - dev.js - Api side dev mode entry point
21
+ - index.js - Api side entry point
22
+ - src/ - Client side code (A standard react app structure)
23
+ - .env - Environment variables
24
+ - .env.development.local - Local development environment variables
25
+ - .eslintrc.js - ESLint configuration
26
+ - .gitignore - Git ignore file
27
+ - .prettierrc - Prettier configuration
28
+ - blocklet.md - Blocklet README
29
+ - blocklet.yml - Blocklet configuration
30
+ - LICENSE - License file
31
+ - logo.png - Blocklet logo file
32
+ - Makefile - Makefile
33
+ - package.json - Npm package file
34
+ - README.md - A guide for this blocklet
35
+ - version - Version file
36
+
37
+ ## Development
38
+
39
+ 1. Make sure you have [@blocklet/cli](https://www.npmjs.com/package/@blocklet/cli) installed
40
+
41
+ Blocklet needs blocklet server as a dependency. So you need to install it first.
42
+ `npm install -g @blocklet/cli`
43
+ See details in [https://www.arcblock.io/docs/blocklet-developer/install-blocklet-cli](https://www.arcblock.io/docs/blocklet-developer/install-blocklet-cli)
44
+
45
+ 2. Init blocklet server & start blocklet server
46
+
47
+ Before starting an blocklet server, you need to init blocklet server.
48
+ `blocklet server init --mode=debug`
49
+ `blocklet server start`
50
+ See details in [https://www.arcblock.io/docs/blocklet-developer/getting-started](https://www.arcblock.io/docs/blocklet-developer/getting-started)
51
+
52
+ 3. Go to the project directory `cd [name]`
53
+ 4. Install dependencies: `npm install` or `yarn` or `pnpm install`
54
+ 5. Start development server: `blocklet dev`
55
+
56
+ ## Bundle
57
+
58
+ After developing a blocklet, you may need to bundle it. Use `npm run bundle` command.
59
+
60
+ ## Deploy
61
+
62
+ - If you want to deploy this blocklet to local blocklet server, you can use `blocklet deploy .blocklet/bundle` command(Make sure the blocklet is bundled before deployment).
63
+ > Or you can simply use `npm run deploy` command.
64
+ - If you want to deploy this blocklet to remote blocklet server, you can use the command below.
65
+
66
+ ```shell
67
+ blocklet deploy .blocklet/bundle --endpoint {your blocklet server url} --access-key {blocklet server access key} --access-secret {blocklet server access secret}
68
+ ```
69
+
70
+ > Make sure the blocklet is bundled before deployment.
71
+
72
+ ## Upload to blocklet store
73
+
74
+ - If you want to upload the blocklet to any store for other users to download and use, you can following the following instructions.
75
+
76
+ Bump version at first.
77
+
78
+ ```shell
79
+ npm run bump-version
80
+ ```
81
+
82
+ Then config blocklet store url.
83
+ You can use those store url in below.
84
+
85
+ 1. [https://store.blocklet.dev/](https://store.blocklet.dev/)
86
+ 2. [https://dev.store.blocklet.dev/](https://dev.store.blocklet.dev/)
87
+ 3. A blocklet store started by yourself.
88
+ > Make sure you have installed a `blocklet store` on your own blocklet server. Check it on here: [https://store.blocklet.dev/blocklet/z8ia29UsENBg6tLZUKi2HABj38Cw1LmHZocbQ](https://store.blocklet.dev/blocklet/z8ia29UsENBg6tLZUKi2HABj38Cw1LmHZocbQ)
89
+
90
+ ```shell
91
+ blocklet config set store {store url}
92
+ ```
93
+
94
+ Get a `accessToken` by using this command.
95
+
96
+ > Why we need a `accessToken`?
97
+ > A `accessToken` is genrate by blocklet store, which help us upload our blocklet to any store.
98
+
99
+ Set `accessToken` to blocklet config
100
+
101
+ ```shell
102
+ blocklet config set accessToken {accessToken}
103
+ ```
104
+
105
+ Upload a new version to a store.
106
+
107
+ > Make sure the blocklet is bundled before upload.
108
+
109
+ ```shell
110
+ blocklet upload
111
+ ```
112
+
113
+ Or you can simply use `npm run upload` command.
114
+
115
+ - You also can upload a new version to a store by Github CI.
116
+ Bump version at first.
117
+
118
+ ```shell
119
+ npm run bump-version
120
+ ```
121
+
122
+ Push your code to Github main/master branch, or make a pull request to the main/master branch.
123
+ The CI workflow will automatically upload a new version to a store.
124
+
125
+ ## Q & A
126
+
127
+ 1. Q: How to change a blocklet's logo?
128
+
129
+ Change the `logo.png` file root folder.
130
+
131
+ Or you can change the `logo` field in the `blocklet.yml` file.
132
+
133
+ > Make sure you have added the logo path to the `blocklet.yml` file `files` field.
134
+
135
+ ## Learn More
136
+
137
+ - Full specification of `blocklet.yml`: [https://github.com/blocklet/blocklet-specification/blob/main/docs/meta.md](https://github.com/blocklet/blocklet-specification/blob/main/docs/meta.md)
138
+ - Full document of Blocklet Server & blocklet development: [https://www.arcblock.io/docs/blocklet-developer](https://www.arcblock.io/docs/blocklet-developer)
139
+
140
+ ## License
141
+
142
+ The code is licensed under the Apache 2.0 license found in the
143
+ [LICENSE](LICENSE) file.
@@ -0,0 +1,5 @@
1
+ const { app } = require('./index');
2
+
3
+ import('vite-plugin-blocklet').then(({ setupClient }) => {
4
+ setupClient(app);
5
+ });
@@ -0,0 +1,33 @@
1
+ require('@blocklet/sdk/lib/error-handler');
2
+ require('dotenv-flow').config();
3
+
4
+ const Client = require('@ocap/client');
5
+
6
+ const env = require('../libs/env');
7
+ const logger = require('../libs/logger');
8
+ const { wallet } = require('../libs/auth');
9
+ const { name } = require('../../package.json');
10
+
11
+ const ensureAccountDeclared = async () => {
12
+ if (env.isComponent) return;
13
+ if (!env.chainHost) return;
14
+
15
+ const client = new Client(env.chainHost);
16
+ const { state } = await client.getAccountState({ address: wallet.toAddress() }, { ignoreFields: ['context'] });
17
+ if (!state) {
18
+ const hash = await client.declare({ moniker: name, wallet });
19
+ logger.log(`app account declared on chain ${env.chainHost}`, hash);
20
+ } else {
21
+ logger.log(`app account already declared on chain ${env.chainHost}`);
22
+ }
23
+ };
24
+
25
+ (async () => {
26
+ try {
27
+ await ensureAccountDeclared();
28
+ process.exit(0);
29
+ } catch (err) {
30
+ logger.error(`${name} pre-start error`, err.message);
31
+ process.exit(1);
32
+ }
33
+ })();
@@ -0,0 +1,48 @@
1
+ require('dotenv-flow').config();
2
+ require('express-async-errors');
3
+ const path = require('path');
4
+ const express = require('express');
5
+ const cookieParser = require('cookie-parser');
6
+ const fallback = require('@blocklet/sdk/lib/middlewares/fallback');
7
+
8
+ const authRoutes = require('./routes/auth');
9
+ const { name, version } = require('../package.json');
10
+ const logger = require('./libs/logger');
11
+
12
+ const app = express();
13
+
14
+ app.set('trust proxy', true);
15
+ app.use(cookieParser());
16
+ app.use(express.json({ limit: '1 mb' }));
17
+ app.use(express.urlencoded({ extended: true, limit: '1 mb' }));
18
+
19
+ const router = express.Router();
20
+
21
+ authRoutes.init(router);
22
+ app.use(router);
23
+
24
+ const isProduction = process.env.NODE_ENV === 'production' || process.env.ABT_NODE_SERVICE_ENV === 'production';
25
+
26
+ if (isProduction) {
27
+ const staticDir = path.resolve(__dirname, '../dist');
28
+ app.use(express.static(staticDir, { maxAge: '30d', index: false }));
29
+ app.use(fallback('index.html', { root: staticDir }));
30
+
31
+ // eslint-disable-next-line no-unused-vars
32
+ app.use((err, req, res, next) => {
33
+ logger.error(err.stack);
34
+ res.status(500).send('Something broke!');
35
+ });
36
+ }
37
+
38
+ const port = parseInt(process.env.BLOCKLET_PORT, 10);
39
+
40
+ const server = app.listen(port, (err) => {
41
+ if (err) throw err;
42
+ logger.info(`> ${name} v${version} ready on ${port}`);
43
+ });
44
+
45
+ module.exports = {
46
+ app,
47
+ server,
48
+ };
@@ -0,0 +1,25 @@
1
+ const path = require('path');
2
+ const AuthStorage = require('@arcblock/did-auth-storage-nedb');
3
+ const getWallet = require('@blocklet/sdk/lib/wallet');
4
+ const WalletAuthenticator = require('@blocklet/sdk/lib/wallet-authenticator');
5
+ const WalletHandler = require('@blocklet/sdk/lib/wallet-handler');
6
+ const Client = require('@ocap/client');
7
+
8
+ const env = require('./env');
9
+
10
+ const client = new Client(env.chainHost);
11
+ const wallet = getWallet();
12
+ const authenticator = new WalletAuthenticator();
13
+ const handlers = new WalletHandler({
14
+ authenticator,
15
+ tokenStorage: new AuthStorage({
16
+ dbPath: path.join(env.dataDir, 'auth.db'),
17
+ }),
18
+ });
19
+
20
+ module.exports = {
21
+ authenticator,
22
+ handlers,
23
+ wallet,
24
+ client,
25
+ };
@@ -0,0 +1,9 @@
1
+ const env = require('@blocklet/sdk/lib/env');
2
+
3
+ module.exports = {
4
+ ...env,
5
+ chainHost: process.env.CHAIN_HOST || '',
6
+ chainId: 'playground',
7
+ localTokenId: process.env.LOCAL_TOKEN_ID || 'z35n6UoHSi9MED4uaQy6ozFgKPaZj2UKrurBG',
8
+ apiPrefix: process.env.API_PREFIX || '',
9
+ };
@@ -0,0 +1,3 @@
1
+ const logger = console;
2
+
3
+ module.exports = logger;
@@ -0,0 +1,70 @@
1
+ const { getRandomBytes } = require('@ocap/mcrypto');
2
+ const pick = require('lodash/pick');
3
+ const { toAddress, fromBase58 } = require('@ocap/util');
4
+ const { isFromPublicKey, toTypeInfo } = require('@arcblock/did');
5
+ const { fromPublicKey } = require('@ocap/wallet');
6
+
7
+ const { client } = require('./auth');
8
+ const env = require('./env');
9
+
10
+ const getRandomMessage = (len = 16) => {
11
+ const hex = getRandomBytes(len);
12
+ return hex.replace(/^0x/, '').toUpperCase();
13
+ };
14
+
15
+ const getTokenInfo = async () => {
16
+ const [{ state }] = await Promise.all([client.getTokenState({ address: env.localTokenId })]);
17
+
18
+ const result = {
19
+ symbol: state.symbol,
20
+ decimal: state.decimal,
21
+ };
22
+
23
+ return result;
24
+ };
25
+ const pickGasPayerHeaders = ({ headers }) => ({ headers: pick(headers, ['x-gas-payer-sig', 'x-gas-payer-pk']) });
26
+
27
+ const verifyAssetClaim = async ({ claim, challenge, trustedIssuers = [], trustedParents = [] }) => {
28
+ const fields = ['asset', 'ownerProof', 'ownerPk', 'ownerDid'];
29
+ for (const field of fields) {
30
+ if (!claim[field]) {
31
+ throw new Error(`Invalid asset claim: ${field} is missing`);
32
+ }
33
+ }
34
+
35
+ const address = claim.asset;
36
+ const ownerDid = toAddress(claim.ownerDid);
37
+ const ownerPk = fromBase58(claim.ownerPk);
38
+ const ownerProof = fromBase58(claim.ownerProof);
39
+ if (isFromPublicKey(ownerDid, ownerPk) === false) {
40
+ throw new Error('Invalid asset claim: owner did and pk mismatch');
41
+ }
42
+
43
+ const owner = fromPublicKey(ownerPk, toTypeInfo(ownerDid));
44
+ if (owner.verify(challenge, ownerProof) === false) {
45
+ throw new Error('Invalid asset claim: owner proof invalid');
46
+ }
47
+
48
+ const { state } = await client.getAssetState({ address }, { ignoreFields: ['context'] });
49
+ if (!state) {
50
+ throw new Error('Invalid asset claim: asset not found on chain');
51
+ }
52
+ if (state.owner !== ownerDid) {
53
+ throw new Error('Invalid asset claim: owner does not match with on chain state');
54
+ }
55
+ if (trustedIssuers.length && trustedIssuers.includes(state.issuer) === false) {
56
+ throw new Error('Invalid asset claim: asset issuer not in whitelist');
57
+ }
58
+ if (trustedParents.length && trustedParents.includes(state.parent) === false) {
59
+ throw new Error('Invalid asset claim: asset parent not in whitelist');
60
+ }
61
+
62
+ return state;
63
+ };
64
+
65
+ module.exports = {
66
+ getRandomMessage,
67
+ getTokenInfo,
68
+ pickGasPayerHeaders,
69
+ verifyAssetClaim,
70
+ };
@@ -0,0 +1,15 @@
1
+ /* eslint-disable global-require */
2
+ const { handlers } = require('../../libs/auth');
3
+
4
+ module.exports = {
5
+ init(app) {
6
+ handlers.attach({ app, ...require('./request-profile') });
7
+ handlers.attach({ app, ...require('./request-text-signature') });
8
+ handlers.attach({ app, ...require('./request-digest-signature') });
9
+ handlers.attach({ app, ...require('./request-transaction-signature') });
10
+ handlers.attach({ app, ...require('./request-payment') });
11
+ handlers.attach({ app, ...require('./request-nft') });
12
+ handlers.attach({ app, ...require('./request-multiple-claims') });
13
+ handlers.attach({ app, ...require('./request-multiple-steps') });
14
+ },
15
+ };
@@ -0,0 +1,51 @@
1
+ const { toTypeInfo } = require('@arcblock/did');
2
+ const { fromPublicKey } = require('@ocap/wallet');
3
+ const { types, getHasher } = require('@ocap/mcrypto');
4
+ const { toBase58 } = require('@ocap/util');
5
+
6
+ const logger = require('../../libs/logger');
7
+
8
+ const hasher = getHasher(types.HashType.SHA3);
9
+ const data = 'abcdefghijklmnopqrstuvwxyz'.repeat(32);
10
+
11
+ const action = 'request-digest-signature';
12
+
13
+ module.exports = {
14
+ action,
15
+ claims: {
16
+ signature: () => {
17
+ return {
18
+ description: 'Please sign the digest',
19
+ digest: toBase58(hasher(data, 1)),
20
+ };
21
+ },
22
+ },
23
+
24
+ onAuth: ({ userDid, userPk, claims, updateSession }) => {
25
+ const type = toTypeInfo(userDid);
26
+ const user = fromPublicKey(userPk, type);
27
+ const claim = claims.find((x) => x.type === 'signature');
28
+
29
+ logger.info(`${action}.onAuth`, { userPk, userDid, claim });
30
+
31
+ if (claim.origin) {
32
+ if (user.verify(claim.origin, claim.sig, claim.method !== 'none') === false) {
33
+ throw new Error('Invalid origin signature');
34
+ }
35
+ }
36
+
37
+ // We do not need to hash the data when verifying
38
+ if (claim.digest) {
39
+ if (user.verify(claim.digest, claim.sig, false) === false) {
40
+ throw new Error('Invalid digest signature');
41
+ }
42
+ }
43
+ updateSession({
44
+ result: {
45
+ origin: data,
46
+ digest: claim.digest,
47
+ sig: claim.sig,
48
+ },
49
+ });
50
+ },
51
+ };
@@ -0,0 +1,52 @@
1
+ const { fromBase58, toBase58 } = require('@ocap/util');
2
+ const { getHasher, types } = require('@ocap/mcrypto');
3
+
4
+ const { getRandomMessage } = require('../../libs/utils');
5
+ const logger = require('../../libs/logger');
6
+
7
+ const hasher = getHasher(types.HashType.SHA3);
8
+ const data = 'abcdefghijklmnopqrstuvwxyz'.repeat(32);
9
+
10
+ const action = 'request-multiple-claims';
11
+
12
+ module.exports = {
13
+ action,
14
+ claims: {
15
+ signText: [
16
+ 'signature',
17
+ () => {
18
+ return {
19
+ type: 'mime:text/plain',
20
+ data: getRandomMessage(),
21
+ description: 'Please sign the text',
22
+ };
23
+ },
24
+ ],
25
+ signDigest: [
26
+ 'signature',
27
+ () => {
28
+ return {
29
+ description: 'Please sign the digest',
30
+ digest: toBase58(hasher(data, 1)),
31
+ };
32
+ },
33
+ ],
34
+ },
35
+
36
+ onAuth: ({ userDid, userPk, claims, updateSession }) => {
37
+ logger.info(`${action}.onAuth`, { userPk, userDid, claims });
38
+ updateSession({
39
+ result: [
40
+ {
41
+ origin: fromBase58(claims[0].origin).toString(),
42
+ sig: claims[0].sig,
43
+ },
44
+ {
45
+ origin: data,
46
+ digest: claims[1].digest,
47
+ sig: claims[1].sig,
48
+ },
49
+ ],
50
+ });
51
+ },
52
+ };