@parity/product-sdk-terminal 0.9.1 → 0.10.0

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/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- export { requestResourceAllocation, sendResourceAllocation } from './chunk-OKJQEB6P.js';
1
+ import { cacheFilePath, withFileLock, loadJsonCache, saveJsonCache } from './chunk-EORPX5XL.js';
2
+ export { requestResourceAllocation, sendResourceAllocation } from './chunk-EORPX5XL.js';
2
3
  import { createNodeStorageAdapter, sanitizeKey } from './chunk-GHOFKVUG.js';
3
4
  export { createNodeStorageAdapter } from './chunk-GHOFKVUG.js';
4
5
  import { SS_PREVIEW_STAGE_ENDPOINTS, createPappAdapter, AllowanceError } from '@novasamatech/host-papp';
@@ -10,7 +11,7 @@ import { unifyMetadata, decAnyMetadata } from '@polkadot-api/substrate-bindings'
10
11
  import { deriveProductAccountPublicKey } from '@parity/product-sdk-keys';
11
12
  import { AllowanceExpiredError } from '@parity/product-sdk-signer/errors';
12
13
  export { AllowanceExpiredError, SignerError } from '@parity/product-sdk-signer/errors';
13
- import { fromHex, toHex } from '@polkadot-api/utils';
14
+ import { toHex, fromHex } from '@polkadot-api/utils';
14
15
  import { gcm } from '@noble/ciphers/aes.js';
15
16
  import { blake2b } from '@noble/hashes/blake2.js';
16
17
  import { readFile } from 'fs/promises';
@@ -112,6 +113,70 @@ async function teardown(sessions, lazyClient) {
112
113
  restore();
113
114
  }
114
115
  }
116
+ var log2 = createLogger("terminal");
117
+ var CACHE_KIND = "ProductSubtrees";
118
+ var CACHE_VERSION = 1;
119
+ var SUBTREE_KEY_BYTES = 32;
120
+ var memo = /* @__PURE__ */ new Map();
121
+ function entryKey(session, productId) {
122
+ return `${session.id}::${productId}`;
123
+ }
124
+ async function requestSubtree(session, productId) {
125
+ const result = await session.getProductSubtree(productId);
126
+ if (result.isErr()) {
127
+ throw new Error(`Could not fetch the product subtree key: ${result.error.message}`);
128
+ }
129
+ const key = new Uint8Array(result.value);
130
+ if (key.length !== SUBTREE_KEY_BYTES) {
131
+ throw new Error(
132
+ `Product subtree key must be ${SUBTREE_KEY_BYTES} bytes, got ${key.length}`
133
+ );
134
+ }
135
+ return key;
136
+ }
137
+ function getProductSubtreePublicKey(session, productId, options = {}) {
138
+ const path = cacheFilePath(options.appId ?? productId, CACHE_KIND, options.storageDir);
139
+ const key = `${path}::${entryKey(session, productId)}`;
140
+ const inFlight = memo.get(key);
141
+ if (inFlight) return inFlight;
142
+ const pending = resolveSubtree(session, productId, path, entryKey(session, productId));
143
+ memo.set(key, pending);
144
+ pending.catch(() => memo.delete(key));
145
+ return pending;
146
+ }
147
+ async function resolveSubtree(session, productId, path, entry) {
148
+ return withFileLock(path, async () => {
149
+ const cache = await loadJsonCache(
150
+ path,
151
+ CACHE_VERSION,
152
+ "product-subtree cache"
153
+ );
154
+ const stored = readEntry(cache, entry, path);
155
+ if (stored) return stored;
156
+ const fetched = await requestSubtree(session, productId);
157
+ const entries = typeof cache?.entries === "object" && cache.entries !== null ? cache.entries : {};
158
+ await saveJsonCache(path, {
159
+ version: CACHE_VERSION,
160
+ entries: { ...entries, [entry]: toHex(fetched) }
161
+ });
162
+ return fetched;
163
+ });
164
+ }
165
+ function readEntry(cache, entry, path) {
166
+ const stored = cache?.entries?.[entry];
167
+ if (typeof stored !== "string") return null;
168
+ let bytes;
169
+ try {
170
+ bytes = fromHex(stored);
171
+ } catch {
172
+ bytes = new Uint8Array();
173
+ }
174
+ if (bytes.length === SUBTREE_KEY_BYTES) return bytes;
175
+ log2.warn("product-subtree cache entry is malformed; refetching", { path });
176
+ return null;
177
+ }
178
+
179
+ // src/signer.ts
115
180
  function isNoAllowanceError(error) {
116
181
  for (let current = error, depth = 0; current != null && depth < 8; depth++) {
117
182
  if (current instanceof NoAllowanceError) return true;
@@ -221,16 +286,13 @@ function sessionRootPublicKey(session) {
221
286
  }
222
287
  return publicKey;
223
288
  }
224
- function deriveProductPublicKey(session, ref) {
225
- return deriveProductAccountPublicKey(
226
- sessionRootPublicKey(session),
227
- ref.productId,
228
- ref.derivationIndex
229
- );
289
+ async function deriveProductPublicKey(session, ref, options) {
290
+ const subtree = await getProductSubtreePublicKey(session, ref.productId, options);
291
+ return deriveProductAccountPublicKey(subtree, { tag: "Index", value: ref.derivationIndex });
230
292
  }
231
- function buildSessionSigner(session, ref) {
293
+ async function buildSessionSigner(session, ref, options) {
232
294
  const productAccountId = toProductAccountId(ref);
233
- const publicKey = ref.publicKey ?? deriveProductPublicKey(session, ref);
295
+ const publicKey = ref.publicKey ?? await deriveProductPublicKey(session, ref, options);
234
296
  return {
235
297
  publicKey,
236
298
  // Transaction signing → host-papp `createTransaction`: the wallet builds
@@ -243,11 +305,15 @@ function buildSessionSigner(session, ref) {
243
305
  signBytes: makeRawBytesSignCallback(session, productAccountId)
244
306
  };
245
307
  }
246
- function createSessionSigner(session, adapter, publicKey) {
247
- return buildSessionSigner(session, { productId: adapter.appId, derivationIndex: 0, publicKey });
308
+ function createSessionSigner(session, adapter, publicKey, options) {
309
+ return buildSessionSigner(
310
+ session,
311
+ { productId: adapter.appId, derivationIndex: 0, publicKey },
312
+ { appId: adapter.appId, ...options }
313
+ );
248
314
  }
249
- function createSessionSignerForAccount(session, ref) {
250
- return buildSessionSigner(session, ref);
315
+ function createSessionSignerForAccount(session, ref, options) {
316
+ return buildSessionSigner(session, ref, options);
251
317
  }
252
318
  var AllowanceResourceKindCodec = Enum({
253
319
  bulletin: _void,
@@ -367,6 +433,6 @@ async function renderQrCode(data, options) {
367
433
  return result;
368
434
  }
369
435
 
370
- export { INCOMPLETE_SESSION_MESSAGE, StatementStoreNetworks, createSessionSigner, createSessionSignerForAccount, createTerminalAdapter, deriveProductPublicKey, getBulletinSigner, getStatementStoreProver, hasBulletinAllowance, hasStatementStoreAllowance, isBenignTeardownError, renderQrCode, sessionRootPublicKey, waitForSessions };
436
+ export { INCOMPLETE_SESSION_MESSAGE, StatementStoreNetworks, createSessionSigner, createSessionSignerForAccount, createTerminalAdapter, deriveProductPublicKey, getBulletinSigner, getProductSubtreePublicKey, getStatementStoreProver, hasBulletinAllowance, hasStatementStoreAllowance, isBenignTeardownError, renderQrCode, sessionRootPublicKey, waitForSessions };
371
437
  //# sourceMappingURL=index.js.map
372
438
  //# sourceMappingURL=index.js.map