@asseteragmbh/wallet-connector 0.2.3 → 0.2.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 +69 -1
- package/dist/index.cjs +77 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -4
- package/dist/index.d.ts +62 -4
- package/dist/index.js +77 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -211,12 +211,80 @@ While the pop-up is open the partner page shows a dimming overlay (`overlay: tru
|
|
|
211
211
|
`overlay: { title, body, focus, cancel, blocked }` to translate the built-in text; `partnerName` only shows up
|
|
212
212
|
in that text.
|
|
213
213
|
|
|
214
|
+
The overlay is plain DOM with inline styles, so it needs no React and no stylesheet, and it never reads your
|
|
215
|
+
page CSS. Give it your colours and radii with `overlay.theme`. A dark host takes the `"dark"` base palette and
|
|
216
|
+
overrides what it needs:
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
await openAsseteraOnboarding({
|
|
220
|
+
walletUrl: "https://wallet.wallet-staging.assetera.com",
|
|
221
|
+
chain: "eip155:80002",
|
|
222
|
+
overlay: {
|
|
223
|
+
title: "Continue in the Assetera Wallet",
|
|
224
|
+
body: "Finish the wallet setup in the Assetera window, then come back here.",
|
|
225
|
+
focus: "Open the wallet window",
|
|
226
|
+
cancel: "Not now",
|
|
227
|
+
theme: { scheme: "dark", surface: "#1d1f27", primary: "#7b61ff", radius: "36px" },
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Every `theme` key is optional. `scheme` picks the base palette, `"light"` (today's look, unchanged) or
|
|
233
|
+
`"dark"`; any other key the host passes wins over that palette. So the example above only changes the card
|
|
234
|
+
colour, the focus button colour and the card radius.
|
|
235
|
+
|
|
236
|
+
| Key | Default (light) | Contract |
|
|
237
|
+
| -------------- | -------------------- | -------------------------------------------------- |
|
|
238
|
+
| `scheme` | `"light"` | Base palette, `"light"` or `"dark"`. |
|
|
239
|
+
| `backdrop` | `rgba(15,20,30,0.6)` | The dimming layer, a CSS colour. |
|
|
240
|
+
| `surface` | `#ffffff` | The card background, a CSS colour. |
|
|
241
|
+
| `text` | `#101828` | The title colour, a CSS colour. |
|
|
242
|
+
| `mutedText` | `#475467` | The body text and the Cancel button, a CSS colour. |
|
|
243
|
+
| `primary` | `#101828` | The focus button background, a CSS colour. |
|
|
244
|
+
| `primaryText` | `#ffffff` | The focus button text, a CSS colour. |
|
|
245
|
+
| `border` | `"none"` | The card border, CSS `border` shorthand. |
|
|
246
|
+
| `radius` | `"16px"` | The card corner radius, for example `"36px"`. |
|
|
247
|
+
| `buttonRadius` | `"10px"` | The button corner radius, for example `"9999px"`. |
|
|
248
|
+
| `fontFamily` | `system-ui` stack | The overlay font, CSS `font-family`. |
|
|
249
|
+
|
|
250
|
+
The `"dark"` preset is a neutral card: `surface` `#1b1d24`, white title, `#9aa2b1` body text and a white focus
|
|
251
|
+
button with dark text. Its text keeps WCAG AA contrast on that surface.
|
|
252
|
+
|
|
253
|
+
Each host value is applied to its own CSS property with `style.setProperty`, never concatenated into the style
|
|
254
|
+
text. A value the browser cannot parse is dropped and the rest of the overlay stays as it is. All overlay text
|
|
255
|
+
still goes through `textContent`.
|
|
256
|
+
|
|
257
|
+
### Rendering your own dialog (`overlay: false` with `onControls`)
|
|
258
|
+
|
|
259
|
+
Set `overlay: false` and pass `onControls` to drive the run from your own dialog. The callback runs once,
|
|
260
|
+
synchronously, right after the pop-up opened, whether or not an overlay is shown:
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
import type { OnboardingControls } from "@asseteragmbh/wallet-connector";
|
|
264
|
+
|
|
265
|
+
let controls: OnboardingControls | undefined;
|
|
266
|
+
const wallet = await openAsseteraOnboarding({
|
|
267
|
+
walletUrl: "https://wallet.wallet-staging.assetera.com",
|
|
268
|
+
chain: "eip155:80002",
|
|
269
|
+
overlay: false,
|
|
270
|
+
onControls: (handles) => {
|
|
271
|
+
controls = handles;
|
|
272
|
+
showMyOwnDialog();
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
`controls.focus()` brings the pop-up to the front. `controls.cancel()` behaves like the overlay's Cancel
|
|
278
|
+
button: it rejects with `OnboardingError` code `"cancelled"` before the address arrived, and calls `close()`
|
|
279
|
+
after it. Both are safe to call once the run finished.
|
|
280
|
+
|
|
214
281
|
The promise rejects with an `OnboardingError`; branch on `code`:
|
|
215
282
|
|
|
216
283
|
- `invalid_options`: the chain is not a CAIP-2 EVM id (for example `eip155:80002`) or the wallet URL is invalid.
|
|
217
284
|
- `popup_blocked`: the browser blocked the pop-up. No overlay is shown; ask the user to allow pop-ups.
|
|
218
285
|
- `closed`: the pop-up was closed before the wizard finished (or, from `signMessage`, before the signature).
|
|
219
|
-
- `cancelled`: the user cancelled in the wizard
|
|
286
|
+
- `cancelled`: the user cancelled in the wizard, in the overlay or through `controls.cancel()`, or declined the
|
|
287
|
+
signature.
|
|
220
288
|
- `refused`: the wallet refused the onboarding.
|
|
221
289
|
- `failed`: something else went wrong in the wallet (the optional `message` carries the detail).
|
|
222
290
|
|
package/dist/index.cjs
CHANGED
|
@@ -479,6 +479,48 @@ var DEFAULT_LABELS = {
|
|
|
479
479
|
cancel: "Cancel",
|
|
480
480
|
blocked: "Your browser blocked the Assetera Wallet window. Allow pop-ups for this site and try again."
|
|
481
481
|
};
|
|
482
|
+
var LIGHT_THEME = {
|
|
483
|
+
scheme: "light",
|
|
484
|
+
backdrop: "rgba(15,20,30,0.6)",
|
|
485
|
+
surface: "#ffffff",
|
|
486
|
+
text: "#101828",
|
|
487
|
+
mutedText: "#475467",
|
|
488
|
+
primary: "#101828",
|
|
489
|
+
primaryText: "#ffffff",
|
|
490
|
+
border: "none",
|
|
491
|
+
radius: "16px",
|
|
492
|
+
buttonRadius: "10px",
|
|
493
|
+
fontFamily: "system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif"
|
|
494
|
+
};
|
|
495
|
+
var DARK_THEME = {
|
|
496
|
+
scheme: "dark",
|
|
497
|
+
backdrop: "rgba(8,10,14,0.72)",
|
|
498
|
+
surface: "#1b1d24",
|
|
499
|
+
text: "#f7f8fa",
|
|
500
|
+
mutedText: "#9aa2b1",
|
|
501
|
+
primary: "#ffffff",
|
|
502
|
+
primaryText: "#101828",
|
|
503
|
+
border: "1px solid rgba(255,255,255,0.14)",
|
|
504
|
+
radius: "16px",
|
|
505
|
+
buttonRadius: "10px",
|
|
506
|
+
fontFamily: "system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif"
|
|
507
|
+
};
|
|
508
|
+
function resolveTheme(theme) {
|
|
509
|
+
const base = theme?.scheme === "dark" ? DARK_THEME : LIGHT_THEME;
|
|
510
|
+
return {
|
|
511
|
+
scheme: base.scheme,
|
|
512
|
+
backdrop: theme?.backdrop ?? base.backdrop,
|
|
513
|
+
surface: theme?.surface ?? base.surface,
|
|
514
|
+
text: theme?.text ?? base.text,
|
|
515
|
+
mutedText: theme?.mutedText ?? base.mutedText,
|
|
516
|
+
primary: theme?.primary ?? base.primary,
|
|
517
|
+
primaryText: theme?.primaryText ?? base.primaryText,
|
|
518
|
+
border: theme?.border ?? base.border,
|
|
519
|
+
radius: theme?.radius ?? base.radius,
|
|
520
|
+
buttonRadius: theme?.buttonRadius ?? base.buttonRadius,
|
|
521
|
+
fontFamily: theme?.fontFamily ?? base.fontFamily
|
|
522
|
+
};
|
|
523
|
+
}
|
|
482
524
|
function resolveLabels(options) {
|
|
483
525
|
const overrides = typeof options.overlay === "object" && options.overlay !== null ? options.overlay : {};
|
|
484
526
|
const partnerName = options.partnerName;
|
|
@@ -491,6 +533,10 @@ function resolveLabels(options) {
|
|
|
491
533
|
blocked: overrides.blocked ?? DEFAULT_LABELS.blocked
|
|
492
534
|
};
|
|
493
535
|
}
|
|
536
|
+
function resolveThemeOption(options) {
|
|
537
|
+
const overlay = typeof options.overlay === "object" && options.overlay !== null ? options.overlay : {};
|
|
538
|
+
return resolveTheme(overlay.theme);
|
|
539
|
+
}
|
|
494
540
|
function cancelCode(reason) {
|
|
495
541
|
if (reason === "user") return "cancelled";
|
|
496
542
|
if (reason === "refused") return "refused";
|
|
@@ -504,7 +550,7 @@ function cancelMessage(reason) {
|
|
|
504
550
|
function copyAccountNames(accounts) {
|
|
505
551
|
return accounts.map((account) => ({ address: account.address, name: account.name }));
|
|
506
552
|
}
|
|
507
|
-
function showOverlay(win, labels, handlers) {
|
|
553
|
+
function showOverlay(win, labels, theme, handlers) {
|
|
508
554
|
const doc = win.document;
|
|
509
555
|
const root = doc.createElement("div");
|
|
510
556
|
root.setAttribute("role", "dialog");
|
|
@@ -518,40 +564,43 @@ function showOverlay(win, labels, handlers) {
|
|
|
518
564
|
"justify-content: center",
|
|
519
565
|
"padding: 24px",
|
|
520
566
|
"box-sizing: border-box",
|
|
521
|
-
|
|
522
|
-
`z-index: ${OVERLAY_Z_INDEX}`,
|
|
523
|
-
"font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif"
|
|
567
|
+
`z-index: ${OVERLAY_Z_INDEX}`
|
|
524
568
|
].join("; ");
|
|
569
|
+
root.style.setProperty("background-color", theme.backdrop);
|
|
570
|
+
root.style.setProperty("font-family", theme.fontFamily);
|
|
525
571
|
const card = doc.createElement("div");
|
|
526
572
|
card.style.cssText = [
|
|
527
573
|
"box-sizing: border-box",
|
|
528
574
|
"width: 100%",
|
|
529
575
|
"max-width: 420px",
|
|
530
|
-
"border-radius: 16px",
|
|
531
576
|
"padding: 24px",
|
|
532
|
-
"background: #ffffff",
|
|
533
|
-
"color: #101828",
|
|
534
577
|
"box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35)"
|
|
535
578
|
].join("; ");
|
|
579
|
+
card.style.setProperty("background-color", theme.surface);
|
|
580
|
+
card.style.setProperty("color", theme.text);
|
|
581
|
+
card.style.setProperty("border", theme.border);
|
|
582
|
+
card.style.setProperty("border-radius", theme.radius);
|
|
536
583
|
const title = doc.createElement("h2");
|
|
537
584
|
title.textContent = labels.title;
|
|
538
585
|
title.style.cssText = "margin: 0 0 10px; font-size: 18px; line-height: 1.3; font-weight: 600;";
|
|
586
|
+
title.style.setProperty("color", theme.text);
|
|
539
587
|
const body = doc.createElement("p");
|
|
540
588
|
body.textContent = labels.body;
|
|
541
|
-
body.style.cssText = "margin: 0 0 20px; font-size: 14px; line-height: 1.5;
|
|
589
|
+
body.style.cssText = "margin: 0 0 20px; font-size: 14px; line-height: 1.5;";
|
|
590
|
+
body.style.setProperty("color", theme.mutedText);
|
|
542
591
|
const focus = doc.createElement("button");
|
|
543
592
|
focus.type = "button";
|
|
544
593
|
focus.textContent = labels.focus;
|
|
545
594
|
focus.style.cssText = [
|
|
546
595
|
"padding: 10px 16px",
|
|
547
596
|
"border: 0",
|
|
548
|
-
"border-radius: 10px",
|
|
549
|
-
"background: #101828",
|
|
550
|
-
"color: #ffffff",
|
|
551
597
|
"font: inherit",
|
|
552
598
|
"font-weight: 600",
|
|
553
599
|
"cursor: pointer"
|
|
554
600
|
].join("; ");
|
|
601
|
+
focus.style.setProperty("background-color", theme.primary);
|
|
602
|
+
focus.style.setProperty("color", theme.primaryText);
|
|
603
|
+
focus.style.setProperty("border-radius", theme.buttonRadius);
|
|
555
604
|
focus.addEventListener("click", handlers.onFocus);
|
|
556
605
|
const cancel = doc.createElement("button");
|
|
557
606
|
cancel.type = "button";
|
|
@@ -561,10 +610,11 @@ function showOverlay(win, labels, handlers) {
|
|
|
561
610
|
"border: 0",
|
|
562
611
|
"border-radius: 10px",
|
|
563
612
|
"background: transparent",
|
|
564
|
-
"color: #475467",
|
|
565
613
|
"font: inherit",
|
|
566
614
|
"cursor: pointer"
|
|
567
615
|
].join("; ");
|
|
616
|
+
cancel.style.setProperty("color", theme.mutedText);
|
|
617
|
+
cancel.style.setProperty("border-radius", theme.buttonRadius);
|
|
568
618
|
cancel.addEventListener("click", handlers.onCancel);
|
|
569
619
|
const actions = doc.createElement("div");
|
|
570
620
|
actions.style.cssText = "display: flex; gap: 8px; align-items: center;";
|
|
@@ -599,6 +649,7 @@ function openAsseteraOnboarding(options) {
|
|
|
599
649
|
);
|
|
600
650
|
}
|
|
601
651
|
const labels = resolveLabels(options);
|
|
652
|
+
const theme = resolveThemeOption(options);
|
|
602
653
|
const overlayEnabled = options.overlay !== false;
|
|
603
654
|
const popup = targetWindow.open(
|
|
604
655
|
onboardUrl(options.walletUrl, targetWindow.location.origin, {
|
|
@@ -653,6 +704,16 @@ function openAsseteraOnboarding(options) {
|
|
|
653
704
|
activePopup.close();
|
|
654
705
|
fail(new OnboardingError("cancelled", "The user cancelled the Assetera Wallet onboarding."));
|
|
655
706
|
}
|
|
707
|
+
const controls = {
|
|
708
|
+
focus() {
|
|
709
|
+
if (finished) return;
|
|
710
|
+
activePopup.focus();
|
|
711
|
+
},
|
|
712
|
+
cancel() {
|
|
713
|
+
if (finished) return;
|
|
714
|
+
cancel();
|
|
715
|
+
}
|
|
716
|
+
};
|
|
656
717
|
function signMessage(message) {
|
|
657
718
|
if (finished || activePopup.closed) {
|
|
658
719
|
return Promise.reject(new OnboardingError("closed", "The Assetera Wallet window was closed."));
|
|
@@ -731,11 +792,12 @@ function openAsseteraOnboarding(options) {
|
|
|
731
792
|
);
|
|
732
793
|
}, CLOSE_POLL_MS2);
|
|
733
794
|
if (overlayEnabled) {
|
|
734
|
-
overlay = showOverlay(targetWindow, labels, {
|
|
735
|
-
onFocus: () =>
|
|
736
|
-
onCancel: cancel
|
|
795
|
+
overlay = showOverlay(targetWindow, labels, theme, {
|
|
796
|
+
onFocus: () => controls.focus(),
|
|
797
|
+
onCancel: () => controls.cancel()
|
|
737
798
|
});
|
|
738
799
|
}
|
|
800
|
+
options.onControls?.(controls);
|
|
739
801
|
});
|
|
740
802
|
}
|
|
741
803
|
|