@pasosdejesus/m 0.22.4 → 0.23.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/dist/CHANGELOG.md +43 -0
- package/dist/e2e/env.d.ts +8 -0
- package/dist/e2e/env.d.ts.map +1 -1
- package/dist/e2e/env.js +29 -2
- package/dist/e2e/env.js.map +1 -1
- package/dist/e2e/env.test.d.ts +2 -0
- package/dist/e2e/env.test.d.ts.map +1 -0
- package/dist/e2e/env.test.js +72 -0
- package/dist/e2e/env.test.js.map +1 -0
- package/dist/e2e/index.d.ts +6 -2
- package/dist/e2e/index.d.ts.map +1 -1
- package/dist/e2e/index.js +3 -1
- package/dist/e2e/index.js.map +1 -1
- package/dist/e2e/retry.d.ts +40 -0
- package/dist/e2e/retry.d.ts.map +1 -0
- package/dist/e2e/retry.js +45 -0
- package/dist/e2e/retry.js.map +1 -0
- package/dist/e2e/retry.test.d.ts +2 -0
- package/dist/e2e/retry.test.d.ts.map +1 -0
- package/dist/e2e/retry.test.js +43 -0
- package/dist/e2e/retry.test.js.map +1 -0
- package/dist/e2e/signer.d.ts +23 -0
- package/dist/e2e/signer.d.ts.map +1 -0
- package/dist/e2e/signer.js +28 -0
- package/dist/e2e/signer.js.map +1 -0
- package/dist/e2e/signer.test.d.ts +2 -0
- package/dist/e2e/signer.test.d.ts.map +1 -0
- package/dist/e2e/signer.test.js +57 -0
- package/dist/e2e/signer.test.js.map +1 -0
- package/dist/e2e/siwe-mock.d.ts.map +1 -1
- package/dist/e2e/siwe-mock.js +4 -8
- package/dist/e2e/siwe-mock.js.map +1 -1
- package/dist/e2e/wallet-mock.d.ts +25 -6
- package/dist/e2e/wallet-mock.d.ts.map +1 -1
- package/dist/e2e/wallet-mock.js +45 -4
- package/dist/e2e/wallet-mock.js.map +1 -1
- package/dist/e2e/wallet-mock.test.d.ts +2 -0
- package/dist/e2e/wallet-mock.test.d.ts.map +1 -0
- package/dist/e2e/wallet-mock.test.js +28 -0
- package/dist/e2e/wallet-mock.test.js.map +1 -0
- package/package.json +1 -1
package/dist/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@pasosdejesus/m` are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.23.1] - 2026-10-08
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **`@pasosdejesus/m/e2e` — API de firma real (corrige 0.23.0).** `ethereumMockCode`/
|
|
10
|
+
`eip6963MockCode` **ya no aceptan `privateKey`**: no instalaban el puente y generaban código que
|
|
11
|
+
llamaba a `window.__signMessage` sin existir. Ahora exponen `realSigning` + nombres de puente
|
|
12
|
+
(requieren el puente instalado) y la vía segura es `injectEIP6963(page, { address, privateKey })`,
|
|
13
|
+
que instala el puente **y** activa `realSigning`. Sin `realSigning`/`privateKey` sigue la firma
|
|
14
|
+
falsa `0xabab…` (https://gitlab.com/pasosdeJesus/m/-/work_items/49).
|
|
15
|
+
- Tests: nuevo `signer.test.ts` (EIP-191 verificable con `verifyMessage`, EIP-712, nombres de
|
|
16
|
+
puente) y casos de `SITE_URL` con path / http sin puerto en `env.test.ts`.
|
|
17
|
+
|
|
18
|
+
### Documentation
|
|
19
|
+
|
|
20
|
+
- `m/doc/identidad-multibilletera.md` §8.2: sivel3 **no** consume aún el núcleo (auth
|
|
21
|
+
wagmi/RainbowKit, EIP-191; `m@^0.18.4`); adoptará el núcleo al migrar su auth.
|
|
22
|
+
|
|
23
|
+
## [0.23.0] - 2026-10-08
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- **`@pasosdejesus/m/e2e` — firma real en el mock de billetera.** `installRealSigner(page,
|
|
28
|
+
{ privateKey, name })` expone en la página un puente que firma con la llave del spec, y
|
|
29
|
+
`ethereumMockCode`/`eip6963MockCode`/`injectEIP6963` aceptan `privateKey`: con él,
|
|
30
|
+
`personal_sign` y `eth_signTypedData_v4` devuelven firmas EIP-191/EIP-712 **reales**; sin él,
|
|
31
|
+
el comportamiento es el anterior (firma falsa `0xabab…`). `setupSIWEMock` pasa a usar el mismo
|
|
32
|
+
puente. Permite a los consumidores (sivel3, learn.tg) probar flujos con firma real
|
|
33
|
+
(https://gitlab.com/pasosdeJesus/m/-/work_items/49).
|
|
34
|
+
- **`@pasosdejesus/m/e2e` — reintentos.** `retry`, `retrySpec` y `gotoWithRetry` (`retry.ts`),
|
|
35
|
+
con opción `quiet` para silenciar los logs `[retry:…]`. Estabilizan los specs contra el sitio
|
|
36
|
+
compartido (https://gitlab.com/pasosdeJesus/m/-/work_items/49).
|
|
37
|
+
- **`@pasosdejesus/m/e2e` — `SITE_URL`.** `initTestEnv()` ahora honra `SITE_URL` (http o https),
|
|
38
|
+
p. ej. `SITE_URL=http://localhost:4000`, y resuelve `base`/`host`/`domainPort` acordes (antes
|
|
39
|
+
armaba siempre `https://…`, así que no se podía correr contra un `next dev` local en HTTP).
|
|
40
|
+
Se exportan `parseSiteUrl` y `resolveSiteTarget`. Sin `SITE_URL` no cambia nada
|
|
41
|
+
(https://gitlab.com/pasosdeJesus/m/-/work_items/49).
|
|
42
|
+
|
|
43
|
+
### Documentation
|
|
44
|
+
|
|
45
|
+
- `REQ/49` (helpers E2E), `REQ/36` (tablero único de coordinación), `REQ/47` (núcleo de
|
|
46
|
+
identidad) y `REQ/14` (billetera compartida: Fase 3 reutiliza el firmador de `REQ/49`).
|
|
47
|
+
|
|
5
48
|
## [0.22.4] - 2026-10-06
|
|
6
49
|
|
|
7
50
|
### Fixed
|
package/dist/e2e/env.d.ts
CHANGED
|
@@ -24,4 +24,12 @@ export interface E2EEnv {
|
|
|
24
24
|
}
|
|
25
25
|
export declare function initTestEnv(): Promise<E2EEnv>;
|
|
26
26
|
export declare function short(addr: string): string;
|
|
27
|
+
/** `SITE_URL` como URL absoluta, o `null` (con aviso) si no es válida. */
|
|
28
|
+
export declare function parseSiteUrl(raw: string | undefined): URL | null;
|
|
29
|
+
/** Campos de destino ya resueltos por `initTestEnv` (compatibilidad learn.tg). */
|
|
30
|
+
export declare function resolveSiteTarget(env: E2EEnv): {
|
|
31
|
+
base: string;
|
|
32
|
+
host: string;
|
|
33
|
+
domainPort: string;
|
|
34
|
+
};
|
|
27
35
|
//# sourceMappingURL=env.d.ts.map
|
package/dist/e2e/env.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/e2e/env.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAC5D;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,OAAO,CAAA;IACjB,yDAAyD;IACzD,OAAO,EAAE,UAAU,CAAA;IACnB;;;;;OAKG;IACH,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/e2e/env.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAC5D;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,OAAO,CAAA;IACjB,yDAAyD;IACzD,OAAO,EAAE,UAAU,CAAA;IACnB;;;;;OAKG;IACH,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CA0DnD;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,GAAG,GAAG,IAAI,CAQhE;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAEjG"}
|
package/dist/e2e/env.js
CHANGED
|
@@ -31,7 +31,18 @@ export async function initTestEnv() {
|
|
|
31
31
|
const port = process.env.PUERTOPRU || '443';
|
|
32
32
|
const host = process.env.IPDES || 'learn.tg';
|
|
33
33
|
const domainPort = port === '443' || port === '80' ? '' : `:${port}`;
|
|
34
|
-
|
|
34
|
+
// SITE_URL (m/REQ/49, P2): apunta a un servidor explícito (http o https), p.
|
|
35
|
+
// ej. `SITE_URL=http://localhost:4000`, sin parchear cada spec. Sin SITE_URL
|
|
36
|
+
// el comportamiento es el de siempre.
|
|
37
|
+
const siteUrl = parseSiteUrl(process.env.SITE_URL);
|
|
38
|
+
const resolvedHost = siteUrl ? siteUrl.hostname : host;
|
|
39
|
+
const resolvedDomainPort = siteUrl
|
|
40
|
+
? siteUrl.port ? `:${siteUrl.port}` : ''
|
|
41
|
+
: domainPort;
|
|
42
|
+
const resolvedPort = siteUrl
|
|
43
|
+
? siteUrl.port || (siteUrl.protocol === 'https:' ? '443' : '80')
|
|
44
|
+
: port;
|
|
45
|
+
const base = siteUrl ? siteUrl.origin : `https://${host}${domainPort}`;
|
|
35
46
|
const timeout = 60000;
|
|
36
47
|
const headless = process.env.CONCABEZA ? false : true;
|
|
37
48
|
// Prioridad de claves: TEST_PRIVATE_KEYS (lista) > TEST_PRIVATE_KEY >
|
|
@@ -68,9 +79,25 @@ export async function initTestEnv() {
|
|
|
68
79
|
console.log(` Using Hardhat test key: ${account.address}`);
|
|
69
80
|
}
|
|
70
81
|
const chainId = parseInt(process.env.CHAIN_ID || '42220', 10);
|
|
71
|
-
return { port, host, domainPort, base, timeout, headless, account, wallets, chainId };
|
|
82
|
+
return { port: resolvedPort, host: resolvedHost, domainPort: resolvedDomainPort, base, timeout, headless, account, wallets, chainId };
|
|
72
83
|
}
|
|
73
84
|
export function short(addr) {
|
|
74
85
|
return addr.slice(0, 10) + '...';
|
|
75
86
|
}
|
|
87
|
+
/** `SITE_URL` como URL absoluta, o `null` (con aviso) si no es válida. */
|
|
88
|
+
export function parseSiteUrl(raw) {
|
|
89
|
+
if (!raw)
|
|
90
|
+
return null;
|
|
91
|
+
try {
|
|
92
|
+
return new URL(raw);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
console.warn(`[e2e] SITE_URL inválida, se ignora: ${raw}`);
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** Campos de destino ya resueltos por `initTestEnv` (compatibilidad learn.tg). */
|
|
100
|
+
export function resolveSiteTarget(env) {
|
|
101
|
+
return { base: env.base, host: env.host, domainPort: env.domainPort };
|
|
102
|
+
}
|
|
76
103
|
//# sourceMappingURL=env.js.map
|
package/dist/e2e/env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/e2e/env.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B,oEAAoE;AACpE,2EAA2E;AAC3E,8EAA8E;AAC9E,sCAAsC;AACtC,MAAM,cAAc,GAA0C;IAC5D,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE;IACpD,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE;IAC1D,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;CAC/B,CAAA;AAED,SAAS,WAAW;IAClB,KAAK,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,cAAc,EAAE,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAA;YAC7C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAQ;YACrC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YAChD,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACtD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChE,IAAI,EAAE,IAAI,IAAI;gBAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;QACpD,CAAC;QAAC,MAAM,CAAC,CAAC,yBAAyB,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;AA0B9B,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,KAAK,CAAA;IAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,UAAU,CAAA;IAC5C,MAAM,UAAU,GAAG,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/e2e/env.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.test.d.ts","sourceRoot":"","sources":["../../src/e2e/env.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
2
|
+
import { initTestEnv, parseSiteUrl, resolveSiteTarget } from './env.js';
|
|
3
|
+
// P2 (m/REQ/49): `SITE_URL` permite apuntar a un servidor explícito (http o
|
|
4
|
+
// https) sin parchear cada spec; sin `SITE_URL` el comportamiento no cambia.
|
|
5
|
+
const KEYS = ['SITE_URL', 'IPDES', 'PUERTOPRU'];
|
|
6
|
+
const saved = {};
|
|
7
|
+
for (const k of KEYS)
|
|
8
|
+
saved[k] = process.env[k];
|
|
9
|
+
function restore() {
|
|
10
|
+
for (const k of KEYS) {
|
|
11
|
+
if (saved[k] === undefined)
|
|
12
|
+
delete process.env[k];
|
|
13
|
+
else
|
|
14
|
+
process.env[k] = saved[k];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
describe('e2e env — SITE_URL', () => {
|
|
18
|
+
afterEach(restore);
|
|
19
|
+
it('sin SITE_URL conserva el comportamiento anterior', async () => {
|
|
20
|
+
delete process.env.SITE_URL;
|
|
21
|
+
delete process.env.IPDES;
|
|
22
|
+
delete process.env.PUERTOPRU;
|
|
23
|
+
const env = await initTestEnv();
|
|
24
|
+
expect(env.base).toBe('https://learn.tg');
|
|
25
|
+
expect(env.host).toBe('learn.tg');
|
|
26
|
+
expect(env.domainPort).toBe('');
|
|
27
|
+
expect(env.port).toBe('443');
|
|
28
|
+
});
|
|
29
|
+
it('con SITE_URL http usa el origen tal cual y deriva host/domainPort', async () => {
|
|
30
|
+
process.env.SITE_URL = 'http://localhost:4000';
|
|
31
|
+
delete process.env.IPDES;
|
|
32
|
+
delete process.env.PUERTOPRU;
|
|
33
|
+
const env = await initTestEnv();
|
|
34
|
+
expect(env.base).toBe('http://localhost:4000');
|
|
35
|
+
expect(env.host).toBe('localhost');
|
|
36
|
+
expect(env.domainPort).toBe(':4000');
|
|
37
|
+
expect(env.port).toBe('4000');
|
|
38
|
+
expect(resolveSiteTarget(env)).toEqual({
|
|
39
|
+
base: 'http://localhost:4000',
|
|
40
|
+
host: 'localhost',
|
|
41
|
+
domainPort: ':4000',
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
it('SITE_URL https sin puerto explícito no añade domainPort', async () => {
|
|
45
|
+
process.env.SITE_URL = 'https://sivel.xyz';
|
|
46
|
+
const env = await initTestEnv();
|
|
47
|
+
expect(env.base).toBe('https://sivel.xyz');
|
|
48
|
+
expect(env.host).toBe('sivel.xyz');
|
|
49
|
+
expect(env.domainPort).toBe('');
|
|
50
|
+
expect(env.port).toBe('443');
|
|
51
|
+
});
|
|
52
|
+
it('SITE_URL con path usa solo el origin', async () => {
|
|
53
|
+
process.env.SITE_URL = 'https://sivel.xyz/app?x=1';
|
|
54
|
+
const env = await initTestEnv();
|
|
55
|
+
expect(env.base).toBe('https://sivel.xyz');
|
|
56
|
+
expect(env.host).toBe('sivel.xyz');
|
|
57
|
+
});
|
|
58
|
+
it('SITE_URL http sin puerto resuelve 80 (sin domainPort)', async () => {
|
|
59
|
+
process.env.SITE_URL = 'http://localhost';
|
|
60
|
+
const env = await initTestEnv();
|
|
61
|
+
expect(env.base).toBe('http://localhost');
|
|
62
|
+
expect(env.port).toBe('80');
|
|
63
|
+
expect(env.domainPort).toBe('');
|
|
64
|
+
});
|
|
65
|
+
it('parseSiteUrl ignora valores inválidos o vacíos', () => {
|
|
66
|
+
expect(parseSiteUrl(undefined)).toBeNull();
|
|
67
|
+
expect(parseSiteUrl('')).toBeNull();
|
|
68
|
+
expect(parseSiteUrl('no es una url')).toBeNull();
|
|
69
|
+
expect(parseSiteUrl('http://localhost:4000')?.hostname).toBe('localhost');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=env.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.test.js","sourceRoot":"","sources":["../../src/e2e/env.test.ts"],"names":[],"mappings":"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"}
|
package/dist/e2e/index.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
export { ok, fail, resetFailures, summary } from './assertions.js';
|
|
2
|
-
export { initTestEnv, short } from './env.js';
|
|
2
|
+
export { initTestEnv, short, parseSiteUrl, resolveSiteTarget } from './env.js';
|
|
3
3
|
export type { E2EEnv } from './env.js';
|
|
4
4
|
export { findChrome, launchBrowser, newPage, newIncognitoContext, newIncognitoPage, clearBrowserCache } from './browser.js';
|
|
5
5
|
export type { E2EPage, E2EBrowser, E2EBrowserContext } from './browser.js';
|
|
6
6
|
export { safeNavigate, waitForText } from './navigation.js';
|
|
7
|
+
export { retry, retrySpec, gotoWithRetry } from './retry.js';
|
|
8
|
+
export type { RetryOpts, RetrySpecOpts, GotoRetryOpts } from './retry.js';
|
|
7
9
|
export { simulateSIWE, checkSessionFull, checkPartialLogin } from './siwe.js';
|
|
8
10
|
export { setupSIWEMock } from './siwe-mock.js';
|
|
11
|
+
export { installRealSigner, REAL_SIGNER_NAME, REAL_TYPED_DATA_SIGNER_NAME } from './signer.js';
|
|
12
|
+
export type { RealSigner, RealSignerOpts } from './signer.js';
|
|
9
13
|
export { ethereumMockCode, eip6963MockCode, injectEIP6963 } from './wallet-mock.js';
|
|
10
|
-
export type { EthereumMockOpts } from './wallet-mock.js';
|
|
14
|
+
export type { EthereumMockOpts, InjectEIP6963Opts } from './wallet-mock.js';
|
|
11
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/e2e/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/e2e/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/e2e/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAC9E,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAC3H,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAC1E,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC5D,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACzE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AAC9F,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACnF,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA"}
|
package/dist/e2e/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// Barrel export for @pasosdejesus/m/e2e
|
|
2
2
|
export { ok, fail, resetFailures, summary } from './assertions.js';
|
|
3
|
-
export { initTestEnv, short } from './env.js';
|
|
3
|
+
export { initTestEnv, short, parseSiteUrl, resolveSiteTarget } from './env.js';
|
|
4
4
|
export { findChrome, launchBrowser, newPage, newIncognitoContext, newIncognitoPage, clearBrowserCache } from './browser.js';
|
|
5
5
|
export { safeNavigate, waitForText } from './navigation.js';
|
|
6
|
+
export { retry, retrySpec, gotoWithRetry } from './retry.js';
|
|
6
7
|
export { simulateSIWE, checkSessionFull, checkPartialLogin } from './siwe.js';
|
|
7
8
|
export { setupSIWEMock } from './siwe-mock.js';
|
|
9
|
+
export { installRealSigner, REAL_SIGNER_NAME, REAL_TYPED_DATA_SIGNER_NAME } from './signer.js';
|
|
8
10
|
export { ethereumMockCode, eip6963MockCode, injectEIP6963 } from './wallet-mock.js';
|
|
9
11
|
//# sourceMappingURL=index.js.map
|
package/dist/e2e/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/e2e/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/e2e/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAE9E,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAE3H,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE5D,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AAE9F,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { E2EPage } from './browser.js';
|
|
2
|
+
export interface RetryOpts {
|
|
3
|
+
/** Reintentos además del primer intento (default 3 → 4 ejecuciones). */
|
|
4
|
+
retries?: number;
|
|
5
|
+
/** Espera entre intentos en ms (default 10000). */
|
|
6
|
+
delayMs?: number;
|
|
7
|
+
/** Etiqueta para los logs `[retry:label]`. */
|
|
8
|
+
label?: string;
|
|
9
|
+
/** Silencia los logs `[retry:…]` (los consumidores envuelven `console`). */
|
|
10
|
+
quiet?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface RetrySpecOpts {
|
|
13
|
+
/** Intentos totales (default 2). */
|
|
14
|
+
attempts?: number;
|
|
15
|
+
/** Espera entre intentos en ms (default 20000). */
|
|
16
|
+
delayMs?: number;
|
|
17
|
+
label?: string;
|
|
18
|
+
/** Silencia los logs `[retrySpec:…]`. */
|
|
19
|
+
quiet?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface GotoRetryOpts {
|
|
22
|
+
waitUntil?: string;
|
|
23
|
+
timeout?: number;
|
|
24
|
+
retries?: number;
|
|
25
|
+
delayMs?: number;
|
|
26
|
+
label?: string;
|
|
27
|
+
/** Silencia los logs `[retry:goto:…]`. */
|
|
28
|
+
quiet?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Ejecuta `fn`, reintentando ante error. Propaga el último error si se agota. */
|
|
31
|
+
export declare function retry<T>(fn: () => Promise<T>, opts?: RetryOpts): Promise<T>;
|
|
32
|
+
/**
|
|
33
|
+
* Repite un spec completo. Solo para specs **seguros de re-correr** (billetera
|
|
34
|
+
* fresca o diagnóstico sin gasto on-chain): repetir un flujo con transacción
|
|
35
|
+
* real duplicaría el gasto.
|
|
36
|
+
*/
|
|
37
|
+
export declare function retrySpec<T>(run: () => Promise<T>, opts?: RetrySpecOpts): Promise<T>;
|
|
38
|
+
/** `page.goto` con reintentos. */
|
|
39
|
+
export declare function gotoWithRetry(page: E2EPage, url: string, opts?: GotoRetryOpts): Promise<unknown>;
|
|
40
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/e2e/retry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C,MAAM,WAAW,SAAS;IACxB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAID,kFAAkF;AAClF,wBAAsB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,GAAE,SAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAqBrF;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,CAAC,CAAC,CAO9F;AAED,kCAAkC;AAClC,wBAAsB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAM1G"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
2
|
+
/** Ejecuta `fn`, reintentando ante error. Propaga el último error si se agota. */
|
|
3
|
+
export async function retry(fn, opts = {}) {
|
|
4
|
+
const retries = opts.retries ?? 3;
|
|
5
|
+
const delayMs = opts.delayMs ?? 10000;
|
|
6
|
+
const label = opts.label || 'retry';
|
|
7
|
+
const log = opts.quiet ? () => { } : (msg) => console.log(msg);
|
|
8
|
+
let lastError;
|
|
9
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
10
|
+
try {
|
|
11
|
+
return await fn();
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
lastError = err;
|
|
15
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
16
|
+
if (attempt < retries) {
|
|
17
|
+
log(`[retry:${label}] intento ${attempt + 1}/${retries + 1} falló (${msg}); reintento en ${delayMs}ms`);
|
|
18
|
+
await sleep(delayMs);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
log(`[retry:${label}] agotado tras ${retries + 1} intento(s)`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
throw lastError;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Repite un spec completo. Solo para specs **seguros de re-correr** (billetera
|
|
29
|
+
* fresca o diagnóstico sin gasto on-chain): repetir un flujo con transacción
|
|
30
|
+
* real duplicaría el gasto.
|
|
31
|
+
*/
|
|
32
|
+
export async function retrySpec(run, opts = {}) {
|
|
33
|
+
return retry(run, {
|
|
34
|
+
retries: Math.max(0, (opts.attempts ?? 2) - 1),
|
|
35
|
+
delayMs: opts.delayMs ?? 20000,
|
|
36
|
+
label: opts.label || 'retrySpec',
|
|
37
|
+
quiet: opts.quiet,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** `page.goto` con reintentos. */
|
|
41
|
+
export async function gotoWithRetry(page, url, opts = {}) {
|
|
42
|
+
const label = opts.label || url;
|
|
43
|
+
return retry(() => page.goto(url, { waitUntil: opts.waitUntil || 'domcontentloaded', timeout: opts.timeout ?? 60000 }), { retries: opts.retries ?? 3, delayMs: opts.delayMs ?? 5000, label: `goto:${label}`, quiet: opts.quiet });
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/e2e/retry.ts"],"names":[],"mappings":"AAoCA,MAAM,KAAK,GAAG,CAAC,EAAU,EAAiB,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AAE9F,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,KAAK,CAAI,EAAoB,EAAE,OAAkB,EAAE;IACvE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;IACjC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,KAAK,CAAA;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,OAAO,CAAA;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACrE,IAAI,SAAkB,CAAA;IACtB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;QACpD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAA;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,GAAG,GAAG,CAAA;YACf,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5D,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;gBACtB,GAAG,CAAC,UAAU,KAAK,aAAa,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,WAAW,GAAG,mBAAmB,OAAO,IAAI,CAAC,CAAA;gBACvG,MAAM,KAAK,CAAC,OAAO,CAAC,CAAA;YACtB,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,UAAU,KAAK,kBAAkB,OAAO,GAAG,CAAC,aAAa,CAAC,CAAA;YAChE,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,SAAS,CAAA;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,GAAqB,EAAE,OAAsB,EAAE;IAChF,OAAO,KAAK,CAAC,GAAG,EAAE;QAChB,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC9C,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;QAC9B,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,WAAW;QAChC,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAA;AACJ,CAAC;AAED,kCAAkC;AAClC,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAa,EAAE,GAAW,EAAE,OAAsB,EAAE;IACtF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,CAAA;IAC/B,OAAO,KAAK,CACV,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,kBAAkB,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK,EAAE,CAAC,EACzG,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,KAAK,EAAE,QAAQ,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CACzG,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.test.d.ts","sourceRoot":"","sources":["../../src/e2e/retry.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { gotoWithRetry, retry, retrySpec } from './retry.js';
|
|
3
|
+
// P1 (m/REQ/49): estabilidad de los E2E ante fallos transitorios.
|
|
4
|
+
describe('retry — reintentos', () => {
|
|
5
|
+
it('devuelve el resultado si el primer intento pasa', async () => {
|
|
6
|
+
const fn = vi.fn().mockResolvedValue('ok');
|
|
7
|
+
await expect(retry(fn, { retries: 2, delayMs: 1 })).resolves.toBe('ok');
|
|
8
|
+
expect(fn).toHaveBeenCalledTimes(1);
|
|
9
|
+
});
|
|
10
|
+
it('reintenta hasta lograrlo', async () => {
|
|
11
|
+
let n = 0;
|
|
12
|
+
const fn = vi.fn().mockImplementation(async () => {
|
|
13
|
+
if (++n < 3)
|
|
14
|
+
throw new Error('boom');
|
|
15
|
+
return 'ok';
|
|
16
|
+
});
|
|
17
|
+
await expect(retry(fn, { retries: 3, delayMs: 1 })).resolves.toBe('ok');
|
|
18
|
+
expect(fn).toHaveBeenCalledTimes(3);
|
|
19
|
+
});
|
|
20
|
+
it('propaga el error al agotar los reintentos', async () => {
|
|
21
|
+
const fn = vi.fn().mockRejectedValue(new Error('siempre falla'));
|
|
22
|
+
await expect(retry(fn, { retries: 2, delayMs: 1 })).rejects.toThrow('siempre falla');
|
|
23
|
+
expect(fn).toHaveBeenCalledTimes(3);
|
|
24
|
+
});
|
|
25
|
+
it('retrySpec ejecuta hasta `attempts` veces', async () => {
|
|
26
|
+
const run = vi.fn().mockRejectedValue(new Error('x'));
|
|
27
|
+
await expect(retrySpec(run, { attempts: 2, delayMs: 0 })).rejects.toThrow('x');
|
|
28
|
+
expect(run).toHaveBeenCalledTimes(2);
|
|
29
|
+
});
|
|
30
|
+
it('gotoWithRetry reintenta page.goto', async () => {
|
|
31
|
+
let n = 0;
|
|
32
|
+
const page = {
|
|
33
|
+
goto: vi.fn().mockImplementation(async () => {
|
|
34
|
+
if (++n < 2)
|
|
35
|
+
throw new Error('net');
|
|
36
|
+
return 'page';
|
|
37
|
+
}),
|
|
38
|
+
};
|
|
39
|
+
await expect(gotoWithRetry(page, 'http://x', { retries: 3, delayMs: 0 })).resolves.toBe('page');
|
|
40
|
+
expect(page.goto).toHaveBeenCalledTimes(2);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=retry.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.test.js","sourceRoot":"","sources":["../../src/e2e/retry.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { E2EPage } from './browser.js';
|
|
2
|
+
/** Nombre por defecto del puente para `personal_sign`. */
|
|
3
|
+
export declare const REAL_SIGNER_NAME = "__signMessage";
|
|
4
|
+
/** Nombre por defecto del puente para `eth_signTypedData_v4`. */
|
|
5
|
+
export declare const REAL_TYPED_DATA_SIGNER_NAME = "__signTypedData";
|
|
6
|
+
export interface RealSignerOpts {
|
|
7
|
+
privateKey: `0x${string}`;
|
|
8
|
+
/** Nombre del puente de `personal_sign` (default `__signMessage`). */
|
|
9
|
+
name?: string;
|
|
10
|
+
/** Nombre del puente de `eth_signTypedData_v4` (default `__signTypedData`). */
|
|
11
|
+
typedDataName?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface RealSigner {
|
|
14
|
+
address: string;
|
|
15
|
+
name: string;
|
|
16
|
+
typedDataName: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Instala en `page` el puente de firma real. Llamar **antes** de
|
|
20
|
+
* `evaluateOnNewDocument`/navegar. Devuelve la dirección derivada de la llave.
|
|
21
|
+
*/
|
|
22
|
+
export declare function installRealSigner(page: E2EPage, opts: RealSignerOpts): Promise<RealSigner>;
|
|
23
|
+
//# sourceMappingURL=signer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/e2e/signer.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,kBAAkB,CAAA;AAC/C,iEAAiE;AACjE,eAAO,MAAM,2BAA2B,oBAAoB,CAAA;AAE5D,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,KAAK,MAAM,EAAE,CAAA;IACzB,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;CACtB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAqBhG"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Nombre por defecto del puente para `personal_sign`. */
|
|
2
|
+
export const REAL_SIGNER_NAME = '__signMessage';
|
|
3
|
+
/** Nombre por defecto del puente para `eth_signTypedData_v4`. */
|
|
4
|
+
export const REAL_TYPED_DATA_SIGNER_NAME = '__signTypedData';
|
|
5
|
+
/**
|
|
6
|
+
* Instala en `page` el puente de firma real. Llamar **antes** de
|
|
7
|
+
* `evaluateOnNewDocument`/navegar. Devuelve la dirección derivada de la llave.
|
|
8
|
+
*/
|
|
9
|
+
export async function installRealSigner(page, opts) {
|
|
10
|
+
const { privateKeyToAccount } = await import('viem/accounts');
|
|
11
|
+
const account = privateKeyToAccount(opts.privateKey);
|
|
12
|
+
const name = opts.name || REAL_SIGNER_NAME;
|
|
13
|
+
const typedDataName = opts.typedDataName || REAL_TYPED_DATA_SIGNER_NAME;
|
|
14
|
+
await page.exposeFunction(name, async (message) => {
|
|
15
|
+
const sig = await account.signMessage({ message });
|
|
16
|
+
return typeof sig === 'string' ? sig : sig.signature || sig;
|
|
17
|
+
});
|
|
18
|
+
await page.exposeFunction(typedDataName, async (json) => {
|
|
19
|
+
const typedData = typeof json === 'string' ? JSON.parse(json) : json;
|
|
20
|
+
const { domain, types, primaryType, message } = typedData;
|
|
21
|
+
// viem deriva `EIP712Domain` de `domain`; no debe ir en `types`.
|
|
22
|
+
const cleanTypes = { ...types };
|
|
23
|
+
delete cleanTypes.EIP712Domain;
|
|
24
|
+
return account.signTypedData({ domain, types: cleanTypes, primaryType, message });
|
|
25
|
+
});
|
|
26
|
+
return { address: account.address, name, typedDataName };
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=signer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../../src/e2e/signer.ts"],"names":[],"mappings":"AAWA,0DAA0D;AAC1D,MAAM,CAAC,MAAM,gBAAgB,GAAG,eAAe,CAAA;AAC/C,iEAAiE;AACjE,MAAM,CAAC,MAAM,2BAA2B,GAAG,iBAAiB,CAAA;AAgB5D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAa,EAAE,IAAoB;IACzE,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;IAC7D,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,gBAAgB,CAAA;IAC1C,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,2BAA2B,CAAA;IAEvE,MAAO,IAAY,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,OAAe,EAAE,EAAE;QACjE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;QAClD,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAE,GAAW,CAAC,SAAS,IAAI,GAAG,CAAA;IACtE,CAAC,CAAC,CAAA;IAEF,MAAO,IAAY,CAAC,cAAc,CAAC,aAAa,EAAE,KAAK,EAAE,IAAqB,EAAE,EAAE;QAChF,MAAM,SAAS,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACpE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,SAAS,CAAA;QACzD,iEAAiE;QACjE,MAAM,UAAU,GAAG,EAAE,GAAG,KAAK,EAAE,CAAA;QAC/B,OAAO,UAAU,CAAC,YAAY,CAAA;QAC9B,OAAO,OAAO,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAA;IACnF,CAAC,CAAC,CAAA;IAEF,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAA;AAC1D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.test.d.ts","sourceRoot":"","sources":["../../src/e2e/signer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { installRealSigner } from './signer.js';
|
|
3
|
+
const PK = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
|
|
4
|
+
const ADDR = '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266';
|
|
5
|
+
/** Página falsa que captura los puentes expuestos con `exposeFunction`. */
|
|
6
|
+
function fakePage() {
|
|
7
|
+
const exposed = {};
|
|
8
|
+
return {
|
|
9
|
+
page: { exposeFunction: async (name, fn) => { exposed[name] = fn; } },
|
|
10
|
+
exposed,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
// P6/P7 (m/REQ/49): el puente de firma real.
|
|
14
|
+
describe('signer — installRealSigner', () => {
|
|
15
|
+
it('deriva la dirección y firma EIP-191 verificable', async () => {
|
|
16
|
+
const { page, exposed } = fakePage();
|
|
17
|
+
const signer = await installRealSigner(page, { privateKey: PK });
|
|
18
|
+
expect(signer.address).toBe(ADDR);
|
|
19
|
+
const sig = await exposed['__signMessage']('hola');
|
|
20
|
+
expect(sig).toMatch(/^0x[0-9a-f]+$/i);
|
|
21
|
+
const { verifyMessage } = await import('viem');
|
|
22
|
+
const ok = await verifyMessage({ address: ADDR, message: 'hola', signature: sig });
|
|
23
|
+
expect(ok).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
it('firma EIP-712 (typed data), ignorando EIP712Domain en types', async () => {
|
|
26
|
+
const { page, exposed } = fakePage();
|
|
27
|
+
await installRealSigner(page, { privateKey: PK });
|
|
28
|
+
const typed = {
|
|
29
|
+
domain: { name: 'Test', version: '1', chainId: 42220 },
|
|
30
|
+
types: {
|
|
31
|
+
EIP712Domain: [
|
|
32
|
+
{ name: 'name', type: 'string' },
|
|
33
|
+
{ name: 'version', type: 'string' },
|
|
34
|
+
{ name: 'chainId', type: 'uint256' },
|
|
35
|
+
],
|
|
36
|
+
Score: [{ name: 'value', type: 'uint256' }],
|
|
37
|
+
},
|
|
38
|
+
primaryType: 'Score',
|
|
39
|
+
message: { value: 1 },
|
|
40
|
+
};
|
|
41
|
+
const sig = await exposed['__signTypedData'](JSON.stringify(typed));
|
|
42
|
+
expect(sig).toMatch(/^0x[0-9a-f]+$/i);
|
|
43
|
+
});
|
|
44
|
+
it('respeta nombres de puente personalizados', async () => {
|
|
45
|
+
const { page, exposed } = fakePage();
|
|
46
|
+
const signer = await installRealSigner(page, {
|
|
47
|
+
privateKey: PK,
|
|
48
|
+
name: '__firma',
|
|
49
|
+
typedDataName: '__firmaTyped',
|
|
50
|
+
});
|
|
51
|
+
expect(signer.name).toBe('__firma');
|
|
52
|
+
expect(signer.typedDataName).toBe('__firmaTyped');
|
|
53
|
+
expect(exposed['__firma']).toBeTypeOf('function');
|
|
54
|
+
expect(exposed['__firmaTyped']).toBeTypeOf('function');
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=signer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.test.js","sourceRoot":"","sources":["../../src/e2e/signer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"siwe-mock.d.ts","sourceRoot":"","sources":["../../src/e2e/siwe-mock.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"siwe-mock.d.ts","sourceRoot":"","sources":["../../src/e2e/siwe-mock.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAgB3C,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,MAAc,EACvB,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,IAAI,CAAC,CAqEf"}
|
package/dist/e2e/siwe-mock.js
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
// const page = await browser.newPage()
|
|
22
22
|
// await setupSIWEMock(page, address, privateKey, chainId)
|
|
23
23
|
// await page.goto(url) // mock is ready before any page script runs
|
|
24
|
+
import { installRealSigner } from './signer.js';
|
|
24
25
|
// Fake balance: 1000 * 10^18 wei (for native CELO / 18-decimal tokens)
|
|
25
26
|
const FAKE_BALANCE_18 = '0x00000000000000000000000000000000000000000000003635C9ADC5DEA00000';
|
|
26
27
|
// Fake balance: 1000 * 10^6 (for USDT / 6-decimal tokens)
|
|
@@ -38,13 +39,8 @@ export async function setupSIWEMock(page, address, privateKey, chainId = 42220,
|
|
|
38
39
|
const fakeBalance = opts.fakeBalance || FAKE_BALANCE_18;
|
|
39
40
|
const fakeCelo = opts.fakeCelo || FAKE_CELO;
|
|
40
41
|
const fakeTxHash = opts.fakeTxHash || ('0x' + 'cd'.repeat(32));
|
|
41
|
-
//
|
|
42
|
-
await page
|
|
43
|
-
const { privateKeyToAccount } = await import('viem/accounts');
|
|
44
|
-
const account = privateKeyToAccount(privateKey);
|
|
45
|
-
const sig = await account.signMessage({ message });
|
|
46
|
-
return typeof sig === 'string' ? sig : sig.signature || sig;
|
|
47
|
-
});
|
|
42
|
+
// Puente de firma real (compartido con wallet-mock) ANTES de que cargue la página.
|
|
43
|
+
await installRealSigner(page, { privateKey: privateKey });
|
|
48
44
|
// Inject full wallet mock BEFORE any page script runs
|
|
49
45
|
// This survives page reloads (evaluateOnNewDocument)
|
|
50
46
|
await page.evaluateOnNewDocument((addr, cid, bal, celo, txHash) => {
|
|
@@ -61,7 +57,7 @@ export async function setupSIWEMock(page, address, privateKey, chainId = 42220,
|
|
|
61
57
|
if (method === 'eth_requestAccounts')
|
|
62
58
|
return [addr];
|
|
63
59
|
if (method === 'personal_sign')
|
|
64
|
-
return window.
|
|
60
|
+
return window.__signMessage(params[0]);
|
|
65
61
|
if (method === 'wallet_switchEthereumChain')
|
|
66
62
|
return null;
|
|
67
63
|
if (method === 'eth_getBalance')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"siwe-mock.js","sourceRoot":"","sources":["../../src/e2e/siwe-mock.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,EAAE;AACF,iEAAiE;AACjE,+EAA+E;AAC/E,EAAE;AACF,+EAA+E;AAC/E,2DAA2D;AAC3D,8EAA8E;AAC9E,4EAA4E;AAC5E,EAAE;AACF,wCAAwC;AACxC,gEAAgE;AAChE,2DAA2D;AAC3D,+DAA+D;AAC/D,sCAAsC;AACtC,yCAAyC;AACzC,0EAA0E;AAC1E,EAAE;AACF,SAAS;AACT,wDAAwD;AACxD,yCAAyC;AACzC,4DAA4D;AAC5D,uEAAuE;
|
|
1
|
+
{"version":3,"file":"siwe-mock.js","sourceRoot":"","sources":["../../src/e2e/siwe-mock.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,12 +2,31 @@ import type { E2EPage } from './browser.js';
|
|
|
2
2
|
export interface EthereumMockOpts {
|
|
3
3
|
address: string;
|
|
4
4
|
chainId?: number;
|
|
5
|
+
/**
|
|
6
|
+
* El código llamará a los puentes de `installRealSigner` para
|
|
7
|
+
* `personal_sign`/`eth_signTypedData_v4`. **Requiere** que el puente esté
|
|
8
|
+
* instalado: llama `installRealSigner(page, { privateKey })` antes, o usa
|
|
9
|
+
* `injectEIP6963(page, { address, privateKey })`, que lo instala por ti.
|
|
10
|
+
* Sin esto, la firma es falsa (`0xabab…`).
|
|
11
|
+
*/
|
|
12
|
+
realSigning?: boolean;
|
|
13
|
+
/** Nombre del puente de `personal_sign` (default `__signMessage`). */
|
|
14
|
+
signerName?: string;
|
|
15
|
+
/** Nombre del puente typed-data (default `__signTypedData`). */
|
|
16
|
+
typedDataSignerName?: string;
|
|
17
|
+
/** Nombre de la billetera anunciada por EIP-6963 (default `MockWallet`). */
|
|
18
|
+
walletName?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface InjectEIP6963Opts extends EthereumMockOpts {
|
|
21
|
+
/** Instala el puente de firma real **y** activa `realSigning`. */
|
|
22
|
+
privateKey?: string;
|
|
5
23
|
}
|
|
6
24
|
export declare function ethereumMockCode(opts: EthereumMockOpts): string;
|
|
7
|
-
export declare function eip6963MockCode(opts: EthereumMockOpts
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
25
|
+
export declare function eip6963MockCode(opts: EthereumMockOpts): string;
|
|
26
|
+
/**
|
|
27
|
+
* Inyecta el mock EIP-6963. Con `privateKey` **instala el puente de firma real**
|
|
28
|
+
* (via `installRealSigner`) y activa `realSigning`, de modo que `personal_sign`
|
|
29
|
+
* y `eth_signTypedData_v4` firman de verdad. Sin `privateKey`, firma en falso.
|
|
30
|
+
*/
|
|
31
|
+
export declare function injectEIP6963(page: E2EPage, opts: InjectEIP6963Opts): Promise<void>;
|
|
13
32
|
//# sourceMappingURL=wallet-mock.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wallet-mock.d.ts","sourceRoot":"","sources":["../../src/e2e/wallet-mock.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wallet-mock.d.ts","sourceRoot":"","sources":["../../src/e2e/wallet-mock.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG3C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gEAAgE;IAChE,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAeD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAwB/D;AAID,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAyC9D;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCzF"}
|
package/dist/e2e/wallet-mock.js
CHANGED
|
@@ -2,11 +2,31 @@
|
|
|
2
2
|
// into the browser page. Not detected by wagmi (EIP-6963), but prevents
|
|
3
3
|
// console errors and enables basic dApp interaction.
|
|
4
4
|
//
|
|
5
|
+
// Firma real (P6, m/REQ/49): el firmado real de `personal_sign` /
|
|
6
|
+
// `eth_signTypedData_v4` se controla con `realSigning` y **requiere** que el
|
|
7
|
+
// puente de `installRealSigner` esté instalado. La forma segura de habilitarlo
|
|
8
|
+
// es `injectEIP6963(page, { address, privateKey })`, que instala el puente y
|
|
9
|
+
// activa `realSigning`. Sin `realSigning` el mock firma en falso (retrocompatible).
|
|
10
|
+
//
|
|
5
11
|
// For wagmi/RainbowKit compatibility, use eip6963MockCode() or injectEIP6963().
|
|
12
|
+
import { installRealSigner } from './signer.js';
|
|
13
|
+
const FAKE_SIG = `'0x' + 'ab'.repeat(65)`;
|
|
14
|
+
/** Devuelve las expresiones de firma para el código inyectado. */
|
|
15
|
+
function signerCalls(opts) {
|
|
16
|
+
if (!opts.realSigning)
|
|
17
|
+
return { personal: FAKE_SIG, typed: FAKE_SIG };
|
|
18
|
+
const name = opts.signerName || '__signMessage';
|
|
19
|
+
const typedName = opts.typedDataSignerName || '__signTypedData';
|
|
20
|
+
return {
|
|
21
|
+
personal: `(await window['${name}'](params[0]))`,
|
|
22
|
+
typed: `(await window['${typedName}'](params[1]))`,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
6
25
|
export function ethereumMockCode(opts) {
|
|
7
26
|
const addr = opts.address;
|
|
8
27
|
const cid = opts.chainId || 42220;
|
|
9
28
|
const hexChainId = '0x' + cid.toString(16);
|
|
29
|
+
const { personal, typed } = signerCalls(opts);
|
|
10
30
|
return `
|
|
11
31
|
window.ethereum = {
|
|
12
32
|
isMetaMask: true,
|
|
@@ -16,7 +36,8 @@ export function ethereumMockCode(opts) {
|
|
|
16
36
|
if (method === 'eth_chainId') return '${hexChainId}'
|
|
17
37
|
if (method === 'eth_accounts') return ['${addr}']
|
|
18
38
|
if (method === 'eth_requestAccounts') return ['${addr}']
|
|
19
|
-
if (method === 'personal_sign') return
|
|
39
|
+
if (method === 'personal_sign') return ${personal}
|
|
40
|
+
if (method === 'eth_signTypedData_v4') return ${typed}
|
|
20
41
|
if (method === 'wallet_switchEthereumChain') return null
|
|
21
42
|
if (method === 'eth_sendTransaction') return '0x' + 'cd'.repeat(32)
|
|
22
43
|
return null
|
|
@@ -33,6 +54,7 @@ export function eip6963MockCode(opts) {
|
|
|
33
54
|
const cid = opts.chainId || 42220;
|
|
34
55
|
const hexChainId = '0x' + cid.toString(16);
|
|
35
56
|
const walletName = opts.walletName || 'MockWallet';
|
|
57
|
+
const { personal, typed } = signerCalls(opts);
|
|
36
58
|
return `
|
|
37
59
|
const __provider = {
|
|
38
60
|
isMetaMask: true,
|
|
@@ -42,7 +64,8 @@ export function eip6963MockCode(opts) {
|
|
|
42
64
|
if (method === 'eth_chainId') return '${hexChainId}'
|
|
43
65
|
if (method === 'eth_accounts') return ['${addr}']
|
|
44
66
|
if (method === 'eth_requestAccounts') return ['${addr}']
|
|
45
|
-
if (method === 'personal_sign') return
|
|
67
|
+
if (method === 'personal_sign') return ${personal}
|
|
68
|
+
if (method === 'eth_signTypedData_v4') return ${typed}
|
|
46
69
|
if (method === 'wallet_switchEthereumChain') return null
|
|
47
70
|
if (method === 'eth_sendTransaction') return '0x' + 'cd'.repeat(32)
|
|
48
71
|
return null
|
|
@@ -68,9 +91,27 @@ export function eip6963MockCode(opts) {
|
|
|
68
91
|
}))
|
|
69
92
|
`;
|
|
70
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Inyecta el mock EIP-6963. Con `privateKey` **instala el puente de firma real**
|
|
96
|
+
* (via `installRealSigner`) y activa `realSigning`, de modo que `personal_sign`
|
|
97
|
+
* y `eth_signTypedData_v4` firman de verdad. Sin `privateKey`, firma en falso.
|
|
98
|
+
*/
|
|
71
99
|
export async function injectEIP6963(page, opts) {
|
|
72
|
-
|
|
73
|
-
|
|
100
|
+
let codeOpts = opts;
|
|
101
|
+
if (opts.privateKey) {
|
|
102
|
+
const signer = await installRealSigner(page, {
|
|
103
|
+
privateKey: opts.privateKey,
|
|
104
|
+
name: opts.signerName,
|
|
105
|
+
typedDataName: opts.typedDataSignerName,
|
|
106
|
+
});
|
|
107
|
+
codeOpts = {
|
|
108
|
+
...opts,
|
|
109
|
+
realSigning: true,
|
|
110
|
+
signerName: signer.name,
|
|
111
|
+
typedDataSignerName: signer.typedDataName,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
await page.evaluateOnNewDocument(eip6963MockCode(codeOpts));
|
|
74
115
|
// Re-dispatch EIP-6963 event after page loads so wagmi catches it
|
|
75
116
|
page.on('load', async () => {
|
|
76
117
|
await page.evaluate(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wallet-mock.js","sourceRoot":"","sources":["../../src/e2e/wallet-mock.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,wEAAwE;AACxE,qDAAqD;AACrD,EAAE;AACF,gFAAgF;
|
|
1
|
+
{"version":3,"file":"wallet-mock.js","sourceRoot":"","sources":["../../src/e2e/wallet-mock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-mock.test.d.ts","sourceRoot":"","sources":["../../src/e2e/wallet-mock.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { eip6963MockCode, ethereumMockCode } from './wallet-mock.js';
|
|
3
|
+
// P6 (m/REQ/49): sin `realSigning` el mock firma en falso (retrocompatible);
|
|
4
|
+
// con `realSigning` delega en el puente de `installRealSigner`.
|
|
5
|
+
describe('wallet-mock — firma real (realSigning)', () => {
|
|
6
|
+
it('sin realSigning devuelve la firma falsa (retrocompatible)', () => {
|
|
7
|
+
const code = ethereumMockCode({ address: '0xabc' });
|
|
8
|
+
expect(code).toContain(`'0x' + 'ab'.repeat(65)`);
|
|
9
|
+
expect(code).not.toContain('__signMessage');
|
|
10
|
+
});
|
|
11
|
+
it('con realSigning delega en el puente real', () => {
|
|
12
|
+
const code = ethereumMockCode({ address: '0xabc', realSigning: true });
|
|
13
|
+
expect(code).toContain(`window['__signMessage'](params[0])`);
|
|
14
|
+
expect(code).toContain(`window['__signTypedData'](params[1])`);
|
|
15
|
+
expect(code).not.toContain(`'0x' + 'ab'.repeat(65)`);
|
|
16
|
+
});
|
|
17
|
+
it('respeta los nombres de puente personalizados (EIP-6963)', () => {
|
|
18
|
+
const code = eip6963MockCode({
|
|
19
|
+
address: '0xabc',
|
|
20
|
+
realSigning: true,
|
|
21
|
+
signerName: '__firma',
|
|
22
|
+
typedDataSignerName: '__firmaTyped',
|
|
23
|
+
});
|
|
24
|
+
expect(code).toContain(`window['__firma'](params[0])`);
|
|
25
|
+
expect(code).toContain(`window['__firmaTyped'](params[1])`);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=wallet-mock.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-mock.test.js","sourceRoot":"","sources":["../../src/e2e/wallet-mock.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAEpE,6EAA6E;AAC7E,gEAAgE;AAChE,QAAQ,CAAC,wCAAwC,EAAE,GAAG,EAAE;IACtD,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;QACnD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAA;QAChD,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;QACtE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,oCAAoC,CAAC,CAAA;QAC5D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,sCAAsC,CAAC,CAAA;QAC9D,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,IAAI,GAAG,eAAe,CAAC;YAC3B,OAAO,EAAE,OAAO;YAChB,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,SAAS;YACrB,mBAAmB,EAAE,cAAc;SACpC,CAAC,CAAA;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAA;QACtD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,mCAAmC,CAAC,CAAA;IAC7D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|