@blocklet/sdk 1.16.54-beta-20251017-133309-7d40faa6 → 1.16.54-beta-20251023-041534-36eec6b9

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 (62) hide show
  1. package/lib/config.js +5 -5
  2. package/lib/connect/authenticator.d.ts +1 -1
  3. package/lib/connect/authenticator.js +9 -11
  4. package/lib/connect/handler.d.ts +1 -1
  5. package/lib/connect/handler.js +3 -1
  6. package/lib/connect/shared.d.ts +1 -1
  7. package/lib/connect/shared.js +17 -6
  8. package/lib/database/index.d.ts +2 -2
  9. package/lib/database/index.js +4 -2
  10. package/lib/did.d.ts +2 -2
  11. package/lib/did.js +4 -7
  12. package/lib/env.d.ts +2 -2
  13. package/lib/env.js +4 -5
  14. package/lib/index.d.ts +9 -9
  15. package/lib/index.js +18 -18
  16. package/lib/middlewares/auth.d.ts +3 -3
  17. package/lib/middlewares/auth.js +7 -8
  18. package/lib/middlewares/blocklet.d.ts +2 -2
  19. package/lib/middlewares/blocklet.js +2 -2
  20. package/lib/middlewares/csrf.js +2 -4
  21. package/lib/middlewares/fallback.d.ts +1 -1
  22. package/lib/middlewares/fallback.js +3 -1
  23. package/lib/middlewares/index.d.ts +5 -5
  24. package/lib/middlewares/index.js +15 -15
  25. package/lib/middlewares/session.d.ts +1 -1
  26. package/lib/middlewares/session.js +3 -1
  27. package/lib/middlewares/sitemap.d.ts +1 -1
  28. package/lib/middlewares/sitemap.js +3 -1
  29. package/lib/middlewares/user.d.ts +1 -1
  30. package/lib/middlewares/user.js +3 -1
  31. package/lib/security/index.d.ts +2 -2
  32. package/lib/security/index.js +3 -3
  33. package/lib/service/blocklet.d.ts +5 -2
  34. package/lib/service/blocklet.js +14 -11
  35. package/lib/service/eventbus.d.ts +2 -2
  36. package/lib/service/eventbus.js +5 -8
  37. package/lib/service/notification.d.ts +7 -6
  38. package/lib/service/notification.js +33 -29
  39. package/lib/service/signature.d.ts +27 -0
  40. package/lib/service/signature.js +112 -0
  41. package/lib/util/app-info.d.ts +1 -1
  42. package/lib/util/app-info.js +2 -2
  43. package/lib/util/check-blocklet-env.d.ts +1 -1
  44. package/lib/util/check-blocklet-env.js +4 -2
  45. package/lib/util/component-api.js +8 -4
  46. package/lib/util/csrf.d.ts +5 -0
  47. package/lib/util/csrf.js +9 -0
  48. package/lib/util/jest-setup.js +9 -4
  49. package/lib/util/jest-teardown.js +2 -2
  50. package/lib/util/send-notification.d.ts +13 -10
  51. package/lib/util/send-notification.js +42 -47
  52. package/lib/util/service-api.js +8 -4
  53. package/lib/util/verify-session.js +10 -7
  54. package/lib/util/verify-sign.d.ts +8 -7
  55. package/lib/util/verify-sign.js +11 -42
  56. package/lib/wallet-authenticator.d.ts +1 -1
  57. package/lib/wallet-authenticator.js +9 -10
  58. package/lib/wallet-handler.d.ts +1 -1
  59. package/lib/wallet-handler.js +3 -1
  60. package/lib/wallet.d.ts +35 -7
  61. package/lib/wallet.js +136 -29
  62. package/package.json +19 -18
@@ -7,7 +7,7 @@ exports.verifyResponse = exports.signResponse = exports.decrypt = exports.encryp
7
7
  const crypto_1 = __importDefault(require("crypto"));
8
8
  const aes_legacy_1 = __importDefault(require("@ocap/mcrypto/lib/crypter/aes-legacy"));
9
9
  const security_1 = require("@blocklet/meta/lib/security");
10
- const wallet_1 = __importDefault(require("../wallet"));
10
+ const wallet_1 = require("../wallet");
11
11
  const AES = { default: aes_legacy_1.default }.default;
12
12
  const encrypt = (message, password, salt) => {
13
13
  const _password = password || process.env.BLOCKLET_APP_EK;
@@ -27,9 +27,9 @@ const decrypt = (message, password, salt) => {
27
27
  return AES.decrypt(message, crypto_1.default.pbkdf2Sync(_password, _salt, 256, 32, 'sha512').toString('hex'));
28
28
  };
29
29
  exports.decrypt = decrypt;
30
- const signResponse = (data) => (0, security_1.signResponse)(data, (0, wallet_1.default)());
30
+ const signResponse = (data) => (0, security_1.signResponse)(data, (0, wallet_1.getWallet)());
31
31
  exports.signResponse = signResponse;
32
- const verifyResponse = (data) => (0, security_1.verifyResponse)(data, (0, wallet_1.default)());
32
+ const verifyResponse = (data) => (0, security_1.verifyResponse)(data, (0, wallet_1.getWallet)());
33
33
  exports.verifyResponse = verifyResponse;
34
34
  exports.default = {
35
35
  encrypt,
@@ -1,5 +1,6 @@
1
1
  import Client from '@blocklet/server-js';
2
2
  import { LOGIN_PROVIDER } from '@blocklet/constant';
3
+ import { AxiosHeaders } from 'axios';
3
4
  type PartialDeep<T> = {
4
5
  [K in keyof T]?: T[K] extends object ? PartialDeep<T[K]> : T[K];
5
6
  };
@@ -14,7 +15,9 @@ declare class BlockletService {
14
15
  constructor(httpEndpoint?: string);
15
16
  }
16
17
  interface BlockletService {
17
- login: (params: object) => Promise<{
18
+ login: (params: object, options?: {
19
+ headers: AxiosHeaders;
20
+ }) => Promise<{
18
21
  user: Object;
19
22
  token: string;
20
23
  refreshToken: string;
@@ -94,4 +97,4 @@ interface BlockletService {
94
97
  configBlocklet(params: OmitDid<Client.RequestConfigBlockletInput>): Promise<Client.ResponseBlocklet>;
95
98
  configNavigations(params: OmitDid<Client.RequestConfigNavigationsInput>): Promise<Client.ResponseBlocklet>;
96
99
  }
97
- export = BlockletService;
100
+ export { BlockletService };
@@ -35,6 +35,8 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.BlockletService = void 0;
38
40
  /* eslint-disable prettier/prettier */
39
41
  /* eslint-disable max-classes-per-file */
40
42
  /* eslint-disable @typescript-eslint/indent */
@@ -47,9 +49,9 @@ const constant_2 = require("@blocklet/constant");
47
49
  const util_2 = require("@blocklet/meta/lib/util");
48
50
  const security_1 = require("@blocklet/meta/lib/security");
49
51
  const error_1 = require("@blocklet/error");
50
- const check_blocklet_env_1 = __importDefault(require("../util/check-blocklet-env"));
52
+ const check_blocklet_env_1 = require("../util/check-blocklet-env");
51
53
  const version_1 = require("../version");
52
- const wallet_1 = __importDefault(require("../wallet"));
54
+ const wallet_1 = require("../wallet");
53
55
  const service_api_1 = __importDefault(require("../util/service-api"));
54
56
  const parse_docker_endpoint_1 = require("../util/parse-docker-endpoint");
55
57
  const { WELLKNOWN_SERVICE_PATH_PREFIX, USER_AVATAR_URL_PREFIX, USER_AVATAR_PATH_PREFIX } = constant_1.default;
@@ -64,18 +66,17 @@ const fixAvatar = (user) => {
64
66
  };
65
67
  class BlockletClient extends server_js_1.default {
66
68
  constructor(httpEndpoint) {
67
- (0, check_blocklet_env_1.default)();
69
+ (0, check_blocklet_env_1.checkBlockletEnvironment)();
68
70
  super(httpEndpoint || `http://${(0, parse_docker_endpoint_1.getServerHost)()}:${process.env.ABT_NODE_PORT}/api/gql`.trim(), `BlockletSDK/${VERSION}`);
69
- const wallet = (0, wallet_1.default)();
71
+ const wallet = wallet_1.getWallet.getAccessWallet();
70
72
  this.setAuthAccessKey({
71
73
  accessKeyId: wallet.address,
72
- // for backward compatibility
73
74
  accessKeySecret: (0, util_1.toBuffer)(wallet.secretKey),
74
75
  type: 'sha256',
75
76
  });
76
77
  }
77
- _getAuthHeaders() {
78
- const headers = super._getAuthHeaders();
78
+ async _getAuthHeaders() {
79
+ const headers = await super._getAuthHeaders();
79
80
  // BLOCKLET_DID is always same as BLOCKLET_APP_PID in structV2 application
80
81
  headers['x-access-blocklet'] = process.env.BLOCKLET_DID;
81
82
  headers['x-access-component'] = process.env.BLOCKLET_COMPONENT_DID;
@@ -229,9 +230,11 @@ class BlockletService {
229
230
  const fn = client[api];
230
231
  this[api] = apiFnMap[api] ? apiFnMap[api](fn) : apiFallback(fn);
231
232
  });
232
- this.login = async (data) => {
233
+ this.login = async (data, options) => {
233
234
  try {
234
- const { data: resData } = await service_api_1.default.post('/api/user/login', data);
235
+ const { data: resData } = await service_api_1.default.post('/api/user/login', data, {
236
+ headers: options?.headers,
237
+ });
235
238
  if (resData?.user) {
236
239
  fixAvatar(resData.user);
237
240
  }
@@ -281,7 +284,7 @@ class BlockletService {
281
284
  return (0, util_2.findComponentByIdV2)(blocklet, did);
282
285
  };
283
286
  this.getVault = async () => {
284
- const wallet = wallet_1.default.getPermanentWallet();
287
+ const wallet = wallet_1.getWallet.getPermanentWallet();
285
288
  const { blocklet } = await this.getBlocklet();
286
289
  return (0, security_1.verifyVault)(blocklet.vaults, wallet.address);
287
290
  };
@@ -353,4 +356,4 @@ class BlockletService {
353
356
  });
354
357
  }
355
358
  }
356
- module.exports = BlockletService;
359
+ exports.BlockletService = BlockletService;
@@ -1,5 +1,5 @@
1
1
  import { TEvent } from '../types/event';
2
- export declare const subscribe: (cb: (event: TEvent) => any | Promise<any>) => void;
2
+ export declare const subscribe: (cb: (event: TEvent) => any | Promise<any>) => Promise<void>;
3
3
  export declare const unsubscribe: (cb: (event: TEvent) => any | Promise<any>) => void;
4
4
  export declare const publish: (name: string, event: {
5
5
  id?: string;
@@ -7,7 +7,7 @@ export declare const publish: (name: string, event: {
7
7
  data: any;
8
8
  }) => Promise<any>;
9
9
  declare const _default: {
10
- subscribe: (cb: (event: TEvent) => any | Promise<any>) => void;
10
+ subscribe: (cb: (event: TEvent) => any | Promise<any>) => Promise<void>;
11
11
  unsubscribe: (cb: (event: TEvent) => any | Promise<any>) => void;
12
12
  publish: (name: string, event: {
13
13
  id?: string;
@@ -1,16 +1,13 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.publish = exports.unsubscribe = exports.subscribe = void 0;
7
4
  const util_1 = require("@blocklet/meta/lib/util");
8
5
  const notification_1 = require("./notification");
9
- const check_blocklet_env_1 = __importDefault(require("../util/check-blocklet-env"));
6
+ const check_blocklet_env_1 = require("../util/check-blocklet-env");
10
7
  const send_notification_1 = require("../util/send-notification");
11
8
  const event_1 = require("../validators/event");
12
- const subscribe = (cb) => {
13
- (0, notification_1.ensureClient)();
9
+ const subscribe = async (cb) => {
10
+ await (0, notification_1.ensureClient)();
14
11
  notification_1._eventBus.on('event', cb);
15
12
  };
16
13
  exports.subscribe = subscribe;
@@ -19,8 +16,8 @@ const unsubscribe = (cb) => {
19
16
  };
20
17
  exports.unsubscribe = unsubscribe;
21
18
  const publish = async (name, event) => {
22
- (0, check_blocklet_env_1.default)();
23
- (0, notification_1.ensureClient)();
19
+ (0, check_blocklet_env_1.checkBlockletEnvironment)();
20
+ await (0, notification_1.ensureClient)();
24
21
  const payload = {
25
22
  id: event.id || (0, util_1.nanoid)(),
26
23
  time: event.time || new Date().toISOString(),
@@ -3,7 +3,7 @@ import { TNotification, TNotificationInput, TSendOptions } from '../types/notifi
3
3
  type $TSFixMe = any;
4
4
  export declare const getSender: () => {
5
5
  appDid: string;
6
- appSk: string;
6
+ wallet: import("@ocap/wallet").WalletObject<string>;
7
7
  };
8
8
  /**
9
9
  *
@@ -29,11 +29,12 @@ declare const doSendMail: (receiver: string | string[], notification: TNotificat
29
29
  */
30
30
  export declare const broadcast: (notification: TNotificationInput, options?: TSendOptions) => Promise<any>;
31
31
  export declare const _eventBus: EventEmitter<[never]>;
32
- export declare const ensureClient: () => void;
33
- export declare const on: (event: string, cb?: $TSFixMe) => EventEmitter<[never]>;
32
+ export declare const _emitter: EventEmitter<[never]>;
33
+ export declare const ensureClient: () => Promise<void>;
34
+ export declare const on: (event: string, cb?: $TSFixMe) => Promise<EventEmitter<[never]>>;
34
35
  export declare const off: any;
35
36
  export declare const _message: {
36
- on: (event: string, cb: $TSFixMe) => EventEmitter<[never]>;
37
+ on: (event: string, cb: $TSFixMe) => Promise<EventEmitter<[never]>>;
37
38
  off: any;
38
39
  };
39
40
  export { doSendToUser as sendToUser };
@@ -44,10 +45,10 @@ declare const _default: {
44
45
  sendToRelay: (topic: string, event: string, data: any) => Promise<any>;
45
46
  sendToMail: (receiver: string | string[], notification: TNotification, options?: TSendOptions) => Promise<any>;
46
47
  broadcast: (notification: TNotificationInput, options?: TSendOptions) => Promise<any>;
47
- on: (event: string, cb?: $TSFixMe) => EventEmitter<[never]>;
48
+ on: (event: string, cb?: $TSFixMe) => Promise<EventEmitter<[never]>>;
48
49
  off: any;
49
50
  _message: {
50
- on: (event: string, cb: $TSFixMe) => EventEmitter<[never]>;
51
+ on: (event: string, cb: $TSFixMe) => Promise<EventEmitter<[never]>>;
51
52
  off: any;
52
53
  };
53
54
  };
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.sendToRelay = exports.sendToMail = exports.sendToUser = exports._message = exports.off = exports.on = exports.ensureClient = exports._eventBus = exports.broadcast = exports.getSender = void 0;
39
+ exports.sendToRelay = exports.sendToMail = exports.sendToUser = exports._message = exports.off = exports.on = exports.ensureClient = exports._emitter = exports._eventBus = exports.broadcast = exports.getSender = void 0;
40
40
  /* eslint-disable @typescript-eslint/naming-convention */
41
41
  const Jwt = __importStar(require("@arcblock/jwt"));
42
42
  const debug_1 = __importDefault(require("debug"));
@@ -45,18 +45,21 @@ const ws_1 = require("@arcblock/ws");
45
45
  const util_1 = require("@blocklet/meta/lib/util");
46
46
  const channel_1 = require("@blocklet/meta/lib/channel");
47
47
  const constant_1 = require("@blocklet/constant");
48
- const check_blocklet_env_1 = __importDefault(require("../util/check-blocklet-env"));
48
+ const check_blocklet_env_1 = require("../util/check-blocklet-env");
49
49
  const send_notification_1 = require("../util/send-notification");
50
50
  const constants_1 = require("../util/constants");
51
- const wallet_1 = __importStar(require("../wallet"));
51
+ const wallet_1 = require("../wallet");
52
52
  const notification_1 = require("../validators/notification");
53
53
  const parse_docker_endpoint_1 = require("../util/parse-docker-endpoint");
54
54
  const debug = (0, debug_1.default)('@blocklet/sdk:notification');
55
55
  const getSender = () => {
56
- const wallet = (0, wallet_1.default)();
56
+ const wallet = (0, wallet_1.getWallet)();
57
+ const accessKeyWallet = (0, wallet_1.getAccessWallet)();
57
58
  return {
59
+ // appDid is used by the server to identify the blocklet
58
60
  appDid: wallet.address,
59
- appSk: wallet.secretKey,
61
+ // wallet is used for signing on the client side and verification on the server side
62
+ wallet: accessKeyWallet,
60
63
  };
61
64
  };
62
65
  exports.getSender = getSender;
@@ -70,19 +73,19 @@ exports.getSender = getSender;
70
73
  */
71
74
  // eslint-disable-next-line require-await
72
75
  const doSendToUser = async (receiver, notification, options) => {
73
- (0, check_blocklet_env_1.default)();
76
+ (0, check_blocklet_env_1.checkBlockletEnvironment)();
74
77
  return (0, send_notification_1.sendToUser)(receiver, notification, (0, exports.getSender)(), options, 'send-to-user');
75
78
  };
76
79
  exports.sendToUser = doSendToUser;
77
80
  // eslint-disable-next-line require-await
78
81
  const doSendToRelay = async (topic, event, data) => {
79
- (0, check_blocklet_env_1.default)();
82
+ (0, check_blocklet_env_1.checkBlockletEnvironment)();
80
83
  return (0, send_notification_1.sendToRelay)(topic, event, data, (0, exports.getSender)());
81
84
  };
82
85
  exports.sendToRelay = doSendToRelay;
83
86
  // eslint-disable-next-line require-await
84
87
  const doSendMail = async (receiver, notification, options) => {
85
- (0, check_blocklet_env_1.default)();
88
+ (0, check_blocklet_env_1.checkBlockletEnvironment)();
86
89
  return (0, send_notification_1.sendToUser)(receiver, notification, (0, exports.getSender)(), options, 'send-to-mail');
87
90
  };
88
91
  exports.sendToMail = doSendMail;
@@ -99,7 +102,7 @@ exports.sendToMail = doSendMail;
99
102
  */
100
103
  // eslint-disable-next-line require-await
101
104
  const broadcast = async (notification, options = {}) => {
102
- (0, check_blocklet_env_1.default)();
105
+ (0, check_blocklet_env_1.checkBlockletEnvironment)();
103
106
  const sender = (0, exports.getSender)();
104
107
  const { channel = (0, channel_1.getAppPublicChannel)(sender.appDid) } = options;
105
108
  const { event = 'message' } = options;
@@ -110,6 +113,7 @@ const noop = () => { };
110
113
  const emitter = new node_events_1.EventEmitter();
111
114
  const messageEmitter = new node_events_1.EventEmitter();
112
115
  exports._eventBus = new node_events_1.EventEmitter(); // for event bus
116
+ exports._emitter = emitter; // export internal emitter for testing
113
117
  const emitError = (error) => {
114
118
  messageEmitter.emit('error', error);
115
119
  emitter.emit('error', error);
@@ -125,30 +129,30 @@ const joinChannelErrorHandler = (name, type, emitters) => (err) => {
125
129
  (emitters || [emitter]).forEach((x) => x.emit('error', { message: msg }));
126
130
  };
127
131
  let client = null;
128
- const initClient = () => {
132
+ const initClient = async () => {
129
133
  if (!client) {
130
134
  ensureErrorListener();
131
- const wallet = (0, wallet_1.getPermanentWallet)();
135
+ const accessWallet = (0, wallet_1.getAccessWallet)();
132
136
  const componentDid = process.env.BLOCKLET_COMPONENT_DID;
133
- const { address: did, publicKey: pk, secretKey: sk } = wallet;
134
- const url = `ws://${(0, parse_docker_endpoint_1.getServerHost)()}:${process.env.ABT_NODE_SERVICE_PORT}${constants_1.SERVICE_PREFIX}`;
135
- const token = () => Jwt.sign(did, sk, {});
137
+ const appDid = process.env.BLOCKLET_APP_PID;
138
+ const { publicKey: pk } = accessWallet;
139
+ // Generate one token and reuse it for connection and all channels
140
+ const token = await accessWallet.signJWT({});
141
+ // Build URL with query parameters directly
142
+ const baseUrl = `ws://${(0, parse_docker_endpoint_1.getServerHost)()}:${process.env.ABT_NODE_SERVICE_PORT}${constants_1.SERVICE_PREFIX}/websocket`;
143
+ const url = `${baseUrl}?token=${encodeURIComponent(token)}&pk=${encodeURIComponent(pk)}`;
136
144
  client = new ws_1.WsClient(url, {
137
145
  heartbeatIntervalMs: 10 * 1000,
138
- params: () => ({
139
- token: token(),
140
- pk,
141
- }),
142
146
  });
143
147
  client.connect();
144
- const messageChannel = client.channel(did, () => ({ token: token(), pk }));
145
- const appPublicChannel = client.channel((0, channel_1.getAppPublicChannel)(did), () => ({ token: token(), pk }));
146
- const componentChannel = client.channel((0, channel_1.getComponentChannel)(did, componentDid), () => ({
147
- token: token(),
148
+ const messageChannel = client.channel(accessWallet.address, () => ({ token, pk }));
149
+ const appPublicChannel = client.channel((0, channel_1.getAppPublicChannel)(appDid), () => ({ token, pk }));
150
+ const componentChannel = client.channel((0, channel_1.getComponentChannel)(appDid, componentDid), () => ({
151
+ token,
148
152
  pk,
149
153
  apiKey: process.env.BLOCKLET_COMPONENT_API_KEY,
150
154
  }));
151
- const eventBusChannel = client.channel((0, channel_1.getEventBusChannel)(did), () => ({ token: token(), pk }));
155
+ const eventBusChannel = client.channel((0, channel_1.getEventBusChannel)(appDid), () => ({ token, pk }));
152
156
  messageChannel
153
157
  .join()
154
158
  .receive('error', joinChannelErrorHandler('message channel', 'error', [messageEmitter, emitter]))
@@ -237,24 +241,24 @@ const initClient = () => {
237
241
  });
238
242
  }
239
243
  };
240
- const ensureClient = () => {
244
+ const ensureClient = async () => {
241
245
  if (process.env.BLOCKLET_MODE === 'test') {
242
246
  return;
243
247
  }
244
248
  if (!client) {
245
- initClient();
249
+ await initClient();
246
250
  }
247
251
  };
248
252
  exports.ensureClient = ensureClient;
249
- const on = (event, cb) => {
250
- (0, exports.ensureClient)();
253
+ const on = async (event, cb) => {
254
+ await (0, exports.ensureClient)();
251
255
  return emitter.on(event, cb);
252
256
  };
253
257
  exports.on = on;
254
258
  exports.off = emitter.off.bind(emitter);
255
259
  exports._message = {
256
- on: (event, cb) => {
257
- (0, exports.ensureClient)();
260
+ on: async (event, cb) => {
261
+ await (0, exports.ensureClient)();
258
262
  return messageEmitter.on(event, cb);
259
263
  },
260
264
  off: messageEmitter.off.bind(messageEmitter),
@@ -0,0 +1,27 @@
1
+ import { SerializedWallet } from '@ocap/wallet';
2
+ import { DIDTypeArg } from '@arcblock/did';
3
+ import { EncodingType } from '@ocap/util';
4
+ export interface RemoteSignResponse {
5
+ signature: string;
6
+ publicKey?: string;
7
+ }
8
+ export interface RemoteSignJWTResponse {
9
+ token: string;
10
+ publicKey?: string;
11
+ }
12
+ export interface RemoteSignETHResponse {
13
+ signature: string;
14
+ publicKey?: string;
15
+ }
16
+ export interface RemoteSignOptions {
17
+ keyType?: 'sk' | 'psk';
18
+ type?: DIDTypeArg;
19
+ doSign?: boolean;
20
+ version?: string;
21
+ encoding?: EncodingType;
22
+ hashBeforeSign?: boolean;
23
+ }
24
+ export declare function remoteSign(payload: unknown, options?: RemoteSignOptions): Promise<RemoteSignResponse>;
25
+ export declare function remoteSignJWT(payload: unknown, options?: any): Promise<RemoteSignJWTResponse>;
26
+ export declare function remoteSignETH(data: string, options?: RemoteSignOptions): Promise<RemoteSignETHResponse>;
27
+ export declare function remoteDeriveWallet(sub: string, type?: any, index?: number, options?: RemoteSignOptions): Promise<SerializedWallet>;
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.remoteSign = remoteSign;
7
+ exports.remoteSignJWT = remoteSignJWT;
8
+ exports.remoteSignETH = remoteSignETH;
9
+ exports.remoteDeriveWallet = remoteDeriveWallet;
10
+ const axios_1 = __importDefault(require("axios"));
11
+ const env_1 = require("@blocklet/env");
12
+ const debug_1 = __importDefault(require("debug"));
13
+ const omit_1 = __importDefault(require("lodash/omit"));
14
+ const error_1 = require("@blocklet/error");
15
+ const constants_1 = require("../util/constants");
16
+ const parse_docker_endpoint_1 = require("../util/parse-docker-endpoint");
17
+ const debug = (0, debug_1.default)('@blocklet/sdk:remote-sign');
18
+ const { serverVersion } = env_1.blockletEnv;
19
+ const signClient = axios_1.default.create({
20
+ proxy: false,
21
+ baseURL: `http://${(0, parse_docker_endpoint_1.getServerHost)()}:${process.env.ABT_NODE_SERVICE_PORT}${constants_1.SERVICE_PREFIX}`,
22
+ timeout: 30 * 1000,
23
+ headers: {
24
+ 'User-Agent': `BlockletSDK/${serverVersion}`,
25
+ 'x-blocklet-server-version': serverVersion,
26
+ 'x-blocklet-did': process.env.BLOCKLET_DID,
27
+ 'x-component-did': process.env.BLOCKLET_COMPONENT_DID,
28
+ },
29
+ });
30
+ const ensureRemoteContext = () => {
31
+ const { BLOCKLET_DID, BLOCKLET_REAL_DID, BLOCKLET_COMPONENT_API_KEY } = process.env;
32
+ if (!BLOCKLET_DID || !BLOCKLET_REAL_DID) {
33
+ throw new Error('Missing blocklet runtime context for remote signing: require BLOCKLET_DID and BLOCKLET_REAL_DID');
34
+ }
35
+ if (!BLOCKLET_COMPONENT_API_KEY) {
36
+ throw new Error('Missing BLOCKLET_COMPONENT_API_KEY for remote signing');
37
+ }
38
+ return { apiKey: BLOCKLET_COMPONENT_API_KEY, did: BLOCKLET_DID, realDid: BLOCKLET_REAL_DID };
39
+ };
40
+ const normalizePayload = (payload) => {
41
+ if (Buffer.isBuffer(payload)) {
42
+ return {
43
+ __type: 'buffer',
44
+ data: payload.toString('hex'),
45
+ };
46
+ }
47
+ return payload;
48
+ };
49
+ const getPayloadInfo = (payload) => {
50
+ if (payload !== undefined) {
51
+ if (typeof payload === 'string') {
52
+ return { payloadPreview: payload.substring(0, 100), payloadType: 'string' };
53
+ }
54
+ if (Buffer.isBuffer(payload)) {
55
+ return { payloadPreview: `Buffer(${payload.length} bytes)`, payloadType: 'Buffer' };
56
+ }
57
+ if (typeof payload === 'object') {
58
+ const preview = JSON.stringify(payload).substring(0, 100);
59
+ return { payloadPreview: preview, payloadType: 'object' };
60
+ }
61
+ }
62
+ return {};
63
+ };
64
+ /**
65
+ * Generic remote signing API caller
66
+ * @param endpoint - API endpoint (e.g., '/api/sign', '/api/sign/jwt')
67
+ * @param requestBody - Request body to send
68
+ * @returns API response data
69
+ */
70
+ async function callRemoteSignAPI(endpoint, requestBody) {
71
+ const { apiKey } = ensureRemoteContext();
72
+ const startTime = Date.now();
73
+ // Prepare payload preview for logging (avoid logging sensitive data)
74
+ const payloadInfo = getPayloadInfo(requestBody.payload);
75
+ debug(`Remote Sign API call started: ${endpoint}`, {
76
+ ...payloadInfo,
77
+ body: (0, omit_1.default)(requestBody, 'payload'),
78
+ });
79
+ try {
80
+ const { data } = await signClient.post(endpoint, {
81
+ ...requestBody,
82
+ apiKey,
83
+ });
84
+ const duration = Date.now() - startTime;
85
+ debug(`Remote Sign API call succeeded: ${endpoint} in ${duration}`, {
86
+ responseKeys: Object.keys(data),
87
+ });
88
+ return data;
89
+ }
90
+ catch (error) {
91
+ const duration = Date.now() - startTime;
92
+ const message = (0, error_1.formatError)(error);
93
+ debug(`Remote Sign API call failed: ${endpoint} in ${duration}`, {
94
+ message,
95
+ });
96
+ throw new Error(`Remote signing API request failed: ${message}`);
97
+ }
98
+ }
99
+ function remoteSign(payload, options) {
100
+ const normalized = normalizePayload(payload);
101
+ return callRemoteSignAPI('/api/sign', { payload: normalized, options });
102
+ }
103
+ function remoteSignJWT(payload, options) {
104
+ return callRemoteSignAPI('/api/sign/jwt', { payload, options });
105
+ }
106
+ function remoteSignETH(data, options) {
107
+ const { hashBeforeSign, ...restOptions } = options || {};
108
+ return callRemoteSignAPI('/api/sign/eth', { data, hashBeforeSign, options: restOptions });
109
+ }
110
+ function remoteDeriveWallet(sub, type, index, options) {
111
+ return callRemoteSignAPI('/api/sign/derive', { sub, type, index, options });
112
+ }
@@ -17,9 +17,9 @@ export declare function getBlockletInfoSimple(getBlocklet?: () => Promise<ABTNod
17
17
  federated: import("@blocklet/server-js").FederatedConfig;
18
18
  appPid: string;
19
19
  blocklet: import("@blocklet/server-js").BlockletState;
20
+ version: string;
20
21
  description: string;
21
22
  name: string;
22
- version: string;
23
23
  } | {
24
24
  version: any;
25
25
  name: string;
@@ -9,7 +9,7 @@ exports.getAppInfo = getAppInfo;
9
9
  exports.getMemberAppInfo = getMemberAppInfo;
10
10
  const ufo_1 = require("ufo");
11
11
  const util_1 = require("@blocklet/meta/lib/util");
12
- const info_1 = __importDefault(require("@blocklet/meta/lib/info"));
12
+ const info_1 = require("@blocklet/meta/lib/info");
13
13
  const constant_1 = require("@abtnode/constant");
14
14
  const pick_1 = __importDefault(require("lodash/pick"));
15
15
  const login_1 = require("./login");
@@ -40,7 +40,7 @@ async function getBlockletInfoSimple(getBlocklet) {
40
40
  // 适用于 service 中获取 blocklet 信息
41
41
  if (getBlocklet && getBlocklet instanceof Function) {
42
42
  const blocklet = await getBlocklet();
43
- const blockletInfo = (0, info_1.default)(blocklet, undefined, {
43
+ const blockletInfo = (0, info_1.getBlockletInfo)(blocklet, undefined, {
44
44
  returnWallet: false,
45
45
  });
46
46
  return {
@@ -1,2 +1,2 @@
1
1
  declare const checkBlockletEnvironment: () => void;
2
- export = checkBlockletEnvironment;
2
+ export { checkBlockletEnvironment };
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkBlockletEnvironment = void 0;
2
4
  const checkBlockletEnvironment = () => {
3
5
  const envNames = [
4
6
  'BLOCKLET_APP_ID',
5
7
  'BLOCKLET_APP_NAME',
6
8
  'BLOCKLET_APP_DESCRIPTION',
7
- 'BLOCKLET_APP_SK',
8
9
  'BLOCKLET_DID',
10
+ 'BLOCKLET_APP_EK',
9
11
  'ABT_NODE_DID',
10
12
  'ABT_NODE_PK',
11
13
  'ABT_NODE_PORT',
@@ -17,4 +19,4 @@ const checkBlockletEnvironment = () => {
17
19
  }
18
20
  });
19
21
  };
20
- module.exports = checkBlockletEnvironment;
22
+ exports.checkBlockletEnvironment = checkBlockletEnvironment;
@@ -7,20 +7,24 @@ const axios_1 = __importDefault(require("axios"));
7
7
  const env_1 = require("@blocklet/env");
8
8
  const qs_1 = __importDefault(require("qs"));
9
9
  const verify_sign_1 = require("./verify-sign");
10
+ const { serverVersion } = env_1.blockletEnv;
10
11
  const componentApi = axios_1.default.create({
11
12
  timeout: 60 * 1000,
12
13
  headers: {
13
- 'User-Agent': `BlockletSDK/${env_1.serverVersion}`,
14
- 'x-blocklet-server-version': env_1.serverVersion,
14
+ 'User-Agent': `BlockletSDK/${serverVersion}`,
15
+ 'x-blocklet-server-version': serverVersion,
15
16
  },
16
17
  paramsSerializer: (params) => qs_1.default.stringify(params),
17
18
  });
18
- componentApi.interceptors.request.use((config) => {
19
- const { sig, exp, iat, version } = (0, verify_sign_1.getSignData)({
19
+ componentApi.interceptors.request.use(async (config) => {
20
+ const { sig, exp, iat, version } = await (0, verify_sign_1.getSignData)({
20
21
  data: config.data,
21
22
  method: config.method,
22
23
  params: config.params,
23
24
  url: config.url,
25
+ }, {
26
+ // Compatible with previous version where APP_ASK does not exist
27
+ appSk: process.env.BLOCKLET_APP_ASK || process.env.BLOCKLET_APP_SK,
24
28
  });
25
29
  config.headers['x-component-did'] = process.env.BLOCKLET_COMPONENT_DID;
26
30
  config.headers['x-component-sig'] = sig;
@@ -1,5 +1,10 @@
1
1
  import type { LiteralUnion } from 'type-fest';
2
2
  export declare function hmac(secretKey: string, message: string, algorithm?: LiteralUnion<'md5' | 'sha256', string>): string;
3
+ /**
4
+ * Get CSRF secret key with smart fallback strategy
5
+ * @returns CSRF secret key
6
+ */
7
+ export declare function getCsrfSecret(): string;
3
8
  /**
4
9
  * 生成 CSRF Token
5
10
  * @param secretKey 服务器密钥(必填,需保密)
package/lib/util/csrf.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hmac = hmac;
4
+ exports.getCsrfSecret = getCsrfSecret;
4
5
  exports.sign = sign;
5
6
  exports.verify = verify;
6
7
  const crypto_1 = require("crypto");
@@ -8,6 +9,14 @@ function hmac(secretKey, message, algorithm = 'md5') {
8
9
  const hmacFunc = (0, crypto_1.createHmac)(algorithm, secretKey);
9
10
  return hmacFunc.update(message).digest('base64url');
10
11
  }
12
+ /**
13
+ * Get CSRF secret key with smart fallback strategy
14
+ * @returns CSRF secret key
15
+ */
16
+ function getCsrfSecret() {
17
+ // Compatible with previous version where APP_ASK does not exist
18
+ return process.env.BLOCKLET_APP_ASK || process.env.BLOCKLET_APP_SK;
19
+ }
11
20
  /**
12
21
  * 生成 CSRF Token
13
22
  * @param secretKey 服务器密钥(必填,需保密)
@@ -8,14 +8,15 @@ exports.default = setupJest;
8
8
  const os_1 = __importDefault(require("os"));
9
9
  const fs_1 = __importDefault(require("fs"));
10
10
  const path_1 = __importDefault(require("path"));
11
- const parse_1 = __importDefault(require("@blocklet/meta/lib/parse"));
11
+ const parse_1 = require("@blocklet/meta/lib/parse");
12
12
  const mcrypto_1 = require("@ocap/mcrypto");
13
13
  const wallet_1 = require("@ocap/wallet");
14
+ const did_ext_1 = require("@arcblock/did-ext");
14
15
  function setupJest() {
15
16
  try {
16
17
  const dir = process.cwd();
17
18
  const wallet = (0, wallet_1.fromRandom)({ role: mcrypto_1.types.RoleType.ROLE_APPLICATION });
18
- const meta = (0, parse_1.default)(dir, { ensureComponentStore: false });
19
+ const meta = (0, parse_1.parse)(dir, { ensureComponentStore: false });
19
20
  const tmpDir = path_1.default.join(os_1.default.tmpdir(), meta.did);
20
21
  if (fs_1.default.existsSync(tmpDir) === false) {
21
22
  fs_1.default.mkdirSync(tmpDir, { recursive: true });
@@ -29,13 +30,17 @@ function setupJest() {
29
30
  process.env.BLOCKLET_COMPONENT_DID = meta.did;
30
31
  process.env.BLOCKLET_DATA_DIR = path_1.default.join(tmpDir, wallet.address);
31
32
  process.env.BLOCKLET_LOG_DIR = path_1.default.join(tmpDir, wallet.address);
32
- process.env.BLOCKLET_APP_SK = wallet.secretKey;
33
- process.env.BLOCKLET_APP_PSK = wallet.secretKey;
33
+ // process.env.BLOCKLET_APP_SK = wallet.secretKey;
34
+ // process.env.BLOCKLET_APP_PSK = wallet.secretKey;
35
+ process.env.BLOCKLET_APP_PK = wallet.publicKey;
36
+ process.env.BLOCKLET_APP_PPK = wallet.publicKey;
34
37
  process.env.BLOCKLET_APP_ID = wallet.address;
35
38
  process.env.BLOCKLET_APP_PID = wallet.address;
36
39
  process.env.BLOCKLET_APP_IDS = wallet.address;
37
40
  process.env.BLOCKLET_APP_NAME = meta.title;
38
41
  process.env.BLOCKLET_APP_DESCRIPTION = meta.description;
42
+ process.env.BLOCKLET_APP_EK = (0, did_ext_1.fromAppDid)(meta.did, process.env.ABT_NODE_PK, undefined, 1).secretKey;
43
+ process.env.BLOCKLET_APP_ASK = (0, did_ext_1.fromAppDid)(meta.did, process.env.ABT_NODE_PK, undefined, 1).secretKey;
39
44
  process.env.BLOCKLET_APP_URL = 'http://192.168.0.10:3030';
40
45
  process.env.BLOCKLET_MOUNT_POINTS = JSON.stringify([
41
46
  {