@1shotapi/ows-signer 0.3.0 → 0.3.1

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 CHANGED
@@ -40,7 +40,7 @@ Only accepts messages when `event.source === window.parent`. Replies use the par
40
40
  | `createCredential` | `name`, `options?` (incl. ceremony UI) | `KeyDerived`, `CredentialCreated` |
41
41
  | `signDigest` | `digests[]`, `credentialId?`, ceremony UI? | `KeyDerived` (PRF path), `DigestSigned` (`results[]`) |
42
42
  | `executeBatch` | batch fields + ceremony UI? | `KeyDerived` (when keys derived), `BatchExecuted` |
43
- | `revealPrivateKey` | `credentialId?`, ceremony UI? | `KeyDerived` (+ DOM display) |
43
+ | `revealPrivateKey` | `credentialId?`, ceremony UI? | `KeyDerived`, then `PrivateKeyRevealed` (after user dismisses DOM key UI) |
44
44
  | `createRecoveryData` | passphrase fields + ceremony UI? | `KeyDerived`, `RecoveryDataCreated` |
45
45
  | `recoverKey` | envelope + passphrase fields + ceremony UI? | DOM display; `RecoverySessionStarted` or re-bind → `RecoverySessionCleared` |
46
46
  | `getPublicKey` | `credentialId?`, `challenge?`, ceremony UI? | `KeyDerived`, `PublicKey`, `ChallengeSigned?` |
package/html/index.html CHANGED
@@ -77,6 +77,12 @@
77
77
  flex-wrap: wrap;
78
78
  gap: 8px;
79
79
  }
80
+ .ows-actions {
81
+ flex: 0 0 auto;
82
+ display: flex;
83
+ flex-wrap: wrap;
84
+ gap: 8px;
85
+ }
80
86
  .ows-copy,
81
87
  .ows-confirm,
82
88
  .ows-deny {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1shotapi/ows-signer",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "OWS Signing Layer — plain JavaScript WebAuthn PRF key custody with curve-based signing (on-chain via EIP-8244)",
5
5
  "type": "module",
6
6
  "files": [
package/src/handlers.js CHANGED
@@ -445,9 +445,21 @@ async function handleRevealPrivateKey(params, correlationId, targetOrigin) {
445
445
  keys.secp256k1PublicKey,
446
446
  keys.ed25519PublicKey,
447
447
  );
448
- showPrivateKey(keys.secp256k1PrivateKey);
449
- zeroize(keys.secp256k1PrivateKey);
448
+ try {
449
+ const dismiss = showPrivateKey(keys.secp256k1PrivateKey);
450
+ zeroize(keys.secp256k1PrivateKey);
451
+ await dismiss;
452
+ } finally {
453
+ zeroize(keys.secp256k1PrivateKey);
454
+ }
450
455
  });
456
+ emitEvent(
457
+ window.parent,
458
+ targetOrigin,
459
+ "PrivateKeyRevealed",
460
+ correlationId,
461
+ {},
462
+ );
451
463
  }
452
464
 
453
465
  /**
package/src/ui.js CHANGED
@@ -225,23 +225,43 @@ export function promptCeremonyConfirm(fields, runOnConfirm) {
225
225
  }
226
226
 
227
227
  /**
228
+ * Show the private key hex with Copy + Done. Resolves when the user clicks Done
229
+ * (or the UI is cleared), so Branding can keep the ceremony panel open.
230
+ *
228
231
  * @param {Uint8Array} privateKey
232
+ * @returns {Promise<void>}
229
233
  */
230
234
  export function showPrivateKey(privateKey) {
231
- if (!root) return;
235
+ if (!root) {
236
+ return Promise.reject(new Error("uiNotInitialized"));
237
+ }
232
238
  cancelPendingCeremonyConfirm();
233
239
  clearUi();
234
- const pre = document.createElement("pre");
235
- pre.className = "ows-key";
236
- pre.textContent = to0xHex(privateKey);
237
- const copyBtn = document.createElement("button");
238
- copyBtn.type = "button";
239
- copyBtn.className = "ows-copy";
240
- copyBtn.textContent = "Copy";
241
- copyBtn.addEventListener("click", async () => {
242
- await navigator.clipboard.writeText(pre.textContent ?? "");
240
+ const hex = to0xHex(privateKey);
241
+ return new Promise((resolve) => {
242
+ const pre = document.createElement("pre");
243
+ pre.className = "ows-key";
244
+ pre.textContent = hex;
245
+ const copyBtn = document.createElement("button");
246
+ copyBtn.type = "button";
247
+ copyBtn.className = "ows-copy";
248
+ copyBtn.textContent = "Copy";
249
+ copyBtn.addEventListener("click", async () => {
250
+ await navigator.clipboard.writeText(pre.textContent ?? "");
251
+ });
252
+ const doneBtn = document.createElement("button");
253
+ doneBtn.type = "button";
254
+ doneBtn.className = "ows-confirm";
255
+ doneBtn.textContent = "Done";
256
+ doneBtn.addEventListener("click", () => {
257
+ clearUi();
258
+ resolve();
259
+ });
260
+ const actions = document.createElement("div");
261
+ actions.className = "ows-actions";
262
+ actions.append(copyBtn, doneBtn);
263
+ root.append(pre, actions);
243
264
  });
244
- root.append(pre, copyBtn);
245
265
  }
246
266
 
247
267
  /**