@pasosdejesus/m 0.23.1 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CHANGELOG.md +29 -0
- package/dist/e2e/full-wallet.d.ts +41 -0
- package/dist/e2e/full-wallet.d.ts.map +1 -0
- package/dist/e2e/full-wallet.js +138 -0
- package/dist/e2e/full-wallet.js.map +1 -0
- package/dist/e2e/full-wallet.test.d.ts +2 -0
- package/dist/e2e/full-wallet.test.d.ts.map +1 -0
- package/dist/e2e/full-wallet.test.js +37 -0
- package/dist/e2e/full-wallet.test.js.map +1 -0
- package/dist/e2e/index.d.ts +4 -0
- package/dist/e2e/index.d.ts.map +1 -1
- package/dist/e2e/index.js +2 -0
- package/dist/e2e/index.js.map +1 -1
- package/dist/e2e/local-node.d.ts +22 -0
- package/dist/e2e/local-node.d.ts.map +1 -0
- package/dist/e2e/local-node.js +144 -0
- package/dist/e2e/local-node.js.map +1 -0
- package/dist/e2e/local-node.test.d.ts +2 -0
- package/dist/e2e/local-node.test.d.ts.map +1 -0
- package/dist/e2e/local-node.test.js +43 -0
- package/dist/e2e/local-node.test.js.map +1 -0
- package/dist/tasks/wallet.d.ts.map +1 -1
- package/dist/tasks/wallet.js +14 -25
- package/dist/tasks/wallet.js.map +1 -1
- package/dist/test-utils/index.d.ts +1 -0
- package/dist/test-utils/index.d.ts.map +1 -1
- package/dist/test-utils/index.js +1 -0
- package/dist/test-utils/index.js.map +1 -1
- package/dist/test-utils/wallet-mocks.d.ts +44 -0
- package/dist/test-utils/wallet-mocks.d.ts.map +1 -0
- package/dist/test-utils/wallet-mocks.js +114 -0
- package/dist/test-utils/wallet-mocks.js.map +1 -0
- package/dist/test-utils/wallet-mocks.test.d.ts +2 -0
- package/dist/test-utils/wallet-mocks.test.d.ts.map +1 -0
- package/dist/test-utils/wallet-mocks.test.js +55 -0
- package/dist/test-utils/wallet-mocks.test.js.map +1 -0
- package/dist/test-utils/wallet-setup.d.ts +2 -0
- package/dist/test-utils/wallet-setup.d.ts.map +1 -0
- package/dist/test-utils/wallet-setup.js +23 -0
- package/dist/test-utils/wallet-setup.js.map +1 -0
- package/dist/test-utils/wallet-setup.test.d.ts +2 -0
- package/dist/test-utils/wallet-setup.test.d.ts.map +1 -0
- package/dist/test-utils/wallet-setup.test.js +18 -0
- package/dist/test-utils/wallet-setup.test.js.map +1 -0
- package/dist/wallet/biometric.d.ts +33 -0
- package/dist/wallet/biometric.d.ts.map +1 -0
- package/dist/wallet/biometric.js +88 -0
- package/dist/wallet/biometric.js.map +1 -0
- package/dist/wallet/biometric.test.d.ts +2 -0
- package/dist/wallet/biometric.test.d.ts.map +1 -0
- package/dist/wallet/biometric.test.js +44 -0
- package/dist/wallet/biometric.test.js.map +1 -0
- package/dist/wallet/crypto.d.ts +42 -0
- package/dist/wallet/crypto.d.ts.map +1 -0
- package/dist/wallet/crypto.js +127 -0
- package/dist/wallet/crypto.js.map +1 -0
- package/dist/wallet/crypto.test.d.ts +2 -0
- package/dist/wallet/crypto.test.d.ts.map +1 -0
- package/dist/wallet/crypto.test.js +34 -0
- package/dist/wallet/crypto.test.js.map +1 -0
- package/dist/wallet/destinations.d.ts +20 -0
- package/dist/wallet/destinations.d.ts.map +1 -0
- package/dist/wallet/destinations.js +98 -0
- package/dist/wallet/destinations.js.map +1 -0
- package/dist/wallet/destinations.test.d.ts +2 -0
- package/dist/wallet/destinations.test.d.ts.map +1 -0
- package/dist/wallet/destinations.test.js +34 -0
- package/dist/wallet/destinations.test.js.map +1 -0
- package/dist/wallet/external-provider.d.ts +33 -0
- package/dist/wallet/external-provider.d.ts.map +1 -0
- package/dist/wallet/external-provider.js +108 -0
- package/dist/wallet/external-provider.js.map +1 -0
- package/dist/wallet/external-provider.test.d.ts +2 -0
- package/dist/wallet/external-provider.test.d.ts.map +1 -0
- package/dist/wallet/external-provider.test.js +44 -0
- package/dist/wallet/external-provider.test.js.map +1 -0
- package/dist/wallet/index.d.ts +14 -0
- package/dist/wallet/index.d.ts.map +1 -0
- package/dist/wallet/index.js +24 -0
- package/dist/wallet/index.js.map +1 -0
- package/dist/wallet/indexeddb.test.d.ts +2 -0
- package/dist/wallet/indexeddb.test.d.ts.map +1 -0
- package/dist/wallet/indexeddb.test.js +28 -0
- package/dist/wallet/indexeddb.test.js.map +1 -0
- package/dist/wallet/kdf.test.d.ts +2 -0
- package/dist/wallet/kdf.test.d.ts.map +1 -0
- package/dist/wallet/kdf.test.js +54 -0
- package/dist/wallet/kdf.test.js.map +1 -0
- package/dist/wallet/provider.d.ts +38 -0
- package/dist/wallet/provider.d.ts.map +1 -0
- package/dist/wallet/provider.js +285 -0
- package/dist/wallet/provider.js.map +1 -0
- package/dist/wallet/provider.test.d.ts +2 -0
- package/dist/wallet/provider.test.d.ts.map +1 -0
- package/dist/wallet/provider.test.js +170 -0
- package/dist/wallet/provider.test.js.map +1 -0
- package/dist/wallet/signer.d.ts +55 -0
- package/dist/wallet/signer.d.ts.map +1 -0
- package/dist/wallet/signer.js +91 -0
- package/dist/wallet/signer.js.map +1 -0
- package/dist/wallet/signer.test.d.ts +2 -0
- package/dist/wallet/signer.test.d.ts.map +1 -0
- package/dist/wallet/signer.test.js +62 -0
- package/dist/wallet/signer.test.js.map +1 -0
- package/dist/wallet/siwe.d.ts +2 -0
- package/dist/wallet/siwe.d.ts.map +1 -0
- package/dist/wallet/siwe.js +5 -0
- package/dist/wallet/siwe.js.map +1 -0
- package/dist/wallet/storage/file.d.ts +19 -0
- package/dist/wallet/storage/file.d.ts.map +1 -0
- package/dist/wallet/storage/file.js +48 -0
- package/dist/wallet/storage/file.js.map +1 -0
- package/dist/wallet/storage/idb.d.ts +25 -0
- package/dist/wallet/storage/idb.d.ts.map +1 -0
- package/dist/wallet/storage/idb.js +58 -0
- package/dist/wallet/storage/idb.js.map +1 -0
- package/dist/wallet/storage/index.d.ts +5 -0
- package/dist/wallet/storage/index.d.ts.map +1 -0
- package/dist/wallet/storage/index.js +4 -0
- package/dist/wallet/storage/index.js.map +1 -0
- package/dist/wallet/storage/indexeddb.d.ts +8 -0
- package/dist/wallet/storage/indexeddb.d.ts.map +1 -0
- package/dist/wallet/storage/indexeddb.js +18 -0
- package/dist/wallet/storage/indexeddb.js.map +1 -0
- package/dist/wallet/storage/memory.d.ts +10 -0
- package/dist/wallet/storage/memory.d.ts.map +1 -0
- package/dist/wallet/storage/memory.js +19 -0
- package/dist/wallet/storage/memory.js.map +1 -0
- package/dist/wallet/storage.test.d.ts +2 -0
- package/dist/wallet/storage.test.d.ts.map +1 -0
- package/dist/wallet/storage.test.js +103 -0
- package/dist/wallet/storage.test.js.map +1 -0
- package/dist/wallet/types.d.ts +69 -0
- package/dist/wallet/types.d.ts.map +1 -0
- package/dist/wallet/types.js +6 -0
- package/dist/wallet/types.js.map +1 -0
- package/dist/wallet/wallet.d.ts +81 -0
- package/dist/wallet/wallet.d.ts.map +1 -0
- package/dist/wallet/wallet.js +358 -0
- package/dist/wallet/wallet.js.map +1 -0
- package/dist/wallet/wallet.test.d.ts +2 -0
- package/dist/wallet/wallet.test.d.ts.map +1 -0
- package/dist/wallet/wallet.test.js +150 -0
- package/dist/wallet/wallet.test.js.map +1 -0
- package/dist/wallet/web-authn.d.ts +78 -0
- package/dist/wallet/web-authn.d.ts.map +1 -0
- package/dist/wallet/web-authn.js +250 -0
- package/dist/wallet/web-authn.js.map +1 -0
- package/package.json +14 -4
- package/src/e2e/README.md +51 -0
- package/src/wallet/README.md +96 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const EMPTY = { provider: null, announced: [], source: null, rdns: null };
|
|
2
|
+
let state = EMPTY;
|
|
3
|
+
let started = false;
|
|
4
|
+
const listeners = new Set();
|
|
5
|
+
function emit(partial) {
|
|
6
|
+
state = { ...state, ...partial };
|
|
7
|
+
for (const listener of listeners)
|
|
8
|
+
listener();
|
|
9
|
+
}
|
|
10
|
+
function injected() {
|
|
11
|
+
if (typeof window === 'undefined')
|
|
12
|
+
return null;
|
|
13
|
+
return window.ethereum ?? null;
|
|
14
|
+
}
|
|
15
|
+
/** Sticky choice: `window.ethereum` when it exists, otherwise the announcement. */
|
|
16
|
+
function choose() {
|
|
17
|
+
if (state.provider)
|
|
18
|
+
return;
|
|
19
|
+
const direct = injected();
|
|
20
|
+
if (direct) {
|
|
21
|
+
emit({ provider: direct, source: 'window.ethereum', rdns: null });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (state.announced[0]) {
|
|
25
|
+
emit({ provider: state.announced[0].provider, source: 'eip6963', rdns: state.announced[0].rdns });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function start() {
|
|
29
|
+
if (started || typeof window === 'undefined')
|
|
30
|
+
return;
|
|
31
|
+
started = true;
|
|
32
|
+
window.addEventListener('eip6963:announceProvider', (event) => {
|
|
33
|
+
const detail = event.detail;
|
|
34
|
+
if (!detail?.provider)
|
|
35
|
+
return;
|
|
36
|
+
const rdns = detail.info?.rdns ?? detail.info?.name ?? 'unknown';
|
|
37
|
+
const announced = [
|
|
38
|
+
...state.announced.filter((item) => item.rdns !== rdns),
|
|
39
|
+
{
|
|
40
|
+
uuid: detail.info?.uuid ?? rdns,
|
|
41
|
+
name: detail.info?.name ?? rdns,
|
|
42
|
+
rdns,
|
|
43
|
+
icon: detail.info?.icon,
|
|
44
|
+
provider: detail.provider,
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
emit({ announced });
|
|
48
|
+
choose();
|
|
49
|
+
});
|
|
50
|
+
window.addEventListener('ethereum#initialized', choose);
|
|
51
|
+
window.dispatchEvent(new Event('eip6963:requestProvider'));
|
|
52
|
+
// Algunas WebViews inyectan tarde: reintentar un rato y una vez al primer gesto.
|
|
53
|
+
let attempts = 0;
|
|
54
|
+
const timer = window.setInterval(() => {
|
|
55
|
+
attempts += 1;
|
|
56
|
+
choose();
|
|
57
|
+
if (attempts >= 8)
|
|
58
|
+
window.clearInterval(timer);
|
|
59
|
+
}, 400);
|
|
60
|
+
for (const eventName of ['pointerdown', 'keydown', 'focus', 'visibilitychange']) {
|
|
61
|
+
window.addEventListener(eventName, choose, { once: true });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Suscribe un listener (para `useSyncExternalStore` del consumidor). */
|
|
65
|
+
export function subscribeExternalProvider(listener) {
|
|
66
|
+
start();
|
|
67
|
+
listeners.add(listener);
|
|
68
|
+
return () => {
|
|
69
|
+
listeners.delete(listener);
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** Snapshot actual del store (para `useSyncExternalStore`). */
|
|
73
|
+
export function getExternalProviderSnapshot() {
|
|
74
|
+
start();
|
|
75
|
+
choose();
|
|
76
|
+
return state;
|
|
77
|
+
}
|
|
78
|
+
/** Effective injected provider, or `null` (also callable outside React). */
|
|
79
|
+
export function getExternalProvider() {
|
|
80
|
+
start();
|
|
81
|
+
choose();
|
|
82
|
+
return state.provider;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Valor para `wallet_source` cuando la sesión se inicia con una billetera inyectada:
|
|
86
|
+
* `eip6963:<rdns>` si llegó por anuncio, `window.ethereum` si es el objeto clásico y
|
|
87
|
+
* `unknown` si todavía no hay proveedor.
|
|
88
|
+
*/
|
|
89
|
+
export function externalWalletSource() {
|
|
90
|
+
start();
|
|
91
|
+
choose();
|
|
92
|
+
if (state.source === 'eip6963')
|
|
93
|
+
return state.rdns ? `eip6963:${state.rdns}` : 'eip6963:unknown';
|
|
94
|
+
if (state.source === 'window.ethereum')
|
|
95
|
+
return 'window.ethereum';
|
|
96
|
+
return 'unknown';
|
|
97
|
+
}
|
|
98
|
+
export function getAnnouncedProviders() {
|
|
99
|
+
start();
|
|
100
|
+
return state.announced;
|
|
101
|
+
}
|
|
102
|
+
/** Test-only: forgets the listeners and the chosen provider. */
|
|
103
|
+
export function resetExternalProviderForTests() {
|
|
104
|
+
state = EMPTY;
|
|
105
|
+
started = false;
|
|
106
|
+
listeners.clear();
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=external-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-provider.js","sourceRoot":"","sources":["../../src/wallet/external-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-provider.test.d.ts","sourceRoot":"","sources":["../../src/wallet/external-provider.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { externalWalletSource, getAnnouncedProviders, getExternalProvider, resetExternalProviderForTests, } from './external-provider.js';
|
|
4
|
+
const provider = () => ({ request: async () => null });
|
|
5
|
+
function announce(p, info) {
|
|
6
|
+
window.dispatchEvent(new CustomEvent('eip6963:announceProvider', {
|
|
7
|
+
detail: { info: { uuid: info.rdns, ...info }, provider: p },
|
|
8
|
+
}));
|
|
9
|
+
}
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
vi.useFakeTimers();
|
|
12
|
+
delete window.ethereum;
|
|
13
|
+
resetExternalProviderForTests();
|
|
14
|
+
});
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
vi.useRealTimers();
|
|
17
|
+
delete window.ethereum;
|
|
18
|
+
});
|
|
19
|
+
describe('external-provider (EIP-6963)', () => {
|
|
20
|
+
it('prefers window.ethereum when it exists', () => {
|
|
21
|
+
const injected = provider();
|
|
22
|
+
window.ethereum = injected;
|
|
23
|
+
resetExternalProviderForTests();
|
|
24
|
+
expect(getExternalProvider()).toBe(injected);
|
|
25
|
+
expect(externalWalletSource()).toBe('window.ethereum');
|
|
26
|
+
});
|
|
27
|
+
it('resolves a late EIP-6963 announcement when there is no window.ethereum', () => {
|
|
28
|
+
const announced = provider();
|
|
29
|
+
expect(getExternalProvider()).toBeNull();
|
|
30
|
+
announce(announced, { name: 'Rabby', rdns: 'io.rabby' });
|
|
31
|
+
expect(getExternalProvider()).toBe(announced);
|
|
32
|
+
expect(externalWalletSource()).toBe('eip6963:io.rabby');
|
|
33
|
+
expect(getAnnouncedProviders().map((item) => item.rdns)).toContain('io.rabby');
|
|
34
|
+
});
|
|
35
|
+
it('stays on the first provider (the choice is sticky)', () => {
|
|
36
|
+
const first = provider();
|
|
37
|
+
const second = provider();
|
|
38
|
+
getExternalProvider();
|
|
39
|
+
announce(first, { name: 'One', rdns: 'one' });
|
|
40
|
+
announce(second, { name: 'Two', rdns: 'two' });
|
|
41
|
+
expect(getExternalProvider()).toBe(first);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=external-provider.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-provider.test.js","sourceRoot":"","sources":["../../src/wallet/external-provider.test.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AACxE,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,6BAA6B,GAC9B,MAAM,wBAAwB,CAAA;AAG/B,MAAM,QAAQ,GAAG,GAAoB,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAA;AAEvE,SAAS,QAAQ,CAAC,CAAkB,EAAE,IAAoC;IACxE,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,0BAA0B,EAAE;QAC1C,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE;KAC5D,CAAC,CACH,CAAA;AACH,CAAC;AAED,UAAU,CAAC,GAAG,EAAE;IACd,EAAE,CAAC,aAAa,EAAE,CAAA;IAClB,OAAQ,MAAiC,CAAC,QAAQ,CAAA;IAClD,6BAA6B,EAAE,CAAA;AACjC,CAAC,CAAC,CAAA;AAEF,SAAS,CAAC,GAAG,EAAE;IACb,EAAE,CAAC,aAAa,EAAE,CAAA;IAClB,OAAQ,MAAiC,CAAC,QAAQ,CAAA;AACpD,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAC1B;QAAC,MAAyC,CAAC,QAAQ,GAAG,QAAQ,CAAA;QAC/D,6BAA6B,EAAE,CAAA;QAC/B,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC5C,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,MAAM,SAAS,GAAG,QAAQ,EAAE,CAAA;QAC5B,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAA;QACxC,QAAQ,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAA;QAExD,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC7C,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;QACvD,MAAM,CAAC,qBAAqB,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;IAChF,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;QACxB,MAAM,MAAM,GAAG,QAAQ,EAAE,CAAA;QACzB,mBAAmB,EAAE,CAAA;QACrB,QAAQ,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAC7C,QAAQ,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAC9C,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { createWallet, importWallet, unlockWallet, lockWallet, deleteWallet, currentLockEpoch, hasWallet, getWalletInfo, setWalletChain, isValidPassword, enableBiometricUnlock, hasBiometricUnlock, unlockWithBiometric, disableBiometricUnlock, exportMnemonic, exportPrivateKey, isUnlocked, getUnlockedAccount, getUnlockedInfo, signMessage, signTypedData, signTransaction, } from './wallet.js';
|
|
2
|
+
export { signSIWE } from './siwe.js';
|
|
3
|
+
export { addressFromMnemonic, accountFromMnemonic, accountFromPrivateKey, assertValidMnemonic, isValidMnemonic, newMnemonic, normalizeMnemonic, privateKeyFromMnemonic, keccak, type PrivateKey, } from './signer.js';
|
|
4
|
+
export { encryptSecret, decryptSecret, sha256, toBase64, fromBase64, wipe, KDF_ITERATIONS, KDF_ITERATIONS_FLOOR, KDF_ITERATIONS_CEILING, KDF_BUDGET_MS, calibrateIterations, normalizePassword, type EncryptedSecret, } from './crypto.js';
|
|
5
|
+
export { detectPlatformSupport, createPrfCredential, evaluatePrf, deriveWrappingKey, setRpName, USER_VERIFICATION_GRACE_MS, markUserVerified, clearUserVerification, hasRecentUserVerification, signalUnknownCredential, isUserCancelledError, type PlatformSupport, type PrfCredential, } from './web-authn.js';
|
|
6
|
+
export { type BiometricRecord, readBiometricRecord, writeBiometricRecord, deleteBiometricRecord, forgetBiometricCredential, sealWithPrfSecret, unsealWithPrfSecret, } from './biometric.js';
|
|
7
|
+
export { getInAppWalletProvider, extractDestination, requireFundsConfirmation, emitAccountsChanged, type ProviderOptions, } from './provider.js';
|
|
8
|
+
export { isKnownDestination, rememberDestination, clearDestinations, setDestinationsPrefix, } from './destinations.js';
|
|
9
|
+
export { getExternalProvider, externalWalletSource, getAnnouncedProviders, subscribeExternalProvider, getExternalProviderSnapshot, resetExternalProviderForTests, type AnnouncedProvider, type ExternalProviderState, type ExternalProviderSource, } from './external-provider.js';
|
|
10
|
+
export { MemoryStorage } from './storage/memory.js';
|
|
11
|
+
export { IndexedDBStorage } from './storage/indexeddb.js';
|
|
12
|
+
export { setWalletDbName, getWalletDbName, DB_NAME } from './storage/idb.js';
|
|
13
|
+
export { CHAIN_IDS, DEFAULT_CHAIN, type ChainName, type CreateWalletOptions, type ImportWalletOptions, type StorageAdapter, type StoredWallet, type WalletInfo, type Eip1193Provider, type Eip1193RequestArgs, } from './types.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/wallet/index.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEpC,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,sBAAsB,EACtB,MAAM,EACN,KAAK,UAAU,GAChB,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,aAAa,EACb,aAAa,EACb,MAAM,EACN,QAAQ,EACR,UAAU,EACV,IAAI,EACJ,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAA;AAGpB,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,SAAS,EACT,0BAA0B,EAC1B,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACL,KAAK,eAAe,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,mBAAmB,EACnB,KAAK,eAAe,GACrB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAE5E,OAAO,EACL,SAAS,EACT,aAAa,EACb,KAAK,SAAS,EACd,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// @pasosdejesus/m/wallet — núcleo compartido de billetera (`m/REQ/14`).
|
|
2
|
+
//
|
|
3
|
+
// Sin React y sin Kysely: mnemónica (BIP39), derivación, firma, cifrado en reposo
|
|
4
|
+
// (PBKDF2 + AES-GCM), almacenamiento intercambiable, estado de la billetera in-app,
|
|
5
|
+
// provider EIP-1193, verificación del usuario (WebAuthn L1/L2), destinos y el
|
|
6
|
+
// resolutor del proveedor inyectado (EIP-6963). Lo usan el CLI de `m` y los
|
|
7
|
+
// consumidores (learn.tg, sivel3, stable-sl).
|
|
8
|
+
export { createWallet, importWallet, unlockWallet, lockWallet, deleteWallet, currentLockEpoch, hasWallet, getWalletInfo, setWalletChain, isValidPassword, enableBiometricUnlock, hasBiometricUnlock, unlockWithBiometric, disableBiometricUnlock, exportMnemonic, exportPrivateKey, isUnlocked, getUnlockedAccount, getUnlockedInfo, signMessage, signTypedData, signTransaction, } from './wallet.js';
|
|
9
|
+
export { signSIWE } from './siwe.js';
|
|
10
|
+
export { addressFromMnemonic, accountFromMnemonic, accountFromPrivateKey, assertValidMnemonic, isValidMnemonic, newMnemonic, normalizeMnemonic, privateKeyFromMnemonic, keccak, } from './signer.js';
|
|
11
|
+
export { encryptSecret, decryptSecret, sha256, toBase64, fromBase64, wipe, KDF_ITERATIONS, KDF_ITERATIONS_FLOOR, KDF_ITERATIONS_CEILING, KDF_BUDGET_MS, calibrateIterations, normalizePassword, } from './crypto.js';
|
|
12
|
+
// Capa L1/L2: gesto WebAuthn y sello con el secreto PRF.
|
|
13
|
+
export { detectPlatformSupport, createPrfCredential, evaluatePrf, deriveWrappingKey, setRpName, USER_VERIFICATION_GRACE_MS, markUserVerified, clearUserVerification, hasRecentUserVerification, signalUnknownCredential, isUserCancelledError, } from './web-authn.js';
|
|
14
|
+
export { readBiometricRecord, writeBiometricRecord, deleteBiometricRecord, forgetBiometricCredential, sealWithPrfSecret, unsealWithPrfSecret, } from './biometric.js';
|
|
15
|
+
// Provider EIP-1193 de la billetera in-app y destinos conocidos.
|
|
16
|
+
export { getInAppWalletProvider, extractDestination, requireFundsConfirmation, emitAccountsChanged, } from './provider.js';
|
|
17
|
+
export { isKnownDestination, rememberDestination, clearDestinations, setDestinationsPrefix, } from './destinations.js';
|
|
18
|
+
// Resolutor del proveedor inyectado (EIP-6963) — graduado de learn.tg.
|
|
19
|
+
export { getExternalProvider, externalWalletSource, getAnnouncedProviders, subscribeExternalProvider, getExternalProviderSnapshot, resetExternalProviderForTests, } from './external-provider.js';
|
|
20
|
+
export { MemoryStorage } from './storage/memory.js';
|
|
21
|
+
export { IndexedDBStorage } from './storage/indexeddb.js';
|
|
22
|
+
export { setWalletDbName, getWalletDbName, DB_NAME } from './storage/idb.js';
|
|
23
|
+
export { CHAIN_IDS, DEFAULT_CHAIN, } from './types.js';
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/wallet/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,EAAE;AACF,kFAAkF;AAClF,oFAAoF;AACpF,8EAA8E;AAC9E,4EAA4E;AAC5E,8CAA8C;AAC9C,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEpC,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,sBAAsB,EACtB,MAAM,GAEP,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,aAAa,EACb,aAAa,EACb,MAAM,EACN,QAAQ,EACR,UAAU,EACV,IAAI,EACJ,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,GAElB,MAAM,aAAa,CAAA;AAEpB,yDAAyD;AACzD,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,SAAS,EACT,0BAA0B,EAC1B,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,oBAAoB,GAGrB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAEL,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,gBAAgB,CAAA;AAEvB,iEAAiE;AACjE,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,mBAAmB,GAEpB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,mBAAmB,CAAA;AAE1B,uEAAuE;AACvE,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,GAI9B,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAE5E,OAAO,EACL,SAAS,EACT,aAAa,GASd,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexeddb.test.d.ts","sourceRoot":"","sources":["../../src/wallet/indexeddb.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { beforeAll, describe, expect, it } from 'vitest';
|
|
2
|
+
import { installIndexedDB } from '../test-utils/wallet-mocks.js';
|
|
3
|
+
import { IndexedDBStorage } from './storage/indexeddb.js';
|
|
4
|
+
const record = {
|
|
5
|
+
version: 1,
|
|
6
|
+
address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
|
|
7
|
+
chain: 'celoSepolia',
|
|
8
|
+
createdAt: 1,
|
|
9
|
+
kdf: { name: 'PBKDF2', hash: 'SHA-256', iterations: 600_000, salt: 'AA==' },
|
|
10
|
+
cipher: { name: 'AES-GCM', iv: 'BB==', data: 'CC==' },
|
|
11
|
+
};
|
|
12
|
+
beforeAll(async () => {
|
|
13
|
+
await installIndexedDB();
|
|
14
|
+
});
|
|
15
|
+
describe('IndexedDBStorage', () => {
|
|
16
|
+
it('stores, reads and deletes the encrypted record', async () => {
|
|
17
|
+
const storage = new IndexedDBStorage();
|
|
18
|
+
await storage.delete();
|
|
19
|
+
expect(await storage.has()).toBe(false);
|
|
20
|
+
expect(await storage.get()).toBeNull();
|
|
21
|
+
await storage.set(record);
|
|
22
|
+
expect(await storage.has()).toBe(true);
|
|
23
|
+
expect(await storage.get()).toEqual(record);
|
|
24
|
+
await storage.delete();
|
|
25
|
+
expect(await storage.has()).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=indexeddb.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexeddb.test.js","sourceRoot":"","sources":["../../src/wallet/indexeddb.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAGzD,MAAM,MAAM,GAAiB;IAC3B,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,4CAA4C;IACrD,KAAK,EAAE,aAAa;IACpB,SAAS,EAAE,CAAC;IACZ,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;IAC3E,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;CACtD,CAAA;AAED,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,gBAAgB,EAAE,CAAA;AAC1B,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,OAAO,GAAG,IAAI,gBAAgB,EAAE,CAAA;QACtC,MAAM,OAAO,CAAC,MAAM,EAAE,CAAA;QAEtB,MAAM,CAAC,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACvC,MAAM,CAAC,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAA;QAEtC,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACzB,MAAM,CAAC,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACtC,MAAM,CAAC,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAE3C,MAAM,OAAO,CAAC,MAAM,EAAE,CAAA;QACtB,MAAM,CAAC,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kdf.test.d.ts","sourceRoot":"","sources":["../../src/wallet/kdf.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { KDF_ITERATIONS_CEILING, KDF_ITERATIONS_FLOOR, calibrateIterations, decryptSecret, encryptSecret, normalizePassword, } from './crypto.js';
|
|
3
|
+
describe('password normalization (R-#251)', () => {
|
|
4
|
+
it('trims and applies NFKD', () => {
|
|
5
|
+
expect(normalizePassword(' correct horse ')).toBe('correct horse');
|
|
6
|
+
expect(normalizePassword('café')).toBe('cafe\u0301');
|
|
7
|
+
expect(normalizePassword('clave')).toBe('clave');
|
|
8
|
+
});
|
|
9
|
+
it('is idempotent', () => {
|
|
10
|
+
const once = normalizePassword(' ñandú ');
|
|
11
|
+
expect(normalizePassword(once)).toBe(once);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
describe('KDF calibration (R-#251)', () => {
|
|
15
|
+
it('never goes below the historical floor', async () => {
|
|
16
|
+
const slow = async () => 5000;
|
|
17
|
+
expect(await calibrateIterations(slow, 400)).toBe(KDF_ITERATIONS_FLOOR);
|
|
18
|
+
});
|
|
19
|
+
it('scales the count up to the budget on a fast device', async () => {
|
|
20
|
+
const fast = async () => 100;
|
|
21
|
+
expect(await calibrateIterations(fast, 400)).toBe(KDF_ITERATIONS_FLOOR * 4);
|
|
22
|
+
});
|
|
23
|
+
it('clamps at the ceiling so a slow phone cannot hang', async () => {
|
|
24
|
+
const instant = async () => 0.01;
|
|
25
|
+
expect(await calibrateIterations(instant, 400)).toBe(KDF_ITERATIONS_CEILING);
|
|
26
|
+
});
|
|
27
|
+
it('falls back to the floor when the measurement fails', async () => {
|
|
28
|
+
const broken = async () => { throw new Error('no crypto'); };
|
|
29
|
+
expect(await calibrateIterations(broken)).toBe(KDF_ITERATIONS_FLOOR);
|
|
30
|
+
const nonsense = async () => 0;
|
|
31
|
+
expect(await calibrateIterations(nonsense)).toBe(KDF_ITERATIONS_FLOOR);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe('record work factor (R-#251)', () => {
|
|
35
|
+
it('stores the iteration count it was asked for', async () => {
|
|
36
|
+
const secret = await encryptSecret('{"v":1}', 'clave-de-prueba', 1234);
|
|
37
|
+
expect(secret.kdf.iterations).toBe(1234);
|
|
38
|
+
expect(await decryptSecret(secret, 'clave-de-prueba')).toBe('{"v":1}');
|
|
39
|
+
});
|
|
40
|
+
it('uses the historical count by default', async () => {
|
|
41
|
+
const secret = await encryptSecret('{"v":1}', 'clave-de-prueba');
|
|
42
|
+
expect(secret.kdf.iterations).toBe(KDF_ITERATIONS_FLOOR);
|
|
43
|
+
});
|
|
44
|
+
it('opens a record whose password was written with spaces or accents', async () => {
|
|
45
|
+
const secret = await encryptSecret('{"v":1}', 'café con leche');
|
|
46
|
+
expect(await decryptSecret(secret, ' café con leche ')).toBe('{"v":1}');
|
|
47
|
+
expect(await decryptSecret(secret, 'cafe\u0301 con leche')).toBe('{"v":1}');
|
|
48
|
+
});
|
|
49
|
+
it('still rejects a wrong password', async () => {
|
|
50
|
+
const secret = await encryptSecret('{"v":1}', 'clave-de-prueba');
|
|
51
|
+
await expect(decryptSecret(secret, 'otra-clave')).rejects.toThrow(/Wrong password/);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=kdf.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kdf.test.js","sourceRoot":"","sources":["../../src/wallet/kdf.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Eip1193Provider, type StorageAdapter } from './types.js';
|
|
2
|
+
/** Dapps that subscribed: the wallet left the session (lock or delete). */
|
|
3
|
+
export declare function emitAccountsChanged(accounts: string[]): void;
|
|
4
|
+
export interface ProviderOptions {
|
|
5
|
+
rpcUrl?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Layer L1 of https://github.com/pasosdeJesus/learn.tg/issues/246: before an
|
|
8
|
+
* `eth_sendTransaction` (money leaving the wallet), ask the device to verify the
|
|
9
|
+
* user. On by default when a passkey is enrolled; set to `false` in tests.
|
|
10
|
+
*/
|
|
11
|
+
requireUserVerification?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Wallet storage, so `wallet_switchEthereumChain` can persist the network it
|
|
14
|
+
* changes to. Defaults to the browser one (IndexedDB), the same store the app
|
|
15
|
+
* unlocks the wallet from.
|
|
16
|
+
*/
|
|
17
|
+
storage?: StorageAdapter;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Recipient of a transfer (R-#253): `tx.to` for a native transfer, or the address
|
|
21
|
+
* argument of an ERC-20 `transfer(address,uint256)` / `transferFrom(address,address,uint256)`
|
|
22
|
+
* (that is where USDT/G$/XAUT put the recipient; `to` is the token contract).
|
|
23
|
+
*/
|
|
24
|
+
export declare function extractDestination(tx: Record<string, unknown>): string | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Fresh user-verified assertion before moving funds (L1). Silently allows the
|
|
27
|
+
* request on devices without a platform authenticator — no passkey enrolled, or a
|
|
28
|
+
* wallet WebView without WebAuthn: L1 needs hardware and must not block the
|
|
29
|
+
* wallet. A cancelled prompt is a rejection (`4001`), like any wallet.
|
|
30
|
+
*
|
|
31
|
+
* R-#253: `destination` (when known) decides whether the grace window applies. A
|
|
32
|
+
* **new** destination always asks for the gesture.
|
|
33
|
+
*/
|
|
34
|
+
export declare function requireFundsConfirmation({ destination }?: {
|
|
35
|
+
destination?: string;
|
|
36
|
+
}): Promise<void>;
|
|
37
|
+
export declare function getInAppWalletProvider(options?: ProviderOptions): Eip1193Provider | null;
|
|
38
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/wallet/provider.ts"],"names":[],"mappings":"AAIA,OAAO,EAA6B,KAAK,eAAe,EAA2B,KAAK,cAAc,EAAmB,MAAM,YAAY,CAAA;AA2B3I,2EAA2E;AAC3E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAG5D;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,cAAc,CAAA;CACzB;AAsBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAalF;AAED;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,EAAE,WAAW,EAAE,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,OAAO,CAAC,IAAI,CAAC,CAmBf;AAkFD,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,eAAoB,GAAG,eAAe,GAAG,IAAI,CA2I5F"}
|