@multiplatform.one/web3 8.2.0 → 8.2.2
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/cjs/bundler/metaMaskConnectTimeouts.cjs +6 -0
- package/dist/cjs/bundler/metaMaskConnectTimeouts.native.js +6 -0
- package/dist/cjs/bundler/metaMaskConnectTimeouts.native.js.map +1 -1
- package/dist/cjs/keycloak/KeycloakWalletLogin.cjs +33 -4
- package/dist/esm/bundler/metaMaskConnectTimeouts.mjs +6 -0
- package/dist/esm/bundler/metaMaskConnectTimeouts.mjs.map +1 -1
- package/dist/esm/bundler/metaMaskConnectTimeouts.native.js +6 -0
- package/dist/esm/bundler/metaMaskConnectTimeouts.native.js.map +1 -1
- package/dist/esm/keycloak/KeycloakWalletLogin.mjs +33 -4
- package/dist/esm/keycloak/KeycloakWalletLogin.mjs.map +1 -1
- package/dist/jsx/bundler/metaMaskConnectTimeouts.mjs +6 -0
- package/dist/jsx/bundler/metaMaskConnectTimeouts.mjs.map +1 -1
- package/dist/jsx/bundler/metaMaskConnectTimeouts.native.js +6 -0
- package/dist/jsx/bundler/metaMaskConnectTimeouts.native.js.map +1 -1
- package/dist/jsx/keycloak/KeycloakWalletLogin.mjs +33 -4
- package/dist/jsx/keycloak/KeycloakWalletLogin.mjs.map +1 -1
- package/dist/keycloak/login.iife.js +334 -334
- package/package.json +7 -7
- package/src/bundler/metaMaskConnectTimeouts.spec.ts +131 -0
- package/src/bundler/metaMaskConnectTimeouts.ts +15 -0
- package/src/keycloak/KeycloakWalletLogin.theme.spec.tsx +118 -0
- package/src/keycloak/KeycloakWalletLogin.tsx +31 -5
- package/types/bundler/metaMaskConnectTimeouts.d.ts.map +1 -1
- package/types/keycloak/KeycloakWalletLogin.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplatform.one/web3",
|
|
3
|
-
"version": "8.2.
|
|
3
|
+
"version": "8.2.2",
|
|
4
4
|
"description": "Web3 wallet integration for multiplatform.one ecosystem with ConnectKit and wagmi",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"connectkit",
|
|
@@ -120,10 +120,10 @@
|
|
|
120
120
|
"@aave/account": "^0.2.1",
|
|
121
121
|
"@coinbase/wallet-sdk": "^4.4.0",
|
|
122
122
|
"@metamask/connect-evm": "^2.1.1",
|
|
123
|
-
"@multiplatform.one/connectkit": "^8.2.
|
|
124
|
-
"@multiplatform.one/gpg": "^8.2.
|
|
125
|
-
"@multiplatform.one/platform": "^8.2.
|
|
126
|
-
"@multiplatform.one/theme": "^8.2.
|
|
123
|
+
"@multiplatform.one/connectkit": "^8.2.2",
|
|
124
|
+
"@multiplatform.one/gpg": "^8.2.2",
|
|
125
|
+
"@multiplatform.one/platform": "^8.2.2",
|
|
126
|
+
"@multiplatform.one/theme": "^8.2.2",
|
|
127
127
|
"@noble/ciphers": "^1.3.0",
|
|
128
128
|
"@noble/curves": "^1.9.7",
|
|
129
129
|
"@phosphor-icons/react": "^2.1.10",
|
|
@@ -147,8 +147,8 @@
|
|
|
147
147
|
"wagmi": "^3.7.1"
|
|
148
148
|
},
|
|
149
149
|
"devDependencies": {
|
|
150
|
-
"@multiplatform.one/config": "8.2.
|
|
151
|
-
"@multiplatform.one/test-utils": "8.2.
|
|
150
|
+
"@multiplatform.one/config": "8.2.2",
|
|
151
|
+
"@multiplatform.one/test-utils": "8.2.2",
|
|
152
152
|
"@tamagui/build": "2.7.6",
|
|
153
153
|
"@tanstack/react-query": "^5.104.3",
|
|
154
154
|
"@testing-library/jest-dom": "^7.0.1",
|
|
@@ -54,6 +54,12 @@ const iPadCheck =
|
|
|
54
54
|
|
|
55
55
|
const pageLoadResume =
|
|
56
56
|
/resumeSession_fn = function\(session, options\)[\s\S]*?isContinuingPriorAttempt \? this\.options\.resumeTimeout : options \? this\.options\.connectionTimeout : 120 \* 1e3/;
|
|
57
|
+
const extensionTimer = (seconds: number) =>
|
|
58
|
+
new RegExp(
|
|
59
|
+
`DEFAULT_REQUEST_TIMEOUT\\d* = ${seconds} \\* 1e3;\\s+var _notificationCallbacks\\d*, _transport\\d*, _defaultRequestOptions`,
|
|
60
|
+
"g",
|
|
61
|
+
);
|
|
62
|
+
|
|
57
63
|
const stockConnectionTimer =
|
|
58
64
|
/isContinuingPriorAttempt \? this\.options\.resumeTimeout : this\.options\.connectionTimeout/g;
|
|
59
65
|
|
|
@@ -85,6 +91,16 @@ describe("the timer patches on the installed MetaMask Connect", () => {
|
|
|
85
91
|
}
|
|
86
92
|
});
|
|
87
93
|
|
|
94
|
+
it("raises the desktop extension's request timer to 600 s", () => {
|
|
95
|
+
for (const file of multichainFiles) {
|
|
96
|
+
const code = read(file);
|
|
97
|
+
expect(code.match(extensionTimer(60))).toHaveLength(1);
|
|
98
|
+
const patched = patchMetaMaskConnectTimeouts(file, code)!.code;
|
|
99
|
+
expect(patched.match(extensionTimer(600))).toHaveLength(1);
|
|
100
|
+
expect(patched).not.toMatch(extensionTimer(60));
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
88
104
|
it("gives only the option-less page-load resume the stock 120 s", () => {
|
|
89
105
|
for (const file of multichainFiles) {
|
|
90
106
|
const code = read(file);
|
|
@@ -149,6 +165,14 @@ describe("the timer patches on the installed MetaMask Connect", () => {
|
|
|
149
165
|
code.replace(/(DEFAULT_REQUEST_TIMEOUT\d*) = 60 \* 1e3;/, "$1 = 90 * 1e3;"),
|
|
150
166
|
),
|
|
151
167
|
).toThrow(/timer DEFAULT_REQUEST_TIMEOUT not found/);
|
|
168
|
+
expect(() =>
|
|
169
|
+
patchMetaMaskConnectTimeouts(
|
|
170
|
+
multichain!,
|
|
171
|
+
code.replace(extensionTimer(60), (match) => match.replace("60 * 1e3", "30 * 1e3")),
|
|
172
|
+
),
|
|
173
|
+
).toThrow(
|
|
174
|
+
/timer DefaultTransport DEFAULT_REQUEST_TIMEOUT not found .* would lose the ten-minute desktop extension confirmation/,
|
|
175
|
+
);
|
|
152
176
|
expect(() =>
|
|
153
177
|
patchMetaMaskConnectTimeouts(
|
|
154
178
|
dappClient!,
|
|
@@ -278,6 +302,107 @@ describe("the patched MetaMask Connect transport", () => {
|
|
|
278
302
|
});
|
|
279
303
|
});
|
|
280
304
|
|
|
305
|
+
type DefaultTransportClass = new () => {
|
|
306
|
+
sendEip1193Message(payload: { method: string; params?: unknown[] }): Promise<{ result: unknown }>;
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
/** connect-multichain's desktop extension transport from its node build, patched or stock. */
|
|
310
|
+
function loadDefaultTransport(patched: boolean): DefaultTransportClass {
|
|
311
|
+
const file = requireHere.resolve(multichainPkg);
|
|
312
|
+
const code = patched ? patchMetaMaskConnectTimeouts(file, read(file))!.code : read(file);
|
|
313
|
+
const wrapper = runInThisContext(
|
|
314
|
+
`(function (module, exports, require, __filename, __dirname) {${code}\nreturn DefaultTransport;\n})`,
|
|
315
|
+
{ filename: file },
|
|
316
|
+
);
|
|
317
|
+
const module = { exports: {} };
|
|
318
|
+
return wrapper(module, module.exports, createRequire(file), file, dirname(file));
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
describe("the desktop extension transport", () => {
|
|
322
|
+
const origin = "https://dev.promanager.vip";
|
|
323
|
+
|
|
324
|
+
/** A page with the MetaMask extension that holds every confirmation until told. */
|
|
325
|
+
function extensionPage() {
|
|
326
|
+
const listeners: ((event: unknown) => void)[] = [];
|
|
327
|
+
const sent: { id: string; method: string }[] = [];
|
|
328
|
+
vi.stubGlobal("location", { origin });
|
|
329
|
+
vi.stubGlobal("window", {
|
|
330
|
+
addEventListener: (type: string, listener: (event: unknown) => void) => {
|
|
331
|
+
if (type === "message") listeners.push(listener);
|
|
332
|
+
},
|
|
333
|
+
removeEventListener: vi.fn(),
|
|
334
|
+
postMessage: (message: { data: { data: { id: string; method: string } } }) =>
|
|
335
|
+
sent.push(message.data.data),
|
|
336
|
+
});
|
|
337
|
+
return {
|
|
338
|
+
sent,
|
|
339
|
+
confirm(id: string, result: string) {
|
|
340
|
+
const event = {
|
|
341
|
+
origin,
|
|
342
|
+
data: {
|
|
343
|
+
target: "metamask-inpage",
|
|
344
|
+
data: { name: "metamask-provider", data: { id, result } },
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
for (const listener of listeners) listener(event);
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function settle(promise: Promise<unknown>) {
|
|
353
|
+
const state: { value?: unknown; error?: unknown; settled: boolean } = { settled: false };
|
|
354
|
+
promise.then(
|
|
355
|
+
(value) => Object.assign(state, { settled: true, value }),
|
|
356
|
+
(error) => Object.assign(state, { settled: true, error }),
|
|
357
|
+
);
|
|
358
|
+
return state;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
afterEach(() => {
|
|
362
|
+
vi.useRealTimers();
|
|
363
|
+
vi.unstubAllGlobals();
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
it("stock MetaMask Connect rejects a transaction still in MetaMask after 60 s", async () => {
|
|
367
|
+
vi.useFakeTimers();
|
|
368
|
+
extensionPage();
|
|
369
|
+
const DefaultTransport = loadDefaultTransport(false);
|
|
370
|
+
const send = settle(
|
|
371
|
+
new DefaultTransport().sendEip1193Message({ method: "eth_sendTransaction", params: [] }),
|
|
372
|
+
);
|
|
373
|
+
await vi.advanceTimersByTimeAsync(60_000);
|
|
374
|
+
expect((send.error as Error | undefined)?.message).toBe("Request timeout");
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it("resolves with the hash when the user confirms three minutes later", async () => {
|
|
378
|
+
vi.useFakeTimers();
|
|
379
|
+
const page = extensionPage();
|
|
380
|
+
const DefaultTransport = loadDefaultTransport(true);
|
|
381
|
+
const send = settle(
|
|
382
|
+
new DefaultTransport().sendEip1193Message({ method: "eth_sendTransaction", params: [] }),
|
|
383
|
+
);
|
|
384
|
+
await vi.advanceTimersByTimeAsync(180_000);
|
|
385
|
+
expect(send.settled).toBe(false);
|
|
386
|
+
expect(page.sent).toHaveLength(1);
|
|
387
|
+
page.confirm(page.sent[0]!.id, "0xhash");
|
|
388
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
389
|
+
expect(send.value).toMatchObject({ result: "0xhash" });
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
it("still gives up on a confirmation left open for ten minutes", async () => {
|
|
393
|
+
vi.useFakeTimers();
|
|
394
|
+
extensionPage();
|
|
395
|
+
const DefaultTransport = loadDefaultTransport(true);
|
|
396
|
+
const send = settle(
|
|
397
|
+
new DefaultTransport().sendEip1193Message({ method: "eth_sendTransaction", params: [] }),
|
|
398
|
+
);
|
|
399
|
+
await vi.advanceTimersByTimeAsync(599_999);
|
|
400
|
+
expect(send.settled).toBe(false);
|
|
401
|
+
await vi.advanceTimersByTimeAsync(1);
|
|
402
|
+
expect((send.error as Error | undefined)?.message).toBe("Request timeout");
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
|
|
281
406
|
const userAgents = {
|
|
282
407
|
iPadSafari:
|
|
283
408
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15",
|
|
@@ -356,6 +481,12 @@ const renameGracePeriod: Plugin = {
|
|
|
356
481
|
function expectLongTimers(code: string) {
|
|
357
482
|
expect(code).toMatch(/DEFAULT_REQUEST_TIMEOUT[\w$]* = 600 \* 1e3;\s+CONNECTION_GRACE_PERIOD/);
|
|
358
483
|
expect(code).toMatch(/HANDSHAKE_TIMEOUT[\w$]* = 540 \* 1e3;/);
|
|
484
|
+
expect(code).toMatch(
|
|
485
|
+
/DEFAULT_REQUEST_TIMEOUT[\w$]* = 600 \* 1e3;\s+var _notificationCallbacks[\w$]*[,;]\s+(?:var )?_transport/,
|
|
486
|
+
);
|
|
487
|
+
expect(code).not.toMatch(
|
|
488
|
+
/DEFAULT_REQUEST_TIMEOUT[\w$]* = 60 \* 1e3;\s+var _notificationCallbacks/,
|
|
489
|
+
);
|
|
359
490
|
expect(code).toMatch(/resumeTimeout : [\w$]+ \? this\.options\.connectionTimeout : 120 \* 1e3/);
|
|
360
491
|
expect(code).not.toMatch(/DEFAULT_REQUEST_TIMEOUT[\w$]* = 60 \* 1e3;\s+CONNECTION_GRACE_PERIOD/);
|
|
361
492
|
expect(code).not.toMatch(/HANDSHAKE_TIMEOUT[\w$]* = 60 \* 1e3;/);
|
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
// until the user switches back; a user who lingered in MetaMask lost the request
|
|
8
8
|
// to those timers. Both become ten minutes (540 s + the 60 s session expiry).
|
|
9
9
|
//
|
|
10
|
+
// On desktop the extension transport (DefaultTransport, window.postMessage to
|
|
11
|
+
// MetaMask's content script) has its own 60 s request timer, also a module
|
|
12
|
+
// constant. A transaction that sat in MetaMask's confirmation longer than that
|
|
13
|
+
// was rejected as "Request timeout" while MetaMask still showed it, so a user
|
|
14
|
+
// who confirmed late paid and the app never got the hash. It gets the same
|
|
15
|
+
// ten minutes as the relay's request timer.
|
|
16
|
+
//
|
|
10
17
|
// The connection timer is the request timer plus 60 s, so it grows to 660 s with
|
|
11
18
|
// it. That is right for a connect the user is approving in MetaMask, but the same
|
|
12
19
|
// timer bounds resuming a stored session on page load, where nobody is in
|
|
@@ -31,6 +38,7 @@ export type MetaMaskConnectTimerRewrite = {
|
|
|
31
38
|
};
|
|
32
39
|
|
|
33
40
|
const longTimers = "the long Android timers";
|
|
41
|
+
const longExtensionTimer = "the ten-minute desktop extension confirmation";
|
|
34
42
|
|
|
35
43
|
export type MetaMaskConnectTimeoutPatch = {
|
|
36
44
|
pkg: string;
|
|
@@ -49,6 +57,13 @@ export const metaMaskConnectTimeoutPatches: readonly MetaMaskConnectTimeoutPatch
|
|
|
49
57
|
pattern: /(DEFAULT_REQUEST_TIMEOUT\d*) = 60 \* 1e3;(\s+CONNECTION_GRACE_PERIOD =)/,
|
|
50
58
|
replacement: "$1 = 600 * 1e3;$2",
|
|
51
59
|
},
|
|
60
|
+
{
|
|
61
|
+
target: "timer DefaultTransport DEFAULT_REQUEST_TIMEOUT",
|
|
62
|
+
lost: longExtensionTimer,
|
|
63
|
+
pattern:
|
|
64
|
+
/(DEFAULT_REQUEST_TIMEOUT\d*) = 60 \* 1e3;(\s+var _notificationCallbacks\d*, _transport\d*, _defaultRequestOptions\d*,)/,
|
|
65
|
+
replacement: "$1 = 600 * 1e3;$2",
|
|
66
|
+
},
|
|
52
67
|
{
|
|
53
68
|
target: "timer the page-load session resume",
|
|
54
69
|
lost: longTimers,
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
import { cleanup, render } from "@testing-library/react";
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { createConfig, createStorage, http } from "wagmi";
|
|
5
|
+
import { mainnet } from "wagmi/chains";
|
|
6
|
+
import { mock } from "wagmi/connectors";
|
|
7
|
+
import { KeycloakWalletLogin, type KeycloakWalletLoginProps } from "./KeycloakWalletLogin";
|
|
8
|
+
|
|
9
|
+
const ACCOUNT = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";
|
|
10
|
+
|
|
11
|
+
type ColorScheme = "light" | "dark";
|
|
12
|
+
|
|
13
|
+
function memoryStorage() {
|
|
14
|
+
const map = new Map<string, string>();
|
|
15
|
+
return {
|
|
16
|
+
getItem: (key: string) => map.get(key) ?? null,
|
|
17
|
+
setItem: (key: string, value: string) => void map.set(key, value),
|
|
18
|
+
removeItem: (key: string) => void map.delete(key),
|
|
19
|
+
clear: () => map.clear(),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function setColorScheme(scheme: ColorScheme) {
|
|
24
|
+
const happy = (window as unknown as { happyDOM: { settings: { device: object } } }).happyDOM;
|
|
25
|
+
Object.assign(happy.settings.device, { prefersColorScheme: scheme });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function renderLogin(props: KeycloakWalletLoginProps = {}) {
|
|
29
|
+
const config = createConfig({
|
|
30
|
+
chains: [mainnet],
|
|
31
|
+
connectors: [mock({ accounts: [ACCOUNT] })],
|
|
32
|
+
transports: { [mainnet.id]: http() },
|
|
33
|
+
storage: createStorage({ storage: memoryStorage() }),
|
|
34
|
+
});
|
|
35
|
+
render(
|
|
36
|
+
<KeycloakWalletLogin
|
|
37
|
+
baseUrl="https://kc.example.com"
|
|
38
|
+
realm="main"
|
|
39
|
+
resource="wallet"
|
|
40
|
+
wagmiConfig={config}
|
|
41
|
+
{...props}
|
|
42
|
+
/>,
|
|
43
|
+
);
|
|
44
|
+
return {
|
|
45
|
+
wallet: document.getElementById("mpo-wallet-login") as HTMLButtonElement,
|
|
46
|
+
gpg: document.getElementById("mpo-gpg-login") as HTMLButtonElement,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* happy-dom resolves a custom property only on the element that declares it,
|
|
52
|
+
* so a `var()` in the button's style is looked up the ancestor chain here, the
|
|
53
|
+
* way a browser's cascade inherits it.
|
|
54
|
+
*/
|
|
55
|
+
function computed(element: HTMLElement, property: string) {
|
|
56
|
+
const declared = element.style.getPropertyValue(property);
|
|
57
|
+
const name = /^var\((--[\w-]+)\)$/.exec(declared)?.[1];
|
|
58
|
+
if (!name) return window.getComputedStyle(element).getPropertyValue(property);
|
|
59
|
+
for (let node: HTMLElement | null = element; node; node = node.parentElement) {
|
|
60
|
+
const value = window.getComputedStyle(node).getPropertyValue(name).trim();
|
|
61
|
+
if (value) return value;
|
|
62
|
+
}
|
|
63
|
+
return "";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function painted(button: HTMLElement) {
|
|
67
|
+
return { background: computed(button, "background"), color: computed(button, "color") };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** ConnectKit writes each colour token in display-p3 where the engine supports it. */
|
|
71
|
+
function p3(hex: string) {
|
|
72
|
+
const [r, g, b] = [1, 3, 5].map((at) => Number.parseInt(hex.slice(at, at + 2), 16) / 255);
|
|
73
|
+
return `color(display-p3 ${r} ${g} ${b})`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
beforeEach(() => {
|
|
77
|
+
vi.stubGlobal("localStorage", memoryStorage());
|
|
78
|
+
vi.stubGlobal(
|
|
79
|
+
"fetch",
|
|
80
|
+
vi.fn(async () => new Response("not found", { status: 404 })),
|
|
81
|
+
);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
afterEach(() => {
|
|
85
|
+
cleanup();
|
|
86
|
+
vi.unstubAllGlobals();
|
|
87
|
+
setColorScheme("light");
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe("KeycloakWalletLogin buttons follow the ConnectKit theme", () => {
|
|
91
|
+
it("paint the dark primary-button surface and ink in a dark scheme", () => {
|
|
92
|
+
setColorScheme("dark");
|
|
93
|
+
const { wallet, gpg } = renderLogin();
|
|
94
|
+
|
|
95
|
+
for (const button of [wallet, gpg]) {
|
|
96
|
+
expect(painted(button)).toEqual({ background: p3("#383838"), color: p3("#ffffff") });
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("paint the light primary-button surface and ink in a light scheme", () => {
|
|
101
|
+
setColorScheme("light");
|
|
102
|
+
const { wallet, gpg } = renderLogin();
|
|
103
|
+
|
|
104
|
+
for (const button of [wallet, gpg]) {
|
|
105
|
+
expect(painted(button)).toEqual({ background: p3("#F6F7F9"), color: p3("#373737") });
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("a buttonClassName keeps the host's look and takes no theme paint", () => {
|
|
110
|
+
setColorScheme("dark");
|
|
111
|
+
const { wallet, gpg } = renderLogin({ buttonClassName: "kc-button" });
|
|
112
|
+
|
|
113
|
+
for (const button of [wallet, gpg]) {
|
|
114
|
+
expect(button.getAttribute("style")).toBeNull();
|
|
115
|
+
expect(button.closest("[data-mpo-wallet-theme]")).toBeNull();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { ResetContainer, useContext as useConnectKit } from "@multiplatform.one/connectkit";
|
|
1
2
|
import { GpgProvider } from "@multiplatform.one/gpg";
|
|
2
3
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
3
|
-
import { type CSSProperties, useMemo } from "react";
|
|
4
|
+
import { type CSSProperties, type ReactNode, useMemo } from "react";
|
|
4
5
|
import type { Chain } from "viem";
|
|
5
6
|
import { type Config, WagmiProvider, createConfig } from "wagmi";
|
|
6
7
|
import { arbitrum, mainnet, optimism, polygon } from "wagmi/chains";
|
|
@@ -87,13 +88,18 @@ const buttonStyle: CSSProperties = {
|
|
|
87
88
|
marginTop: 8,
|
|
88
89
|
fontSize: 14,
|
|
89
90
|
cursor: "pointer",
|
|
90
|
-
border: "
|
|
91
|
+
border: "none",
|
|
91
92
|
borderRadius: 4,
|
|
92
|
-
background: "
|
|
93
|
+
background: "var(--ck-primary-button-background)",
|
|
94
|
+
color: "var(--ck-primary-button-color)",
|
|
93
95
|
};
|
|
94
96
|
|
|
97
|
+
const themeScopeStyle: CSSProperties = { display: "block" };
|
|
98
|
+
|
|
95
99
|
const noticeStyle: CSSProperties = { margin: "8px 0 0", fontSize: 13 };
|
|
96
100
|
|
|
101
|
+
const themedNoticeStyle: CSSProperties = { ...noticeStyle, color: "var(--ck-body-color)" };
|
|
102
|
+
|
|
97
103
|
/**
|
|
98
104
|
* Wallet and GPG sign-in for a Keycloak login page, on the browser flow: the
|
|
99
105
|
* signed credential posts to the page's authenticator. Carries its own wagmi,
|
|
@@ -179,7 +185,7 @@ function LoginButtons({
|
|
|
179
185
|
const { openGpg } = useWeb3Modal();
|
|
180
186
|
const style = buttonClassName ? undefined : buttonStyle;
|
|
181
187
|
const busy = status === StatusState.LOADING || status === StatusState.SUCCESS;
|
|
182
|
-
|
|
188
|
+
const buttons = (
|
|
183
189
|
<div className={className ?? "mpo-keycloak-wallet-login"}>
|
|
184
190
|
<button
|
|
185
191
|
type="button"
|
|
@@ -196,7 +202,11 @@ function LoginButtons({
|
|
|
196
202
|
<span>{busy ? "Signing…" : walletLabel}</span>
|
|
197
203
|
</button>
|
|
198
204
|
{dropped && !busy && (
|
|
199
|
-
<p
|
|
205
|
+
<p
|
|
206
|
+
id="mpo-wallet-login-dropped"
|
|
207
|
+
role="status"
|
|
208
|
+
style={style ? themedNoticeStyle : noticeStyle}
|
|
209
|
+
>
|
|
200
210
|
The wallet connection was lost. Tap {walletLabel} to connect again.
|
|
201
211
|
</p>
|
|
202
212
|
)}
|
|
@@ -217,6 +227,22 @@ function LoginButtons({
|
|
|
217
227
|
)}
|
|
218
228
|
</div>
|
|
219
229
|
);
|
|
230
|
+
return buttonClassName ? buttons : <ThemeScope>{buttons}</ThemeScope>;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function ThemeScope({ children }: { children: ReactNode }) {
|
|
234
|
+
const { theme, mode, customTheme } = useConnectKit();
|
|
235
|
+
return (
|
|
236
|
+
<ResetContainer
|
|
237
|
+
data-mpo-wallet-theme=""
|
|
238
|
+
$useTheme={theme}
|
|
239
|
+
$useMode={mode}
|
|
240
|
+
$customTheme={customTheme}
|
|
241
|
+
style={themeScopeStyle}
|
|
242
|
+
>
|
|
243
|
+
{children}
|
|
244
|
+
</ResetContainer>
|
|
245
|
+
);
|
|
220
246
|
}
|
|
221
247
|
|
|
222
248
|
function WalletIcon() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metaMaskConnectTimeouts.d.ts","sourceRoot":"","sources":["../../src/bundler/metaMaskConnectTimeouts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"metaMaskConnectTimeouts.d.ts","sourceRoot":"","sources":["../../src/bundler/metaMaskConnectTimeouts.ts"],"names":[],"mappings":"AA8BA,MAAM,MAAM,2BAA2B,GAAG;IACxC,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAKF,MAAM,MAAM,2BAA2B,GAAG;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,2BAA2B,EAAE,CAAC;CAClD,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,SAAS,2BAA2B,EA8C/E,CAAC;AAMF,2EAA2E;AAC3E,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,GACX,2BAA2B,GAAG,SAAS,CAKzC;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,GACX;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAY3C;AAED;;;GAGG;AACH,wBAAgB,mCAAmC;YAIvC,MAAM;cAGJ,MAAM,QAAQ,MAAM;aAzBxB,MAAM;cAAQ,MAAM;;IA+B1B,gFAAgF;eACrE,MAAM,GAAG,SAAS;EAShC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KeycloakWalletLogin.d.ts","sourceRoot":"","sources":["../../src/keycloak/KeycloakWalletLogin.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"KeycloakWalletLogin.d.ts","sourceRoot":"","sources":["../../src/keycloak/KeycloakWalletLogin.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,EAAE,KAAK,MAAM,EAA+B,MAAM,OAAO,CAAC;AAOjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAExE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAGtD,MAAM,WAAW,wBAAwB;IACvC,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IACtC,kFAAkF;IAClF,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,EACzC,OAAmB,EACnB,cAA2C,EAC3C,MAAuE,EACvE,OAAO,EACP,MAAsB,GACvB,GAAE,IAAI,CACL,wBAAwB,EACxB,SAAS,GAAG,gBAAgB,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAC1D,GAAG,MAAM,CAgBd;AAwBD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,2CAkElE"}
|