create-blocklet 0.9.6 → 0.9.8
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/common/.prettierrc +11 -1
- package/common/scripts/build-clean.mjs +0 -1
- package/common/scripts/bump-version.mjs +33 -29
- package/index.js +16 -10
- package/lib/did.js +10 -5
- package/package.json +1 -1
- package/templates/did-connect-dapp/.eslintrc.js +4 -0
- package/templates/did-connect-dapp/README.md +35 -0
- package/templates/did-connect-dapp/api/dev.js +5 -0
- package/templates/did-connect-dapp/api/hooks/pre-start.js +33 -0
- package/templates/did-connect-dapp/api/index.js +48 -0
- package/templates/did-connect-dapp/api/libs/auth.js +25 -0
- package/templates/did-connect-dapp/api/libs/env.js +9 -0
- package/templates/did-connect-dapp/api/libs/logger.js +3 -0
- package/templates/did-connect-dapp/api/libs/utils.js +70 -0
- package/templates/did-connect-dapp/api/routes/auth/index.js +15 -0
- package/templates/did-connect-dapp/api/routes/auth/request-digest-signature.js +51 -0
- package/templates/did-connect-dapp/api/routes/auth/request-multiple-claims.js +52 -0
- package/templates/did-connect-dapp/api/routes/auth/request-multiple-steps.js +57 -0
- package/templates/did-connect-dapp/api/routes/auth/request-nft.js +82 -0
- package/templates/did-connect-dapp/api/routes/auth/request-payment.js +72 -0
- package/templates/did-connect-dapp/api/routes/auth/request-profile.js +25 -0
- package/templates/did-connect-dapp/api/routes/auth/request-text-signature.js +44 -0
- package/templates/did-connect-dapp/api/routes/auth/request-transaction-signature.js +62 -0
- package/templates/did-connect-dapp/blocklet.md +5 -0
- package/templates/did-connect-dapp/blocklet.yml +57 -0
- package/templates/did-connect-dapp/index.html +17 -0
- package/templates/did-connect-dapp/package.json +86 -0
- package/templates/did-connect-dapp/src/app.jsx +20 -0
- package/templates/did-connect-dapp/src/assets/get_wallet_en.png +0 -0
- package/templates/did-connect-dapp/src/assets/get_wallet_zh.png +0 -0
- package/templates/did-connect-dapp/src/components/connect-item.jsx +39 -0
- package/templates/did-connect-dapp/src/components/connects/request-digest-signature.jsx +45 -0
- package/templates/did-connect-dapp/src/components/connects/request-multiple-claims.jsx +55 -0
- package/templates/did-connect-dapp/src/components/connects/request-multiple-steps.jsx +54 -0
- package/templates/did-connect-dapp/src/components/connects/request-nft.jsx +75 -0
- package/templates/did-connect-dapp/src/components/connects/request-payment.jsx +82 -0
- package/templates/did-connect-dapp/src/components/connects/request-profile.jsx +72 -0
- package/templates/did-connect-dapp/src/components/connects/request-text-signature.jsx +44 -0
- package/templates/did-connect-dapp/src/components/connects/request-transaction-signature.jsx +44 -0
- package/templates/did-connect-dapp/src/components/info-row.jsx +39 -0
- package/templates/did-connect-dapp/src/components/layout.jsx +26 -0
- package/templates/did-connect-dapp/src/index.jsx +6 -0
- package/templates/did-connect-dapp/src/libs/session.js +11 -0
- package/templates/did-connect-dapp/src/libs/utils.js +4 -0
- package/templates/did-connect-dapp/src/locales/en.js +115 -0
- package/templates/did-connect-dapp/src/locales/index.js +5 -0
- package/templates/did-connect-dapp/src/locales/zh.js +115 -0
- package/templates/did-connect-dapp/src/pages/main.jsx +95 -0
- package/templates/did-connect-dapp/template-info.json +12 -0
- package/templates/did-connect-dapp/vite.config.mjs +11 -0
- package/templates/did-wallet-dapp/blocklet.yml +1 -2
- package/templates/did-wallet-dapp/package.json +18 -18
- package/templates/express-api/blocklet.yml +0 -1
- package/templates/express-api/package.json +9 -8
- package/templates/html-static/blocklet.yml +0 -1
- package/templates/html-static/package.json +4 -3
- package/templates/monorepo/package.json +4 -3
- package/templates/monorepo/scripts/bump-version.mjs +36 -32
- package/templates/nestjs-api/blocklet.yml +0 -1
- package/templates/nestjs-api/package.json +16 -15
- package/templates/nextjs-dapp/blocklet.yml +0 -1
- package/templates/nextjs-dapp/package.json +7 -7
- package/templates/react-dapp/blocklet.yml +0 -1
- package/templates/react-dapp/package.json +16 -15
- package/templates/react-dapp-ts/blocklet.yml +0 -1
- package/templates/react-dapp-ts/package.json +19 -18
- package/templates/react-gun-dapp/blocklet.yml +0 -1
- package/templates/react-gun-dapp/package.json +15 -14
- package/templates/react-static/blocklet.yml +0 -1
- package/templates/react-static/package.json +11 -10
- package/templates/solidjs-dapp/blocklet.yml +0 -1
- package/templates/solidjs-dapp/package.json +14 -13
- package/templates/solidjs-static/blocklet.yml +0 -1
- package/templates/solidjs-static/package.json +9 -8
- package/templates/svelte-dapp/blocklet.yml +0 -1
- package/templates/svelte-dapp/package.json +13 -12
- package/templates/svelte-static/blocklet.yml +0 -1
- package/templates/svelte-static/package.json +9 -8
- package/templates/todo-list-example/blocklet.yml +0 -1
- package/templates/todo-list-example/package.json +13 -12
- package/templates/vue-dapp/blocklet.yml +0 -1
- package/templates/vue-dapp/package.json +16 -15
- package/templates/vue-static/blocklet.yml +0 -1
- package/templates/vue-static/package.json +11 -10
- package/templates/vue-ts-static/blocklet.yml +1 -2
- package/templates/vue-ts-static/package.json +12 -12
- package/templates/vue2-dapp/blocklet.yml +0 -1
- package/templates/vue2-dapp/package.json +13 -12
- package/templates/vue2-static/blocklet.yml +0 -1
- package/templates/vue2-static/package.json +9 -8
package/common/.prettierrc
CHANGED
|
@@ -6,5 +6,15 @@
|
|
|
6
6
|
"bracketSameLine": true,
|
|
7
7
|
"semi": true,
|
|
8
8
|
"singleQuote": true,
|
|
9
|
-
"
|
|
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
|
}
|
|
@@ -2,34 +2,38 @@
|
|
|
2
2
|
import { execSync } from 'child_process';
|
|
3
3
|
import { $, chalk, fs } from 'zx';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
await fs.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
97
|
+
color: green,
|
|
93
98
|
},
|
|
94
99
|
{
|
|
95
100
|
name: 'solidjs-static',
|
|
96
101
|
display: '[static] solidjs',
|
|
97
|
-
color:
|
|
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:
|
|
122
|
+
color: green,
|
|
118
123
|
},
|
|
119
124
|
{
|
|
120
125
|
name: 'html-static',
|
|
121
126
|
display: '[static] html',
|
|
122
|
-
color:
|
|
127
|
+
color: green,
|
|
123
128
|
},
|
|
124
129
|
// api
|
|
125
130
|
{
|
|
126
131
|
name: 'express-api',
|
|
127
132
|
display: '[api] express.js',
|
|
128
|
-
color:
|
|
133
|
+
color: blue,
|
|
129
134
|
},
|
|
130
135
|
{
|
|
131
136
|
name: 'nestjs-api',
|
|
132
137
|
display: '[api] nestjs',
|
|
133
|
-
color:
|
|
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
|
-
|
|
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/lib/did.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable import/prefer-default-export */
|
|
2
1
|
import ora from 'ora';
|
|
3
2
|
import Mcrypto from '@ocap/mcrypto';
|
|
4
3
|
import * as jdenticon from 'jdenticon';
|
|
@@ -37,7 +36,8 @@ export async function getBlockletDidList(monikerList = [], connectUrl = '') {
|
|
|
37
36
|
childProcess.stdout.on('data', (data) => {
|
|
38
37
|
const message = data.toString('utf8') || '';
|
|
39
38
|
if (message.includes('gen-key-pair') && message.includes('__connect_url__')) {
|
|
40
|
-
spinner.text =
|
|
39
|
+
spinner.text = 'Waiting for DID Connect to generate a Blocklet DID';
|
|
40
|
+
console.log(message.replace('✔ \n', ''));
|
|
41
41
|
} else {
|
|
42
42
|
lastMessage = message;
|
|
43
43
|
}
|
|
@@ -48,9 +48,14 @@ export async function getBlockletDidList(monikerList = [], connectUrl = '') {
|
|
|
48
48
|
spinner.fail(message);
|
|
49
49
|
}
|
|
50
50
|
});
|
|
51
|
-
childProcess.on('close', () => {
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
childProcess.on('close', (exitCode) => {
|
|
52
|
+
if (exitCode !== 0) {
|
|
53
|
+
spinner.fail();
|
|
54
|
+
reject(new Error('Failed to connect store'));
|
|
55
|
+
} else {
|
|
56
|
+
spinner.succeed();
|
|
57
|
+
resolve(lastMessage);
|
|
58
|
+
}
|
|
54
59
|
});
|
|
55
60
|
childProcess.on('error', (err) => {
|
|
56
61
|
spinner.fail();
|
package/package.json
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# PROJECT_DESCRIPTION
|
|
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
|
|
@@ -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,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
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
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-steps';
|
|
11
|
+
|
|
12
|
+
module.exports = {
|
|
13
|
+
action,
|
|
14
|
+
claims: [
|
|
15
|
+
{
|
|
16
|
+
signature: () => {
|
|
17
|
+
return {
|
|
18
|
+
type: 'mime:text/plain',
|
|
19
|
+
data: getRandomMessage(),
|
|
20
|
+
description: 'Please sign the text',
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
signature: () => {
|
|
26
|
+
return {
|
|
27
|
+
description: 'Please sign the digest',
|
|
28
|
+
digest: toBase58(hasher(data, 1)),
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
|
|
34
|
+
onAuth: ({ userDid, userPk, claims, step, req, updateSession }) => {
|
|
35
|
+
logger.info(`${action}.onAuth`, { step, userPk, userDid, claims });
|
|
36
|
+
const result = req?.context?.store?.result || [];
|
|
37
|
+
const claim = claims.find((x) => x.type === 'signature');
|
|
38
|
+
if (step === 1) {
|
|
39
|
+
result.push({
|
|
40
|
+
step,
|
|
41
|
+
origin: fromBase58(claim.origin).toString(),
|
|
42
|
+
sig: claim.sig,
|
|
43
|
+
});
|
|
44
|
+
} else if (step === 2) {
|
|
45
|
+
result.push({
|
|
46
|
+
step,
|
|
47
|
+
origin: data,
|
|
48
|
+
digest: claim.digest,
|
|
49
|
+
sig: claim.sig,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
updateSession({
|
|
54
|
+
result,
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
};
|