@blocklet/sdk 1.8.1 → 1.8.4
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/README.md +0 -14
- package/lib/connect/authenticator.js +16 -0
- package/lib/connect/handler.js +73 -0
- package/lib/connect/shared.js +34 -0
- package/lib/env.js +24 -0
- package/lib/index.js +4 -2
- package/lib/service/notification.js +99 -17
- package/lib/util/send-notification.js +75 -9
- package/lib/validators/index.js +2 -1
- package/lib/validators/notification.js +6 -1
- package/lib/wallet-authenticator.js +2 -40
- package/package.json +13 -12
- package/lib/logger.js +0 -8
package/README.md
CHANGED
|
@@ -303,20 +303,6 @@ For Blocklet to write business logs, provides a consistent write format.
|
|
|
303
303
|
|
|
304
304
|
### Usage
|
|
305
305
|
|
|
306
|
-
```javascript
|
|
307
|
-
const { logger } = require('@blocklet/sdk');
|
|
308
|
-
|
|
309
|
-
// log
|
|
310
|
-
log = logger('demo');
|
|
311
|
-
log.info('this is demo', { id: 'test-id' });
|
|
312
|
-
log.warn('this is demo', { id: 'test-id' });
|
|
313
|
-
log.error('this is demo', { id: 'test-id' });
|
|
314
|
-
log.debug('this is demo', { id: 'test-id' });
|
|
315
|
-
|
|
316
|
-
// access log
|
|
317
|
-
app.use(morgan('combined', { stream: logger.getAccessLogStream() }));
|
|
318
|
-
```
|
|
319
|
-
|
|
320
306
|
## getWallet
|
|
321
307
|
|
|
322
308
|
### Usage
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const { Authenticator } = require('@did-connect/authenticator');
|
|
2
|
+
|
|
3
|
+
const getWallet = require('../wallet');
|
|
4
|
+
const checkBlockletEnv = require('../util/check-blocklet-env');
|
|
5
|
+
const getShared = require('./shared');
|
|
6
|
+
|
|
7
|
+
module.exports = class BlockletAuthenticator extends Authenticator {
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
checkBlockletEnv();
|
|
10
|
+
|
|
11
|
+
super({
|
|
12
|
+
wallet: getWallet(),
|
|
13
|
+
...getShared(options),
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const get = require('lodash/get');
|
|
2
|
+
const { createHandlers } = require('@did-connect/handler');
|
|
3
|
+
const Notification = require('../service/notification');
|
|
4
|
+
|
|
5
|
+
const noop = () => ({});
|
|
6
|
+
|
|
7
|
+
// whether app web page is in mobile DID wallet
|
|
8
|
+
const inMobileWallet = (didwallet) => {
|
|
9
|
+
return didwallet && ['ios', 'android'].includes(didwallet.os);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const consoleLogger = { info: noop, error: console.error, warn: console.warn, debug: noop };
|
|
13
|
+
const getConnectedDid = (session) => {
|
|
14
|
+
if (session.autoConnect === false) {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (inMobileWallet(session.didwallet)) {
|
|
19
|
+
return '';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return get(session, 'previousConnected.userDid', '');
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
module.exports = ({ authenticator, storage, logger = consoleLogger, socketPathname, sendNotificationFn }) => {
|
|
26
|
+
const handlers = createHandlers({
|
|
27
|
+
storage,
|
|
28
|
+
authenticator,
|
|
29
|
+
logger,
|
|
30
|
+
socketPathname,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const originCreateHandler = handlers.handleSessionCreate;
|
|
34
|
+
handlers.handleSessionCreate = async (context) => {
|
|
35
|
+
const session = await originCreateHandler(context);
|
|
36
|
+
const connectedDid = getConnectedDid(session);
|
|
37
|
+
|
|
38
|
+
// send notification to wallet to trigger wallet to auto connect
|
|
39
|
+
if (connectedDid) {
|
|
40
|
+
// wallet use check url to check status of the session
|
|
41
|
+
let checkUrl = '';
|
|
42
|
+
try {
|
|
43
|
+
checkUrl = new URL(session.authUrl);
|
|
44
|
+
checkUrl.pathname = checkUrl.pathname.replace(/\/auth/, '/session');
|
|
45
|
+
} catch (e) {
|
|
46
|
+
checkUrl = '';
|
|
47
|
+
console.error(e);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const deepLink = new URL('https://abtwallet.io/i/');
|
|
51
|
+
deepLink.searchParams.set('action', 'requestAuth');
|
|
52
|
+
deepLink.searchParams.set('url', encodeURIComponent(session.authUrl));
|
|
53
|
+
const message = {
|
|
54
|
+
type: 'connect',
|
|
55
|
+
url: deepLink.href,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
if (checkUrl) {
|
|
59
|
+
message.checkUrl = checkUrl.href;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// sendNotificationFn maybe custom function so we need params
|
|
63
|
+
const sendFn = sendNotificationFn || Notification.sendToUser.bind(Notification);
|
|
64
|
+
sendFn(connectedDid, message, { ...context, session }).catch((err) => {
|
|
65
|
+
console.error(err);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return session;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
return handlers;
|
|
73
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const joinUrl = require('url-join');
|
|
2
|
+
const { getConnectAppUrl } = require('@blocklet/meta/lib/util');
|
|
3
|
+
const { SERVICE_PREFIX } = require('../util/constants');
|
|
4
|
+
|
|
5
|
+
// wraps value in closure or returns closure
|
|
6
|
+
const closure = (value) => (typeof value === 'function' ? value : () => value);
|
|
7
|
+
|
|
8
|
+
module.exports = (options = {}) => ({
|
|
9
|
+
chainInfo: () => {
|
|
10
|
+
const chainHost = process.env.CHAIN_HOST;
|
|
11
|
+
return chainHost ? { host: chainHost, id: 'chain' } : { host: 'none', id: 'none' };
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
...options,
|
|
15
|
+
|
|
16
|
+
appInfo: async (...args) => {
|
|
17
|
+
const info = await closure(options.appInfo)(...args);
|
|
18
|
+
|
|
19
|
+
const { request, baseUrl } = args[0];
|
|
20
|
+
const groupPathPrefix = request.headers['x-group-path-prefix'] || '/';
|
|
21
|
+
const blockletDid = request.headers['x-blocklet-did'];
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
name: process.env.BLOCKLET_APP_NAME,
|
|
25
|
+
description: process.env.BLOCKLET_APP_DESCRIPTION,
|
|
26
|
+
...(info || {}),
|
|
27
|
+
link: getConnectAppUrl(args[0]),
|
|
28
|
+
icon: joinUrl(baseUrl, SERVICE_PREFIX, `/blocklet/logo/${blockletDid}`),
|
|
29
|
+
updateSubEndpoint: true,
|
|
30
|
+
subscriptionEndpoint: joinUrl(groupPathPrefix, SERVICE_PREFIX, 'websocket'),
|
|
31
|
+
nodeDid: process.env.ABT_NODE_DID,
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
});
|
package/lib/env.js
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
const { getParentComponentName } = require('@blocklet/meta/lib/util');
|
|
2
|
+
|
|
3
|
+
const parsePorts = () => JSON.parse(process.env.BLOCKLET_WEB_PORTS);
|
|
4
|
+
|
|
5
|
+
const getWebEndpoint = (name) => {
|
|
6
|
+
const ports = parsePorts();
|
|
7
|
+
if (ports[name]) {
|
|
8
|
+
return `http://127.0.0.1:${ports[name]}`;
|
|
9
|
+
}
|
|
10
|
+
return '';
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const getChildWebEndpoint = (name) => {
|
|
14
|
+
const fullName = `${process.env.BLOCKLET_REAL_NAME}/${name}`;
|
|
15
|
+
return getWebEndpoint(fullName);
|
|
16
|
+
};
|
|
17
|
+
const getParentWebEndpoint = () => {
|
|
18
|
+
const parentName = getParentComponentName(process.env.BLOCKLET_REAL_NAME);
|
|
19
|
+
return getWebEndpoint(parentName);
|
|
20
|
+
};
|
|
21
|
+
|
|
1
22
|
module.exports = Object.freeze({
|
|
2
23
|
appId: process.env.BLOCKLET_APP_ID,
|
|
3
24
|
appName: process.env.BLOCKLET_APP_NAME,
|
|
@@ -6,4 +27,7 @@ module.exports = Object.freeze({
|
|
|
6
27
|
isComponent: process.env.BLOCKLET_DID !== process.env.BLOCKLET_REAL_DID,
|
|
7
28
|
dataDir: process.env.BLOCKLET_DATA_DIR,
|
|
8
29
|
cacheDir: process.env.BLOCKLET_CACHE_DIR,
|
|
30
|
+
getWebEndpoint,
|
|
31
|
+
getChildWebEndpoint,
|
|
32
|
+
getParentWebEndpoint,
|
|
9
33
|
});
|
package/lib/index.js
CHANGED
|
@@ -2,20 +2,22 @@ const AuthService = require('./service/auth');
|
|
|
2
2
|
const NotificationService = require('./service/notification');
|
|
3
3
|
const WalletAuthenticator = require('./wallet-authenticator');
|
|
4
4
|
const WalletHandlers = require('./wallet-handler');
|
|
5
|
+
const BlockletAuthenticator = require('./connect/authenticator');
|
|
6
|
+
const createConnectHandlers = require('./connect/handler');
|
|
5
7
|
const Database = require('./database');
|
|
6
8
|
const env = require('./env');
|
|
7
9
|
const middlewares = require('./middlewares');
|
|
8
10
|
const getWallet = require('./wallet');
|
|
9
|
-
const logger = require('./logger');
|
|
10
11
|
|
|
11
12
|
module.exports = {
|
|
12
13
|
AuthService,
|
|
13
14
|
NotificationService,
|
|
14
15
|
WalletHandlers,
|
|
15
16
|
WalletAuthenticator,
|
|
17
|
+
BlockletAuthenticator,
|
|
18
|
+
createConnectHandlers,
|
|
16
19
|
Database,
|
|
17
20
|
getWallet,
|
|
18
21
|
env,
|
|
19
22
|
middlewares,
|
|
20
|
-
logger,
|
|
21
23
|
};
|
|
@@ -2,25 +2,62 @@ const Jwt = require('@arcblock/jwt');
|
|
|
2
2
|
const EventEmitter = require('events');
|
|
3
3
|
|
|
4
4
|
const { WsClient } = require('@arcblock/ws');
|
|
5
|
+
const { getAppPublicChannel } = require('@blocklet/meta/lib/channel');
|
|
5
6
|
|
|
6
7
|
const checkBlockletEnv = require('../util/check-blocklet-env');
|
|
7
|
-
const
|
|
8
|
+
const { sendToUser, sendToAppChannel } = require('../util/send-notification');
|
|
8
9
|
const { SERVICE_PREFIX } = require('../util/constants');
|
|
9
10
|
const getWallet = require('../wallet');
|
|
11
|
+
const { NOTIFICATION_TYPES } = require('../validators/notification');
|
|
10
12
|
|
|
11
|
-
const
|
|
13
|
+
const getSender = () => ({
|
|
14
|
+
appDid: process.env.BLOCKLET_APP_ID,
|
|
15
|
+
appSk: process.env.BLOCKLET_APP_SK,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param {Notification} notification
|
|
21
|
+
* @param {{
|
|
22
|
+
* keepForOfflineUser: Boolean
|
|
23
|
+
* }} options
|
|
24
|
+
* @returns
|
|
25
|
+
*/
|
|
26
|
+
const doSendToUser = async (receiver, notification, options) => {
|
|
27
|
+
checkBlockletEnv();
|
|
28
|
+
|
|
29
|
+
return sendToUser(receiver, notification, getSender(), process.env.ABT_NODE_SERVICE_PORT, options);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param {Notification} notification
|
|
35
|
+
* @param {{
|
|
36
|
+
* channel: String
|
|
37
|
+
* event: String
|
|
38
|
+
* socketId: String
|
|
39
|
+
* socketDid: String
|
|
40
|
+
* }} options
|
|
41
|
+
* @returns
|
|
42
|
+
*/
|
|
43
|
+
const broadcast = async (notification, options = {}) => {
|
|
12
44
|
checkBlockletEnv();
|
|
13
45
|
|
|
14
|
-
const sender =
|
|
15
|
-
appId: process.env.BLOCKLET_APP_ID,
|
|
16
|
-
appSk: process.env.BLOCKLET_APP_SK,
|
|
17
|
-
did: process.env.BLOCKLET_DID,
|
|
18
|
-
};
|
|
46
|
+
const sender = getSender();
|
|
19
47
|
|
|
20
|
-
|
|
48
|
+
const { channel = getAppPublicChannel(sender.appDid) } = options;
|
|
49
|
+
const { event = 'message' } = options;
|
|
50
|
+
|
|
51
|
+
return sendToAppChannel(channel, event, notification, sender, process.env.ABT_NODE_SERVICE_PORT, options);
|
|
21
52
|
};
|
|
22
53
|
|
|
23
54
|
const emitter = new EventEmitter();
|
|
55
|
+
const messageEmitter = new EventEmitter();
|
|
56
|
+
|
|
57
|
+
const emitError = (error) => {
|
|
58
|
+
messageEmitter.emit('error', error);
|
|
59
|
+
emitter.emit('error', error);
|
|
60
|
+
};
|
|
24
61
|
|
|
25
62
|
let client = null;
|
|
26
63
|
|
|
@@ -41,9 +78,38 @@ const initClient = () => {
|
|
|
41
78
|
|
|
42
79
|
client.connect();
|
|
43
80
|
|
|
44
|
-
const
|
|
81
|
+
const messageChannel = client.channel(did, () => ({ token: token(), pk }));
|
|
82
|
+
const appPublicChannel = client.channel(getAppPublicChannel(did), () => ({ token: token(), pk }));
|
|
45
83
|
|
|
46
|
-
|
|
84
|
+
messageChannel
|
|
85
|
+
.join()
|
|
86
|
+
.receive('error', (err) => {
|
|
87
|
+
const msg = `join channel error: ${err.message}`;
|
|
88
|
+
console.error(msg);
|
|
89
|
+
emitError({ message: msg });
|
|
90
|
+
})
|
|
91
|
+
.receive('timeout', () => {
|
|
92
|
+
const msg = 'join channel timeout';
|
|
93
|
+
console.error(msg);
|
|
94
|
+
emitError({ message: msg });
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
messageChannel.on('message', ({ status, response } = {}) => {
|
|
98
|
+
if (status === 'ok') {
|
|
99
|
+
messageEmitter.emit(response.type, response);
|
|
100
|
+
if (response.type === NOTIFICATION_TYPES.HI) {
|
|
101
|
+
emitter.emit(response.type, response);
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
emitError(response);
|
|
105
|
+
console.error({
|
|
106
|
+
status,
|
|
107
|
+
response,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
appPublicChannel
|
|
47
113
|
.join()
|
|
48
114
|
.receive('error', (err) => {
|
|
49
115
|
const msg = `join channel error: ${err.message}`;
|
|
@@ -56,9 +122,9 @@ const initClient = () => {
|
|
|
56
122
|
emitter.emit('error', { message: msg });
|
|
57
123
|
});
|
|
58
124
|
|
|
59
|
-
|
|
125
|
+
appPublicChannel.on(NOTIFICATION_TYPES.HI, ({ status, response } = {}) => {
|
|
60
126
|
if (status === 'ok') {
|
|
61
|
-
emitter.emit(
|
|
127
|
+
emitter.emit(NOTIFICATION_TYPES.HI, response);
|
|
62
128
|
} else {
|
|
63
129
|
emitter.emit('error', response);
|
|
64
130
|
console.error({
|
|
@@ -70,14 +136,30 @@ const initClient = () => {
|
|
|
70
136
|
}
|
|
71
137
|
};
|
|
72
138
|
|
|
139
|
+
const ensureClient = () => {
|
|
140
|
+
if (!client) {
|
|
141
|
+
initClient();
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
73
145
|
module.exports = {
|
|
74
|
-
sendToUser,
|
|
75
|
-
|
|
76
|
-
if (!client) {
|
|
77
|
-
initClient();
|
|
78
|
-
}
|
|
146
|
+
sendToUser: doSendToUser,
|
|
147
|
+
broadcast,
|
|
79
148
|
|
|
149
|
+
// System notification
|
|
150
|
+
on: (event, cb) => {
|
|
151
|
+
ensureClient();
|
|
80
152
|
return emitter.on(event, cb);
|
|
81
153
|
},
|
|
82
154
|
off: emitter.off.bind(emitter),
|
|
155
|
+
|
|
156
|
+
// Just for DID Wallet developing
|
|
157
|
+
// Any message received from any account
|
|
158
|
+
_message: {
|
|
159
|
+
on: (event, cb) => {
|
|
160
|
+
ensureClient();
|
|
161
|
+
return messageEmitter.on(event, cb);
|
|
162
|
+
},
|
|
163
|
+
off: messageEmitter.off.bind(messageEmitter),
|
|
164
|
+
},
|
|
83
165
|
};
|
|
@@ -10,26 +10,32 @@ const { SERVICE_PREFIX } = require('./constants');
|
|
|
10
10
|
|
|
11
11
|
const VERSION = require('../../package.json').version; // version of notification sdk
|
|
12
12
|
|
|
13
|
-
const { validateNotification, validateReceiver, validateOption } = validators;
|
|
13
|
+
const { validateNotification, validateReceiver, validateOption, validateChannelEvent } = validators;
|
|
14
14
|
|
|
15
15
|
const SERVER_MODE = process.env.ABT_NODE_MODE;
|
|
16
16
|
|
|
17
|
+
const getRequestHeaders = () => ({ 'User-Agent': `BlockletSDK/${VERSION}` });
|
|
18
|
+
|
|
17
19
|
/**
|
|
18
20
|
* @param {String|Array} receiver
|
|
19
21
|
* @param {Object} notification
|
|
20
|
-
* @param {
|
|
22
|
+
* @param {{
|
|
23
|
+
* appDid: String
|
|
24
|
+
* appSk: String
|
|
25
|
+
* }} sender
|
|
21
26
|
* @param {String|Number} port port of abtnode service endpoint
|
|
22
27
|
* @param {Object} options
|
|
23
28
|
* @returns
|
|
24
29
|
*/
|
|
25
|
-
|
|
30
|
+
const sendToUser = async (
|
|
26
31
|
receiver,
|
|
27
32
|
notification,
|
|
28
|
-
{
|
|
33
|
+
{ appDid, appSk } = {},
|
|
29
34
|
port = process.env.ABT_NODE_SERVICE_PORT,
|
|
30
35
|
options = {}
|
|
31
36
|
) => {
|
|
32
37
|
await validateReceiver(receiver);
|
|
38
|
+
|
|
33
39
|
const opt = pick(options, ['keepForOfflineUser']);
|
|
34
40
|
await validateOption(opt);
|
|
35
41
|
|
|
@@ -37,27 +43,87 @@ module.exports = async (
|
|
|
37
43
|
await validateNotification(notification);
|
|
38
44
|
}
|
|
39
45
|
|
|
40
|
-
const token = JWT.sign(appId, appSk);
|
|
41
|
-
|
|
42
46
|
try {
|
|
43
47
|
const { data: res } = await axios.post(
|
|
44
|
-
`http://127.0.0.1:${port}${SERVICE_PREFIX}/api/
|
|
48
|
+
`http://127.0.0.1:${port}${SERVICE_PREFIX}/api/send-to-user`,
|
|
45
49
|
{
|
|
46
50
|
apiVersion: VERSION,
|
|
47
51
|
data: {
|
|
48
|
-
sender: {
|
|
52
|
+
sender: { appDid, token: JWT.sign(appDid, appSk) },
|
|
49
53
|
receiver,
|
|
50
54
|
notification,
|
|
51
55
|
options: opt,
|
|
52
56
|
},
|
|
53
57
|
},
|
|
54
58
|
{
|
|
55
|
-
|
|
59
|
+
timeout: 60 * 1000,
|
|
60
|
+
headers: getRequestHeaders(),
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
return res;
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error(error);
|
|
67
|
+
throw new Error(error.response ? error.response.statusText : error.message);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const sendToAppChannel = async (
|
|
72
|
+
channel,
|
|
73
|
+
event,
|
|
74
|
+
notification,
|
|
75
|
+
{ appDid, appSk } = {},
|
|
76
|
+
port = process.env.ABT_NODE_SERVICE_PORT,
|
|
77
|
+
options = {}
|
|
78
|
+
) => {
|
|
79
|
+
if (!channel) {
|
|
80
|
+
throw new Error('channel is required');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!event) {
|
|
84
|
+
throw new Error('event is required');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
await validateChannelEvent(event);
|
|
88
|
+
|
|
89
|
+
const opt = pick(options, ['socketId', 'userDid']);
|
|
90
|
+
|
|
91
|
+
if (opt.userDid) {
|
|
92
|
+
opt.socketDid = opt.userDid;
|
|
93
|
+
delete opt.userDid;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (SERVER_MODE !== NODE_MODES.DEBUG) {
|
|
97
|
+
await validateNotification(notification);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
const { data: res } = await axios.post(
|
|
102
|
+
`http://127.0.0.1:${port}${SERVICE_PREFIX}/api/send-to-app-channel`,
|
|
103
|
+
{
|
|
104
|
+
apiVersion: VERSION,
|
|
105
|
+
data: {
|
|
106
|
+
sender: { appDid, token: JWT.sign(appDid, appSk) },
|
|
107
|
+
channel,
|
|
108
|
+
event,
|
|
109
|
+
notification,
|
|
110
|
+
options: opt,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
timeout: 60 * 1000,
|
|
115
|
+
headers: getRequestHeaders(),
|
|
56
116
|
}
|
|
57
117
|
);
|
|
58
118
|
|
|
59
119
|
return res;
|
|
60
120
|
} catch (error) {
|
|
121
|
+
console.error(error);
|
|
61
122
|
throw new Error(error.response ? error.response.statusText : error.message);
|
|
62
123
|
}
|
|
63
124
|
};
|
|
125
|
+
|
|
126
|
+
module.exports = {
|
|
127
|
+
sendToUser,
|
|
128
|
+
sendToAppChannel,
|
|
129
|
+
};
|
package/lib/validators/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
const { validateNotification, validateReceiver, validateOption } = require('./notification');
|
|
1
|
+
const { validateNotification, validateReceiver, validateOption, validateChannelEvent } = require('./notification');
|
|
2
2
|
|
|
3
3
|
module.exports = {
|
|
4
4
|
validateNotification,
|
|
5
5
|
validateReceiver,
|
|
6
6
|
validateOption,
|
|
7
|
+
validateChannelEvent,
|
|
7
8
|
};
|
|
@@ -89,12 +89,15 @@ const inputReceiverSchema = Joi.alternatives().try(Joi.array().items(receiverSch
|
|
|
89
89
|
|
|
90
90
|
const optionSchema = Joi.object({
|
|
91
91
|
keepForOfflineUser: Joi.boolean(),
|
|
92
|
-
});
|
|
92
|
+
}).unknown();
|
|
93
|
+
|
|
94
|
+
const channelEventSchema = Joi.string().required();
|
|
93
95
|
|
|
94
96
|
module.exports = {
|
|
95
97
|
validateReceiver: inputReceiverSchema.validateAsync.bind(inputReceiverSchema),
|
|
96
98
|
validateNotification: inputNotificationSchema.validateAsync.bind(inputNotificationSchema),
|
|
97
99
|
validateMessage: messageSchema.validateAsync.bind(messageSchema),
|
|
100
|
+
validateChannelEvent: channelEventSchema.validateAsync.bind(channelEventSchema),
|
|
98
101
|
validateOption: optionSchema.validateAsync.bind(optionSchema),
|
|
99
102
|
tokenSchema,
|
|
100
103
|
actionSchema,
|
|
@@ -104,4 +107,6 @@ module.exports = {
|
|
|
104
107
|
notificationSchema,
|
|
105
108
|
messageSchema,
|
|
106
109
|
optionSchema,
|
|
110
|
+
channelEventSchema,
|
|
111
|
+
NOTIFICATION_TYPES: TYPES,
|
|
107
112
|
};
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
const joinUrl = require('url-join');
|
|
2
1
|
const { WalletAuthenticator: Authenticator } = require('@arcblock/did-auth');
|
|
3
2
|
|
|
4
3
|
const getWallet = require('./wallet');
|
|
5
4
|
const checkBlockletEnv = require('./util/check-blocklet-env');
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
const env = require('./env');
|
|
9
|
-
|
|
10
|
-
// wraps value in closure or returns closure
|
|
11
|
-
const closure = (value) => (typeof value === 'function' ? value : () => value);
|
|
5
|
+
const getShared = require('./connect/shared');
|
|
12
6
|
|
|
13
7
|
class WalletAuthenticator extends Authenticator {
|
|
14
8
|
constructor(options = {}) {
|
|
@@ -16,39 +10,7 @@ class WalletAuthenticator extends Authenticator {
|
|
|
16
10
|
|
|
17
11
|
super({
|
|
18
12
|
wallet: getWallet().toJSON(),
|
|
19
|
-
|
|
20
|
-
chainInfo: () => {
|
|
21
|
-
const chainHost = process.env.CHAIN_HOST;
|
|
22
|
-
return chainHost ? { host: chainHost, id: 'chain' } : { host: 'none', id: 'none' };
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
...options,
|
|
26
|
-
|
|
27
|
-
appInfo: async (...args) => {
|
|
28
|
-
const info = await closure(options.appInfo)(...args);
|
|
29
|
-
|
|
30
|
-
const { request, baseUrl } = args[0];
|
|
31
|
-
const pathPrefix = request.headers['x-path-prefix'] || '/';
|
|
32
|
-
const groupPathPrefix = request.headers['x-group-path-prefix'] || '/';
|
|
33
|
-
const blockletDid = request.headers['x-blocklet-did'];
|
|
34
|
-
|
|
35
|
-
// Child blocklets should set appInfo.link to exactly the same path as the root blocklet
|
|
36
|
-
let appUrl = baseUrl;
|
|
37
|
-
if (env.isComponent && pathPrefix !== groupPathPrefix) {
|
|
38
|
-
appUrl = joinUrl(joinUrl(appUrl, '/').replace(pathPrefix, groupPathPrefix), '');
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
name: process.env.BLOCKLET_APP_NAME,
|
|
43
|
-
description: process.env.BLOCKLET_APP_DESCRIPTION,
|
|
44
|
-
...(info || {}),
|
|
45
|
-
link: appUrl,
|
|
46
|
-
icon: joinUrl(baseUrl, SERVICE_PREFIX, `/blocklet/logo/${blockletDid}`),
|
|
47
|
-
updateSubEndpoint: true,
|
|
48
|
-
subscriptionEndpoint: joinUrl(groupPathPrefix, SERVICE_PREFIX, 'websocket'),
|
|
49
|
-
nodeDid: process.env.ABT_NODE_DID,
|
|
50
|
-
};
|
|
51
|
-
},
|
|
13
|
+
...getShared(options),
|
|
52
14
|
});
|
|
53
15
|
}
|
|
54
16
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.8.
|
|
6
|
+
"version": "1.8.4",
|
|
7
7
|
"description": "graphql client to read/write data on abt node",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,16 +19,17 @@
|
|
|
19
19
|
"author": "linchen1987 <linchen.1987@foxmail.com> (http://github.com/linchen1987)",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/client": "1.8.
|
|
23
|
-
"@abtnode/constant": "1.8.
|
|
24
|
-
"@
|
|
25
|
-
"@arcblock/
|
|
26
|
-
"@arcblock/
|
|
27
|
-
"@
|
|
28
|
-
"@
|
|
29
|
-
"@
|
|
30
|
-
"@
|
|
31
|
-
"@ocap/
|
|
22
|
+
"@abtnode/client": "1.8.4",
|
|
23
|
+
"@abtnode/constant": "1.8.4",
|
|
24
|
+
"@arcblock/did-auth": "1.17.5",
|
|
25
|
+
"@arcblock/jwt": "1.17.5",
|
|
26
|
+
"@arcblock/ws": "1.17.5",
|
|
27
|
+
"@blocklet/meta": "1.8.4",
|
|
28
|
+
"@did-connect/authenticator": "^2.0.18",
|
|
29
|
+
"@did-connect/handler": "^2.0.18",
|
|
30
|
+
"@nedb/core": "^1.3.2",
|
|
31
|
+
"@ocap/mcrypto": "1.17.5",
|
|
32
|
+
"@ocap/wallet": "1.17.5",
|
|
32
33
|
"axios": "^0.27.2",
|
|
33
34
|
"fs-extra": "^10.0.1",
|
|
34
35
|
"joi": "^17.6.0",
|
|
@@ -40,5 +41,5 @@
|
|
|
40
41
|
"detect-port": "^1.3.0",
|
|
41
42
|
"jest": "^27.4.5"
|
|
42
43
|
},
|
|
43
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "c42fb1bb84c5eef0f753fd5397d8007c7a6eee19"
|
|
44
45
|
}
|
package/lib/logger.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
const logger = require('@abtnode/logger');
|
|
2
|
-
|
|
3
|
-
if (!process.env.BLOCKLET_LOG_DIR) {
|
|
4
|
-
throw new Error('valid BLOCKLET_LOG_DIR env is required by logger');
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
module.exports = (label) => logger(label, { logDir: process.env.BLOCKLET_LOG_DIR, filename: 'info' });
|
|
8
|
-
module.exports.getAccessLogStream = () => logger.getAccessLogStream(process.env.BLOCKLET_LOG_DIR);
|