@provex/extension-react 1.11.0 → 2.0.0-rc.20261103015524.5c1d822
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -123
- package/dist/ZKTLSContext.cjs +7 -75
- package/dist/ZKTLSContext.cjs.map +1 -1
- package/dist/ZKTLSContext.d.cts +1 -15
- package/dist/ZKTLSContext.d.ts +1 -15
- package/dist/ZKTLSContext.js +2 -2
- package/dist/adapters/extensionEnclave.cjs.map +1 -1
- package/dist/adapters/extensionEnclave.js +1 -1
- package/dist/capability.cjs +50 -0
- package/dist/capability.cjs.map +1 -0
- package/dist/capability.d.cts +95 -0
- package/dist/capability.d.ts +95 -0
- package/dist/capability.js +3 -0
- package/dist/capability.js.map +1 -0
- package/dist/{chunk-T42E7EM7.js → chunk-B7RU2WKQ.js} +3 -3
- package/dist/{chunk-T42E7EM7.js.map → chunk-B7RU2WKQ.js.map} +1 -1
- package/dist/chunk-JMVW4H4H.js +44 -0
- package/dist/chunk-JMVW4H4H.js.map +1 -0
- package/dist/chunk-JU2T2TGY.js +123 -0
- package/dist/chunk-JU2T2TGY.js.map +1 -0
- package/dist/chunk-VQFWUZNJ.js +59 -0
- package/dist/chunk-VQFWUZNJ.js.map +1 -0
- package/dist/{chunk-AMJXMSDV.js → chunk-WSLUOLBW.js} +2 -2
- package/dist/chunk-WSLUOLBW.js.map +1 -0
- package/dist/index.cjs +101 -187
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +5 -3
- package/dist/useProofCapability.cjs +104 -0
- package/dist/useProofCapability.cjs.map +1 -0
- package/dist/useProofCapability.d.cts +27 -0
- package/dist/useProofCapability.d.ts +27 -0
- package/dist/useProofCapability.js +4 -0
- package/dist/useProofCapability.js.map +1 -0
- package/dist/useZKTLS.cjs +7 -195
- package/dist/useZKTLS.cjs.map +1 -1
- package/dist/useZKTLS.d.cts +10 -230
- package/dist/useZKTLS.d.ts +10 -230
- package/dist/useZKTLS.js +1 -1
- package/dist/useZKTLSContext.cjs +0 -5
- package/dist/useZKTLSContext.cjs.map +1 -1
- package/dist/useZKTLSContext.d.cts +0 -2
- package/dist/useZKTLSContext.d.ts +0 -2
- package/dist/useZKTLSContext.js +2 -2
- package/package.json +15 -4
- package/skills/extension-react-integration/SKILL.md +16 -73
- package/dist/chunk-AMJXMSDV.js.map +0 -1
- package/dist/chunk-TAS2MB4S.js +0 -301
- package/dist/chunk-TAS2MB4S.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ React hooks and context providers for integrating with the ZKTLS (Zero-Knowledge
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
This package provides React components and hooks that enable web applications to communicate with the ZKTLS browser extension for
|
|
7
|
+
This package provides React components and hooks that enable web applications to communicate with the ZKTLS browser extension for capturing a buyer's payment session. It handles the bridge between your React application and the browser extension, allowing users to prove they made payments through traditional payment providers without revealing sensitive account information.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
@@ -21,7 +21,7 @@ import { ZKTLSProvider } from '@provex/extension-react'
|
|
|
21
21
|
|
|
22
22
|
function App() {
|
|
23
23
|
return (
|
|
24
|
-
<ZKTLSProvider
|
|
24
|
+
<ZKTLSProvider>
|
|
25
25
|
<YourApp />
|
|
26
26
|
</ZKTLSProvider>
|
|
27
27
|
)
|
|
@@ -33,12 +33,12 @@ function App() {
|
|
|
33
33
|
```typescript
|
|
34
34
|
import { useZKTLSContext } from '@provex/extension-react'
|
|
35
35
|
|
|
36
|
-
function
|
|
36
|
+
function PaymentCaptureComponent() {
|
|
37
37
|
const zktls = useZKTLSContext()
|
|
38
38
|
|
|
39
|
-
const
|
|
39
|
+
const handleCapture = async () => {
|
|
40
40
|
if (!zktls.isInitialized) {
|
|
41
|
-
console.log('
|
|
41
|
+
console.log('Peer extension not ready')
|
|
42
42
|
return
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -46,31 +46,20 @@ function PaymentProofComponent() {
|
|
|
46
46
|
// Request connection to extension
|
|
47
47
|
await zktls.requestConnection()
|
|
48
48
|
|
|
49
|
-
//
|
|
50
|
-
const
|
|
49
|
+
// Capture the bank session for the buyer trusted-execution attestation
|
|
50
|
+
const response = await zktls.authenticate({
|
|
51
51
|
actionType: 'transfer_venmo',
|
|
52
|
-
platform: 'venmo'
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
// Generate cryptographic proof
|
|
56
|
-
const proofs = await zktls.generateProofSeries({
|
|
57
52
|
platform: 'venmo',
|
|
58
|
-
|
|
59
|
-
intentHash: '0x1234...',
|
|
60
|
-
originalIndex: 0
|
|
53
|
+
captureMode: 'buyerTee'
|
|
61
54
|
})
|
|
62
55
|
|
|
63
|
-
console.log('
|
|
56
|
+
console.log('Transactions:', response.metadata)
|
|
64
57
|
} catch (error) {
|
|
65
|
-
console.error('
|
|
58
|
+
console.error('Capture failed:', error)
|
|
66
59
|
}
|
|
67
60
|
}
|
|
68
61
|
|
|
69
|
-
return
|
|
70
|
-
<button onClick={handleGenerateProof}>
|
|
71
|
-
Generate Payment Proof
|
|
72
|
-
</button>
|
|
73
|
-
)
|
|
62
|
+
return <button onClick={handleCapture}>Capture payment</button>
|
|
74
63
|
}
|
|
75
64
|
```
|
|
76
65
|
|
|
@@ -86,16 +75,8 @@ The main hook that provides all ZKTLS functionality. Returns an object with the
|
|
|
86
75
|
- `checkConnectionStatus(): Promise<Status>` - Check current connection status
|
|
87
76
|
- `getVersion(): Promise<string>` - Get extension version
|
|
88
77
|
|
|
89
|
-
#### Authentication
|
|
90
|
-
- `authenticate(inputs: AuthenticationInputs): Promise<MetadataMessageResponse>` - Authenticate with a payment provider
|
|
91
|
-
- `generateProof(inputs: HexIntentGenerateProofInputs): Promise<GenerateProofResponse>` - Generate a single proof
|
|
92
|
-
- `generateProofSeries(inputs, mutations): Promise<NotaryRequest[]>` - Generate multiple proofs for complex verification
|
|
93
|
-
- `waitForProof(proofId: string): Promise<NotaryRequest>` - Wait for proof generation to complete
|
|
94
|
-
|
|
95
|
-
#### Proof Management
|
|
96
|
-
- `fetchProofById(proofId: string): Promise<NotaryRequest | null>` - Fetch a specific proof
|
|
97
|
-
- `fetchProofs(): Promise<FetchProofsResponse>` - Fetch all generated proofs
|
|
98
|
-
- `fetchGeneratedProofs(responses: GenerateProofResponse[]): Promise<NotaryRequest[]>` - Fetch multiple proofs by their responses
|
|
78
|
+
#### Authentication
|
|
79
|
+
- `authenticate(inputs: AuthenticationInputs): Promise<MetadataMessageResponse>` - Authenticate with a payment provider and capture the session
|
|
99
80
|
|
|
100
81
|
#### Extension Integration
|
|
101
82
|
- `openSidebar(route: string): Promise<void>` - Open the extension sidebar
|
|
@@ -107,7 +88,6 @@ React context provider that makes ZKTLS functionality available to child compone
|
|
|
107
88
|
|
|
108
89
|
**Props:**
|
|
109
90
|
- `children: ReactNode` - Child components
|
|
110
|
-
- `fallbackComponent?: ReactNode` - Component to show while ZKTLS is initializing
|
|
111
91
|
|
|
112
92
|
### `useZKTLSContext()` Hook
|
|
113
93
|
|
|
@@ -117,40 +97,8 @@ Hook to access the ZKTLS context within components. Must be used within a `ZKTLS
|
|
|
117
97
|
|
|
118
98
|
**Throws:** Error if used outside of `ZKTLSProvider`
|
|
119
99
|
|
|
120
|
-
## Supported Payment Providers
|
|
121
|
-
|
|
122
|
-
The extension supports proof generation for the following payment providers:
|
|
123
|
-
|
|
124
|
-
- **Venmo** - Single proof generation
|
|
125
|
-
- **Zelle** - Multiple proof generation (supports Chase, Bank of America, Citi sub-providers)
|
|
126
|
-
- **CashApp** - Single proof generation
|
|
127
|
-
- **Revolut** - Single proof generation
|
|
128
|
-
- **Wise** - Single proof generation
|
|
129
|
-
- **MercadoPago** - Single proof generation
|
|
130
|
-
|
|
131
100
|
## Advanced Usage
|
|
132
101
|
|
|
133
|
-
### Progress Tracking for Proof Series
|
|
134
|
-
|
|
135
|
-
```typescript
|
|
136
|
-
const generateProofWithProgress = async () => {
|
|
137
|
-
await zktls.generateProofSeries(
|
|
138
|
-
{
|
|
139
|
-
platform: 'chase',
|
|
140
|
-
provider: 'zelle',
|
|
141
|
-
intentHash: '0x1234...',
|
|
142
|
-
originalIndex: 0
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
progress: ({ progress, step, id, total }) => {
|
|
146
|
-
console.log(`Step ${step + 1}/${total}: ${progress}`)
|
|
147
|
-
if (id) console.log(`Proof ID: ${id}`)
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
)
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
102
|
### Metadata Message Handling
|
|
155
103
|
|
|
156
104
|
```typescript
|
|
@@ -165,61 +113,14 @@ useEffect(() => {
|
|
|
165
113
|
}, [zktls])
|
|
166
114
|
```
|
|
167
115
|
|
|
168
|
-
### Finding Matching Payment Metadata
|
|
169
|
-
|
|
170
|
-
```typescript
|
|
171
|
-
import { findMetadataMessage } from '@provex/extension-react'
|
|
172
|
-
|
|
173
|
-
const matchingMessage = findMetadataMessage({
|
|
174
|
-
metadata: paymentMetadata,
|
|
175
|
-
intent: userIntent,
|
|
176
|
-
token: tokenInfo
|
|
177
|
-
})
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## Proof Encoding Utilities
|
|
181
|
-
|
|
182
|
-
The package includes utilities for encoding proofs for blockchain submission:
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
import {
|
|
186
|
-
encodeProofAsBytes,
|
|
187
|
-
encodeTwoProofs,
|
|
188
|
-
encodeProof
|
|
189
|
-
} from '@provex/extension-react'
|
|
190
|
-
|
|
191
|
-
// Encode single proof
|
|
192
|
-
const encodedProof = encodeProofAsBytes(reclaimProof)
|
|
193
|
-
|
|
194
|
-
// Encode multiple proofs (for Zelle/Chase)
|
|
195
|
-
const encodedProofs = encodeTwoProofs(proof1, proof2)
|
|
196
|
-
|
|
197
|
-
// High-level encoding based on provider
|
|
198
|
-
const encoded = encodeProof({
|
|
199
|
-
extensionProofs: notarizedProofs,
|
|
200
|
-
subProvider: 'chase',
|
|
201
|
-
provider: 'zelle'
|
|
202
|
-
})
|
|
203
|
-
```
|
|
204
|
-
|
|
205
116
|
## Error Handling
|
|
206
117
|
|
|
207
|
-
Always wrap
|
|
118
|
+
Always wrap extension calls in try-catch blocks. A capture that fails sets `errorMessage` on the response.
|
|
208
119
|
|
|
209
120
|
```typescript
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
// Handle success
|
|
214
|
-
} catch (error) {
|
|
215
|
-
if (error.message.includes('failed')) {
|
|
216
|
-
// Handle proof generation failure
|
|
217
|
-
} else if (error.message.includes('cancelled')) {
|
|
218
|
-
// Handle user cancellation
|
|
219
|
-
} else {
|
|
220
|
-
// Handle other errors
|
|
221
|
-
}
|
|
222
|
-
}
|
|
121
|
+
const response = await zktls.authenticate(inputs)
|
|
122
|
+
if (response.errorMessage) {
|
|
123
|
+
// Handle a capture failure
|
|
223
124
|
}
|
|
224
125
|
```
|
|
225
126
|
|
|
@@ -232,11 +133,7 @@ import type {
|
|
|
232
133
|
Status,
|
|
233
134
|
MetadataMessage,
|
|
234
135
|
MetadataMessageResponse,
|
|
235
|
-
|
|
236
|
-
GenerateProofResponse,
|
|
237
|
-
AuthenticationInputs,
|
|
238
|
-
NotaryRequest,
|
|
239
|
-
ReclaimProof
|
|
136
|
+
AuthenticationInputs
|
|
240
137
|
} from '@provex/extension-react'
|
|
241
138
|
```
|
|
242
139
|
|
|
@@ -254,11 +151,14 @@ This package requires users to have the ZKTLS browser extension installed. The e
|
|
|
254
151
|
|
|
255
152
|
- All sensitive operations are handled by the browser extension
|
|
256
153
|
- No private keys or sensitive data are exposed to the web application
|
|
257
|
-
-
|
|
258
|
-
- All proof generation happens locally in the user's browser
|
|
154
|
+
- The bank session is encrypted in the browser toward the attestation enclave
|
|
259
155
|
|
|
260
156
|
## License
|
|
261
157
|
|
|
262
158
|
MIT — see `LICENSE` in this package.
|
|
263
159
|
|
|
264
160
|
> Versions `1.6.3` and later are licensed under MIT. Versions published before `1.6.3` carry the license they were originally published under.
|
|
161
|
+
|
|
162
|
+
## Breaking changes in the next major version
|
|
163
|
+
|
|
164
|
+
The Reclaim proof path is removed. These exports no longer exist: `generateProof`, `generateProofSeries`, `waitForProof`, `fetchProofById`, `fetchProofs`, `fetchGeneratedProofs`, `encodeProof`, `encodeProofAsBytes`, `encodeTwoProofs`, `encodeProofWithPaymentMethod`, `parseExtensionProof`, `byteArrayToHexString`, `PROOF_ENCODING`, `findMetadataMessage`, `buildBuyerTeeNotaryRequest`, and the types `ReclaimProof`, `NotaryRequest`, `NotarizedProof`, `GenerateProofInputs`, `GenerateProofResponse`, `FetchProofsResponse`. Use `createExtensionEnclaveAdapter` for capture.
|
package/dist/ZKTLSContext.cjs
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var react = require('react');
|
|
4
|
-
var viem = require('viem');
|
|
5
|
-
var time = require('@provex/utils/time');
|
|
6
|
-
var payment = require('@provex/utils/payment');
|
|
7
|
-
require('@provex/utils/conversionRates');
|
|
8
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
9
5
|
|
|
10
6
|
// src/ZKTLSContext.tsx
|
|
@@ -16,7 +12,6 @@ var buildOnrampQuery = (params) => {
|
|
|
16
12
|
});
|
|
17
13
|
return search.toString();
|
|
18
14
|
};
|
|
19
|
-
viem.parseAbiParameter("((string provider, string parameters, string context) claimInfo, ((bytes32 identifier, address owner, uint32 timestampS, uint32 epoch) claim, bytes[] signatures) signedClaim, bool isAppclipProof)");
|
|
20
15
|
var useZKTLS = () => {
|
|
21
16
|
const [isInitialized, setIsInitialized] = react.useState(false);
|
|
22
17
|
react.useEffect(() => {
|
|
@@ -34,36 +29,6 @@ var useZKTLS = () => {
|
|
|
34
29
|
}
|
|
35
30
|
}, []);
|
|
36
31
|
return react.useMemo(() => {
|
|
37
|
-
const fetchProofById = async (proofId) => {
|
|
38
|
-
const proof = await window.peer.fetchProofById(proofId);
|
|
39
|
-
if (proof && proof.notaryRequest) return proof.notaryRequest;
|
|
40
|
-
const proofs = await window.peer.fetchProofs();
|
|
41
|
-
const proofFromList = proofs.notaryRequests.find((p) => p.id === proofId);
|
|
42
|
-
if (proofFromList) return proofFromList;
|
|
43
|
-
return null;
|
|
44
|
-
};
|
|
45
|
-
const waitForProof = async (proofId, onCurrent) => {
|
|
46
|
-
let notaryRequest = null;
|
|
47
|
-
do {
|
|
48
|
-
notaryRequest = await fetchProofById(proofId);
|
|
49
|
-
onCurrent?.(notaryRequest);
|
|
50
|
-
await time.sleep(1e3);
|
|
51
|
-
} while (!notaryRequest || !notaryRequest.status || notaryRequest.status === "pending");
|
|
52
|
-
if (notaryRequest.status === "failed" || notaryRequest.status === "expired" || notaryRequest.status === "cancelled" || notaryRequest.status === "error") {
|
|
53
|
-
console.error("[waitForProof] proof terminal state:", JSON.stringify(notaryRequest, null, 2));
|
|
54
|
-
const req = notaryRequest;
|
|
55
|
-
const detail = req.errorMessage ?? req.error ?? req.message ?? notaryRequest.status;
|
|
56
|
-
throw new Error(`Proof generation failed: ${detail}`);
|
|
57
|
-
}
|
|
58
|
-
return notaryRequest;
|
|
59
|
-
};
|
|
60
|
-
const generateProof = async (inputs) => {
|
|
61
|
-
return await window.peer.generateProof({
|
|
62
|
-
proofIndex: 0,
|
|
63
|
-
...inputs,
|
|
64
|
-
intentHash: BigInt(inputs.intentHash).toString()
|
|
65
|
-
});
|
|
66
|
-
};
|
|
67
32
|
return {
|
|
68
33
|
/** check if the PeerAuth extension is initialized */
|
|
69
34
|
isInitialized,
|
|
@@ -100,54 +65,20 @@ var useZKTLS = () => {
|
|
|
100
65
|
return data;
|
|
101
66
|
});
|
|
102
67
|
},
|
|
103
|
-
/** generate a proof */
|
|
104
|
-
generateProof,
|
|
105
|
-
/** wait for a proof to be generated */
|
|
106
|
-
waitForProof,
|
|
107
|
-
/** generate a proof series */
|
|
108
|
-
generateProofSeries: async (inputs, { progress: progressCallback } = {}) => {
|
|
109
|
-
const { platform, provider, intentHash, originalIndex } = inputs;
|
|
110
|
-
const args = {
|
|
111
|
-
platform: provider,
|
|
112
|
-
originalIndex,
|
|
113
|
-
intentHash
|
|
114
|
-
};
|
|
115
|
-
const isChase = platform === payment.extensionPlatforms.CHASE;
|
|
116
|
-
const isZelle = provider === payment.providers.ZELLE;
|
|
117
|
-
const expectedTotal = isZelle && isChase ? 2 : 1;
|
|
118
|
-
progressCallback?.({ progress: 0 /* Generating */, step: 0, id: null, total: expectedTotal });
|
|
119
|
-
const genProofA = await generateProof({ ...args, proofIndex: 0 });
|
|
120
|
-
progressCallback?.({ progress: 1 /* Polling */, step: 0, id: genProofA.proofId, total: expectedTotal });
|
|
121
|
-
const proofA = await waitForProof(genProofA.proofId);
|
|
122
|
-
if (!isChase || !isZelle) {
|
|
123
|
-
progressCallback?.({ progress: 2 /* Complete */, step: null, id: null, total: expectedTotal });
|
|
124
|
-
return [proofA];
|
|
125
|
-
}
|
|
126
|
-
progressCallback?.({ progress: 0 /* Generating */, step: 1, id: null, total: expectedTotal });
|
|
127
|
-
const genProofB = await generateProof({ ...args, proofIndex: 1 });
|
|
128
|
-
progressCallback?.({ progress: 1 /* Polling */, step: 1, id: genProofB.proofId, total: expectedTotal });
|
|
129
|
-
const proofB = await waitForProof(genProofB.proofId);
|
|
130
|
-
progressCallback?.({ progress: 2 /* Complete */, step: null, id: null, total: expectedTotal });
|
|
131
|
-
return [proofA, proofB];
|
|
132
|
-
},
|
|
133
68
|
/** subscribe to metadata messages */
|
|
134
69
|
onMetadataMessage: (fn) => {
|
|
135
70
|
return window.peer.onMetadataMessage(fn);
|
|
136
71
|
},
|
|
137
|
-
/** fetch a proof by its id */
|
|
138
|
-
fetchProofById,
|
|
139
|
-
/** fetch generated proofs */
|
|
140
|
-
fetchGeneratedProofs: async (genProofResponses) => {
|
|
141
|
-
return await Promise.all(genProofResponses.map((r) => fetchProofById(r.proofId)));
|
|
142
|
-
},
|
|
143
|
-
/** fetch all proofs */
|
|
144
|
-
fetchProofs: async () => {
|
|
145
|
-
return await window.peer.fetchProofs();
|
|
146
|
-
},
|
|
147
72
|
/** open the PeerAuth sidebar */
|
|
148
73
|
openSidebar: async (route) => {
|
|
149
74
|
return await window.peer.openSidebar(route);
|
|
150
75
|
},
|
|
76
|
+
/* v8 ignore start -- @preserve
|
|
77
|
+
* Excluded from coverage on purpose: the extension's `window.peer.onramp`
|
|
78
|
+
* API is retired (the buyer flow verifies through the zkp2p enclave
|
|
79
|
+
* adapter instead) and no caller in this repository invokes
|
|
80
|
+
* supportsOnramp, onramp or getOnrampTransaction. Testing them would
|
|
81
|
+
* assert behaviour production never reaches. */
|
|
151
82
|
/** Whether the connected extension exposes the trusted-execution on-ramp. */
|
|
152
83
|
supportsOnramp: () => typeof window.peer?.onramp === "function",
|
|
153
84
|
/**
|
|
@@ -184,6 +115,7 @@ var useZKTLS = () => {
|
|
|
184
115
|
if (typeof window.peer?.getOnrampTransaction !== "function") return null;
|
|
185
116
|
return window.peer.getOnrampTransaction(intentHash);
|
|
186
117
|
}
|
|
118
|
+
/* v8 ignore stop -- @preserve */
|
|
187
119
|
};
|
|
188
120
|
}, [isInitialized]);
|
|
189
121
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/useZKTLS.ts","../src/ZKTLSContext.tsx"],"names":["parseAbiParameter","useState","useEffect","useMemo","sleep","extensionPlatforms","providers","createContext","useContext"],"mappings":"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","file":"ZKTLSContext.cjs","sourcesContent":["/**\n * @fileoverview React hook and utilities for PeerAuth browser extension integration.\n *\n * The PeerAuth extension (formerly ZK-TLS) provides secure proof generation\n * for off-chain payment verification. This module provides:\n *\n * 1. Type definitions for extension API (window.peer)\n * 2. useZKTLS hook for React components\n * 3. Utility functions for transaction matching and proof encoding\n *\n * @remarks\n * The extension exposes `window.peer` (or deprecated `window.zktls`) for:\n * - Requesting connection (OAuth-like flow)\n * - Authenticating with payment providers\n * - Generating notarized proofs\n * - Fetching transaction metadata\n *\n * @see {@link ZKTLSContext} for the React context provider\n */\n\nimport { useEffect, useMemo, useState } from \"react\"\nimport { encodeAbiParameters, encodePacked, parseAbiParameter, parseUnits, type Hex } from \"viem\"\nimport { sleep } from \"@provex/utils/time\"\nimport type { IntentStruct } from \"@provex/utils/intent\"\nimport type { TokenInfo } from \"@provex/utils/tokens\"\nimport { extensionPlatforms, providers, subProviderConfigs, type ActionType, type PlatformKey, type ProviderKey, type SubProviderKey } from \"@provex/utils/payment\"\nimport { convertTokenInputToCurrency } from \"@provex/utils/conversionRates\"\n\ndeclare global {\n interface ZKTLS {\n requestConnection(): Promise<boolean>\n checkConnectionStatus(): Promise<Status>\n getVersion(): Promise<string>\n authenticate(inputs: AuthenticationInputs): Promise<void>\n generateProof(inputs: GenerateProofInputs): Promise<GenerateProofResponse>\n fetchProofById(proofId: string): Promise<ProofResponse>\n fetchProofs(): Promise<FetchProofsResponse>\n openSidebar(route: string): Promise<void>\n onMetadataMessage(fn: (data: MetadataMessageResponse) => void): () => void\n /**\n * Trusted-execution on-ramp (PeerAuth v3+). The extension opens the\n * buyer's bank in a new tab, intercepts the authenticated session, calls\n * the zkp2p trusted-execution attestation service, and returns\n * ready-to-send `fulfillIntent` calldata through the callback. Replaces\n * the retired `authenticate` + `generateProof` Reclaim path.\n *\n * Optional: older extension builds predate the on-ramp API, so guard\n * with a runtime presence check (`supportsOnramp`) before calling.\n *\n * @param queryString serialized on-ramp params (see {@link buildOnrampQuery})\n * @param callback invoked once the prepared transaction is ready\n */\n onramp?(\n queryString: string,\n callback: (result: PeerOnrampPreparedTransaction) => void,\n ): void\n /** Retrieve a previously prepared on-ramp transaction by intent hash. */\n getOnrampTransaction?(intentHash: string): Promise<PeerOnrampPreparedTransaction | null>\n }\n interface Window {\n /** @deprecated Use window.peer instead */\n zktls: ZKTLS | undefined\n /** PeerAuth extension API (replaces window.zktls) */\n peer: ZKTLS | undefined\n }\n}\n\n/** the status of the PeerAuth extension */\nexport type Status = 'connected' | 'disconnected' | 'pending'\n\n/** the individual metadata message sent by the PeerAuth extension */\nexport interface MetadataMessage {\n amount: number\n /** Currency code (e.g., 'USD', 'EUR') */\n currency?: string\n /**\n * Date of the transaction.\n * Can be a string in YYYYMMDD format, a number (YYYYMMDD or timestamp), or Date object.\n * The actual type depends on the extension implementation.\n */\n date: string | number | Date\n hidden: boolean\n originalIndex: number\n paymentId: number\n recipient: string\n}\n\n/** the response from the PeerAuth extension when a metadata message is received */\nexport interface MetadataMessageResponse {\n expiresAt: number\n platform: ProviderKey\n requestId: string\n metadata: MetadataMessage[]\n /**\n * Present only when `authenticate` was called with `captureMode: 'buyerTee'`.\n * Carries the bank session already encrypted toward the enclave — feed\n * `encryptedSessionMaterial` (plus the matched transaction's index) to the\n * trusted-execution verify endpoint. No `generateProof` call is involved.\n */\n buyerTeeCapture?: {\n encryptedSessionMaterial: string\n }\n /** Error surfaced by the extension during capture (e.g. missing platform). */\n errorMessage?: string\n}\n\n/** the response from the PeerAuth extension when fetching proofs */\nexport interface FetchProofsResponse {\n notaryRequests: NotaryRequest[]\n}\n\n/** the inputs for the generateProof function */\nexport type GenerateProofInputsAbstracted = {\n platform: PlatformKey\n provider: ProviderKey\n intentHash: Hex\n originalIndex: number\n}\n\n/** the inputs for the generateProof function */\nexport type GenerateProofInputs = {\n platform: ProviderKey\n originalIndex: number\n proofIndex?: number\n intentHash: string\n}\n\n/**\n * inputs for the generate proof function that requires the intent hash\n * as hex to ensure it can be converted to a bigint string accurately\n */\nexport type HexIntentGenerateProofInputs = Exclude<GenerateProofInputs, 'intentHash'> & { intentHash: Hex }\n\n/** the response from the PeerAuth extension when generating a proof */\nexport type GenerateProofResponse = {\n proofId: string\n platform: ProviderKey\n}\n\n/** the inputs for the authenticate function */\nexport type AuthenticationInputs = {\n actionType: ActionType\n platform: PlatformKey\n /**\n * Session capture mode. `'buyerTee'` makes the extension intercept the bank\n * session and return it encrypted toward the trusted-execution enclave in\n * `MetadataMessageResponse.buyerTeeCapture` — the replacement for the retired\n * Reclaim `generateProof` path. Omit for the legacy Reclaim flow. The\n * extension defaults the attestation service URL when this is set.\n */\n captureMode?: 'buyerTee' | 'sellerCredential'\n /**\n * Enclave the extension establishes the Buyer TEE session with and encrypts\n * the captured session material toward (zkp2p 0.6.0 spec §7). Pass explicitly\n * for newer providers — relying on the extension's built-in default is what\n * left non-Revolut rails with \"no buyerTee capture\".\n */\n attestationServiceUrl?: string\n /** Attestation action type; defaults to `actionType` when omitted (spec §2). */\n attestationActionType?: ActionType\n}\n\n/** the response from the PeerAuth extension when fetching a proof */\nexport interface Proof {\n claimInfo: ClaimInfo\n signedClaim: SignedClaim\n isAppclipProof: boolean\n status: string\n}\n\n/** the response from the PeerAuth extension when fetching a proof */\nexport interface NotarizedProof {\n claim: {\n context: string\n epoch: number\n identifier: Hex\n owner: Hex\n parameters: string\n provider: string\n timestampS: number\n },\n signatures: {\n attestorAddress: Hex\n claimSignature: Record<number, number>\n resultSignature: Record<number, number>\n },\n}\n\n/** the claim info for a proof */\nexport interface ClaimInfo {\n provider: string\n parameters: string\n context: string\n}\n\n/** the complete claim data for a proof */\nexport interface CompleteClaimData {\n identifier: Hex\n owner: Hex\n timestampS: number\n epoch: number\n}\n\n/** the signed claim for a proof */\nexport interface SignedClaim {\n claim: CompleteClaimData\n signatures: Hex[]\n}\n\n/** the reclaim proof for a proof */\nexport type ReclaimProof = {\n claimInfo: ClaimInfo\n signedClaim: SignedClaim\n isAppclipProof: boolean\n}\n\n/** the notary request for a proof */\nexport interface NotaryRequest {\n metadata: (string | number)[]\n actionType: ActionType\n id: string\n status: string\n timestamp: number\n proof: NotarizedProof\n}\n\n/** the response from the PeerAuth extension when fetching a proof */\nexport interface ProofResponse {\n notaryRequest: NotaryRequest\n}\n\n/**\n * Ready-to-send transaction the PeerAuth extension hands back once the\n * trusted-execution attestation service has signed the payment. The `data`\n * already embeds the enclave attestation, so the client signs and sends it\n * verbatim — no client-side proof encoding or gate re-signing.\n */\nexport type PeerOnrampPreparedTransaction = {\n intentHash: Hex\n status: 'calldata_ready'\n transaction: {\n to: Hex\n data: Hex\n /** Wei, as a decimal string (the extension keeps it out of JSON-number range). */\n value: string\n chainId: number\n }\n}\n\n/**\n * Structured on-ramp inputs. The extension looks the intent up from\n * `intentHash` (and the optional context fields) to resolve the chain,\n * contracts, and payment platform — we never pass contract addresses.\n */\nexport type PeerExtensionOnrampParams = {\n intentHash: string\n referrer?: string\n referrerLogo?: string\n inputCurrency?: string\n inputAmount?: string | number\n paymentPlatform?: string\n depositId?: string | number | bigint\n toToken?: string\n amountUsdc?: string | number | bigint\n recipientAddress?: string\n}\n\n/**\n * Serialize on-ramp params into the query string the extension's `onramp`\n * entry point expects. Mirrors the mapping `@zkp2p/sdk`'s\n * `peerExtensionSdk.onramp` performs: every defined field becomes one query\n * parameter, `undefined`/`null` fields are dropped, and `bigint` values are\n * stringified.\n */\nexport const buildOnrampQuery = (params: PeerExtensionOnrampParams): string => {\n const search = new URLSearchParams()\n Object.entries(params).forEach(([key, value]) => {\n if (value === undefined || value === null) return\n search.set(key, String(value))\n })\n return search.toString()\n}\n\n/**\n * Wrap a buyerTee capture (from {@link MetadataMessageResponse.buyerTeeCapture})\n * as a `NotaryRequest` so it flows through the existing submit step, which\n * narrows `proof` to a buyerTee proof and routes it to the enclave verify\n * endpoint. The `index` is the matched transaction's `originalIndex` — the\n * extension keys the captured payment on it.\n *\n * This replaces `generateProof` entirely for migrated providers: the session\n * was already captured + encrypted during `authenticate({ captureMode: 'buyerTee' })`.\n */\nexport const buildBuyerTeeNotaryRequest = ({\n encryptedSessionMaterial,\n index,\n actionType,\n}: {\n encryptedSessionMaterial: string\n index: number\n actionType: ActionType\n}): NotaryRequest => ({\n metadata: [],\n actionType,\n id: `buyer-tee-${index}`,\n status: 'success',\n timestamp: 0,\n // The runtime shape is a buyerTee proof, not a Reclaim NotarizedProof; the\n // submit step narrows it via `asBuyerTeeProof` before use.\n proof: {\n proofType: 'buyerTee',\n encryptedSessionMaterial,\n params: { index },\n } as unknown as NotarizedProof,\n})\n\nexport const extensionUrl = 'https://chromewebstore.google.com/detail/ijpgccednehjpeclfcllnjjcmiohdjih'\n\n/** convert a byte array to a hex string */\nexport const byteArrayToHexString = (byteArray: number[]): Hex => {\n return `0x${byteArray\n .map(byte => byte.toString(16).padStart(2, '0'))\n .join('')}`\n}\n\n/** parse a proof object from the PeerAuth extension */\nexport const parseExtensionProof = (proofObject: NotarizedProof) => {\n return {\n claimInfo: {\n provider: proofObject.claim.provider,\n parameters: proofObject.claim.parameters,\n context: proofObject.claim.context\n },\n signedClaim: {\n claim: {\n identifier: proofObject.claim.identifier as Hex,\n owner: proofObject.claim.owner as Hex,\n timestampS: proofObject.claim.timestampS,\n epoch: proofObject.claim.epoch\n },\n signatures: [byteArrayToHexString(Object.values(proofObject.signatures.claimSignature))]\n },\n isAppclipProof: false\n } as ReclaimProof\n}\n\n/** the abi encoding for a proof */\nexport const PROOF_ENCODING = parseAbiParameter(\"((string provider, string parameters, string context) claimInfo, ((bytes32 identifier, address owner, uint32 timestampS, uint32 epoch) claim, bytes[] signatures) signedClaim, bool isAppclipProof)\")\n\n/** encode a single proof as a bytes array */\nexport function encodeProofAsBytes(proof: ReclaimProof): Hex {\n return encodeAbiParameters([PROOF_ENCODING], [proof])\n}\n\n/** encode two proofs to be passed to the underlying sub-provider */\nexport const encodeTwoProofs = (proof1: ReclaimProof, proof2: ReclaimProof) => {\n return encodeAbiParameters([PROOF_ENCODING, PROOF_ENCODING], [proof1, proof2])\n}\n\n/** a high level function to encode a proof for a given provider and sub-provider */\nexport const encodeProof = ({ extensionProofs, subProvider, provider }: {\n extensionProofs: NotarizedProof[],\n subProvider: PlatformKey | null,\n provider: ProviderKey\n}) => {\n const reclaimProofs = extensionProofs.map((p) => parseExtensionProof(p))\n if (provider === 'zelle') {\n // move this to check the blockchain for the payment method\n const paymentMethod = subProviderConfigs![provider]![subProvider as SubProviderKey]!.paymentMethod\n const twoEncoded = reclaimProofs.length === 2\n ? encodeTwoProofs(reclaimProofs[0]!, reclaimProofs[1]!)\n : encodeProofAsBytes(reclaimProofs[0]!)\n // select between various possible sub-providers\n const withPaymentMethod = encodeProofWithPaymentMethod({\n paymentMethod,\n proof: twoEncoded,\n })\n return withPaymentMethod\n }\n const [reclaimProof] = reclaimProofs\n return encodeProofAsBytes(reclaimProof!)\n}\n\n/**\n * wrap a proof with a payment method and proof\n * this allows us to use a single verifier as an entry point for multiple underlying sub-providers\n */\nexport const encodeProofWithPaymentMethod = ({\n proof,\n paymentMethod\n}: {\n proof: Hex,\n paymentMethod: number\n}): Hex => {\n return encodePacked(['uint8', 'bytes'], [paymentMethod, proof])\n}\n\n/** the progress of a proof series */\nexport enum SeriesProgress {\n Generating,\n Polling,\n Complete,\n}\n\nexport type ProgressInfo = {\n progress: SeriesProgress\n total: number\n step: number | null\n id: string | null\n}\n\n/** the mutations for the generate proof series function */\nexport type GenerateProofSeriesMutations = {\n progress?: ({ progress, step, id }: ProgressInfo) => void\n setOwnerName?: (name: string) => void\n}\n\n/** React hook to interact with the PeerAuth extension */\nexport const useZKTLS = () => {\n const [isInitialized, setIsInitialized] = useState(false)\n useEffect(() => {\n const setup = () => {\n setIsInitialized(true)\n }\n const eventName = 'peer#initialized'\n if (typeof window.peer !== 'undefined') {\n // api is available\n setup()\n } else {\n window.addEventListener(eventName, setup)\n return () => {\n window.removeEventListener(eventName, setup)\n }\n }\n }, [])\n return useMemo(() => {\n /** fetch a proof by its id */\n const fetchProofById = async (proofId: string): Promise<NotaryRequest | null> => {\n const proof = await window.peer!.fetchProofById(proofId)\n if (proof && proof.notaryRequest) return proof.notaryRequest\n const proofs = await window.peer!.fetchProofs()\n const proofFromList = proofs.notaryRequests.find((p) => p.id === proofId)\n if (proofFromList) return proofFromList\n return null\n }\n /** wait for a proof to be generated */\n const waitForProof = async (proofId: string, onCurrent?: (notaryRequest: NotaryRequest | null) => void) => {\n let notaryRequest: NotaryRequest | null = null\n do {\n notaryRequest = await fetchProofById(proofId)\n onCurrent?.(notaryRequest)\n await sleep(1_000)\n } while (!notaryRequest || !notaryRequest.status || notaryRequest.status === 'pending')\n if (notaryRequest.status === 'failed' || notaryRequest.status === 'expired' || notaryRequest.status === 'cancelled' || notaryRequest.status === 'error') {\n console.error('[waitForProof] proof terminal state:', JSON.stringify(notaryRequest, null, 2))\n const req = notaryRequest as unknown as Record<string, unknown>\n const detail = req.errorMessage ?? req.error ?? req.message ?? notaryRequest.status\n throw new Error(`Proof generation failed: ${detail}`)\n }\n return notaryRequest\n }\n /** generate a proof */\n const generateProof = async (inputs: HexIntentGenerateProofInputs): Promise<GenerateProofResponse> => {\n return await window.peer!.generateProof({\n proofIndex: 0,\n ...inputs,\n intentHash: BigInt(inputs.intentHash).toString(),\n })\n }\n return {\n /** check if the PeerAuth extension is initialized */\n isInitialized,\n /** request a connection to the PeerAuth extension */\n requestConnection: async () => {\n if (!window.peer) return false\n return window.peer!.requestConnection()\n },\n /**\n * check the connection status of the PeerAuth extension\n * @returns the connection status\n */\n checkConnectionStatus: async () => {\n return await window.peer!.checkConnectionStatus()\n },\n /** get the version of the PeerAuth extension */\n getVersion: async () => {\n return await window.peer?.getVersion()\n },\n /** authenticate with the PeerAuth extension */\n authenticate: async (inputs: AuthenticationInputs) => {\n // Create promise first to avoid race condition where message arrives before resolver is assigned\n let resolve: (value: MetadataMessageResponse) => void\n const promise = new Promise<MetadataMessageResponse>((resolver) => {\n resolve = resolver\n })\n\n // Now set up the listener - resolve is guaranteed to be the real resolver\n const unsub = window.peer!.onMetadataMessage((data) => {\n if (`transfer_${data.platform}` === inputs.actionType) {\n resolve(data)\n }\n })\n\n await window.peer!.authenticate(inputs)\n\n return await promise.then((data) => {\n unsub()\n return data\n })\n },\n /** generate a proof */\n generateProof,\n /** wait for a proof to be generated */\n waitForProof,\n /** generate a proof series */\n generateProofSeries: async (\n inputs: GenerateProofInputsAbstracted,\n { progress: progressCallback }: GenerateProofSeriesMutations = {},\n ): Promise<NotaryRequest[]> => {\n const { platform, provider, intentHash, originalIndex } = inputs\n const args = {\n platform: provider,\n originalIndex,\n intentHash,\n } as const\n // Chase requires 2 proofs (account verification + transaction)\n // Platform is the bank name (e.g., 'chase') from extensionPlatform config\n const isChase = platform === extensionPlatforms.CHASE\n const isZelle = provider === providers.ZELLE\n const expectedTotal = isZelle && isChase ? 2 : 1\n progressCallback?.({ progress: SeriesProgress.Generating, step: 0, id: null, total: expectedTotal })\n const genProofA = await generateProof({ ...args, proofIndex: 0 })\n progressCallback?.({ progress: SeriesProgress.Polling, step: 0, id: genProofA.proofId, total: expectedTotal })\n const proofA = await waitForProof(genProofA.proofId)\n if (!isChase || !isZelle) {\n progressCallback?.({ progress: SeriesProgress.Complete, step: null, id: null, total: expectedTotal })\n return [proofA]\n }\n progressCallback?.({ progress: SeriesProgress.Generating, step: 1, id: null, total: expectedTotal })\n const genProofB = await generateProof({ ...args, proofIndex: 1 })\n progressCallback?.({ progress: SeriesProgress.Polling, step: 1, id: genProofB.proofId, total: expectedTotal })\n const proofB = await waitForProof(genProofB.proofId)\n progressCallback?.({ progress: SeriesProgress.Complete, step: null, id: null, total: expectedTotal })\n return [proofA, proofB]\n },\n /** subscribe to metadata messages */\n onMetadataMessage: (fn: (data: any) => void) => {\n return window.peer!.onMetadataMessage(fn)\n },\n /** fetch a proof by its id */\n fetchProofById,\n /** fetch generated proofs */\n fetchGeneratedProofs: async (genProofResponses: GenerateProofResponse[]) => {\n return await Promise.all(genProofResponses.map((r) => fetchProofById(r.proofId)))\n },\n /** fetch all proofs */\n fetchProofs: async () => {\n return await window.peer!.fetchProofs()\n },\n /** open the PeerAuth sidebar */\n openSidebar: async (route: string) => {\n return await window.peer!.openSidebar(route)\n },\n /** Whether the connected extension exposes the trusted-execution on-ramp. */\n supportsOnramp: (): boolean => typeof window.peer?.onramp === 'function',\n /**\n * Begin the trusted-execution on-ramp and resolve with ready-to-send\n * `fulfillIntent` calldata once the extension has intercepted the bank\n * session and the zkp2p attestation service has signed the payment.\n *\n * The underlying extension API is callback-only with no error channel:\n * the extension surfaces progress and failures in its own sidebar/tab,\n * and only invokes the callback on success. The returned promise\n * therefore stays pending until the prepared transaction arrives — the\n * caller drives the user toward the PeerAuth window and may offer a\n * cancel affordance rather than racing a timeout against a buyer who is\n * still logging into their bank.\n */\n onramp: async (\n params: PeerExtensionOnrampParams,\n ): Promise<PeerOnrampPreparedTransaction> => {\n if (typeof window.peer?.onramp !== 'function') {\n throw new Error(\n 'This PeerAuth extension version does not support the trusted-execution on-ramp. Please update the extension.',\n )\n }\n const queryString = buildOnrampQuery(params)\n return new Promise<PeerOnrampPreparedTransaction>((resolve) => {\n window.peer!.onramp!(queryString, resolve)\n })\n },\n /**\n * Retrieve a previously prepared on-ramp transaction by intent hash.\n * Returns null when the extension lacks the API or has nothing prepared\n * yet — usable as a poll alongside {@link onramp} to recover a result\n * if the one-shot callback is missed.\n */\n getOnrampTransaction: async (\n intentHash: string,\n ): Promise<PeerOnrampPreparedTransaction | null> => {\n if (typeof window.peer?.getOnrampTransaction !== 'function') return null\n return window.peer.getOnrampTransaction(intentHash)\n },\n }\n }, [isInitialized])\n}\n\n/**\n * Find the metadata message that matches the intent by amount.\n * Returns the first (most recent) transaction in the metadata array that matches the expected amount.\n *\n * Simplified matching: just find transactions with the correct amount.\n * The user can manually select if multiple matches exist.\n */\nexport const findMetadataMessage = ({ metadata, intent, token, centIsInt = false }: {\n metadata: MetadataMessage[],\n intent: IntentStruct,\n token: TokenInfo,\n /** @deprecated No longer used - kept for API compatibility */\n recipient?: string,\n centIsInt?: boolean,\n}): MetadataMessage | null => {\n const currencyAmount = convertTokenInputToCurrency({\n token,\n amountOutInt: intent.amount,\n rate: intent.conversionRate,\n })\n /**\n * Normalize an amount from the extension into a bigint in token base units.\n *\n * The extension sends amounts in different formats per provider:\n * - Venmo: `\"- $1.00\"` (formatted dollar string)\n * - Others: `100` (integer cents) or `1.00` (decimal dollars)\n *\n * We detect the format by checking for currency symbols or decimal points\n * in the raw value. If present, the value is already in dollars and we\n * skip the centIsInt division.\n */\n const normalizeAmount = (amount: number | string): bigint => {\n const raw = String(amount)\n const isFormattedDollars = /[^0-9\\-]/.test(raw) && raw.includes('.')\n const cleaned = raw.replace(/[^0-9.]/g, '')\n let value = parseUnits(cleaned, token.decimals)\n if (centIsInt && !isFormattedDollars) {\n value = value / 100n\n }\n return value\n }\n\n // Skip auto-match when manual selection is forced (dev/testing)\n if (typeof window !== 'undefined' && (window as unknown as Record<string, unknown>).__FORCE_MANUAL_TX_SELECT__) {\n return null\n }\n\n // Find the first transaction that matches the amount (first in array = most recent)\n // Note: We ignore the hidden flag - matching is purely by amount\n const match = metadata.find((m) => {\n const converted = normalizeAmount(m.amount)\n return converted === currencyAmount || converted === (currencyAmount * -1n)\n })\n\n if (!match) {\n // Detect 100x scale mismatch — the most common failure mode when centIsInt\n // is wrong for a provider. Fires loudly so it's obvious in dev/staging logs.\n const hundredxMatch = metadata.find((m) => {\n const converted = normalizeAmount(m.amount)\n const abs = converted < 0n ? -converted : converted\n return abs === currencyAmount * 100n || abs * 100n === currencyAmount\n })\n if (hundredxMatch) {\n console.warn(\n `[findMetadataMessage] tx[0] amount=${String(hundredxMatch.amount)} is 100x off from expected ${currencyAmount.toString()} — centIsInt is likely wrong for this provider (currently ${centIsInt})`\n )\n }\n return null\n }\n\n return match\n}\n","/**\n * @fileoverview React context for PeerAuth extension state.\n *\n * Provides global access to the useZKTLS hook state throughout the\n * component tree, avoiding prop drilling for extension status.\n *\n * @see {@link useZKTLS} for the underlying hook\n */\n\nimport { createContext, useContext, type ReactNode } from 'react'\nimport { useZKTLS } from './useZKTLS'\n\n/**\n * Context type derived from useZKTLS hook return value.\n */\ntype ZKTLSContextType = ReturnType<typeof useZKTLS>\n\nexport const ZKTLSContext = createContext<ZKTLSContextType | undefined>(undefined)\n\ninterface ZKTLSProviderProps {\n children: ReactNode\n}\n\n/**\n * Hook to consume the ZKTLS context.\n * Must be used within a ZKTLSProvider.\n *\n * @throws Error if used outside of ZKTLSProvider\n */\nexport function useZKTLSContext() {\n const context = useContext(ZKTLSContext)\n if (context === undefined) {\n throw new Error('useZKTLSContext must be used within a ZKTLSProvider')\n }\n return context\n}\n\nexport function ZKTLSProvider({ children }: ZKTLSProviderProps) {\n const zktlsHook = useZKTLS()\n\n return (\n <ZKTLSContext.Provider value={zktlsHook}>\n {children}\n </ZKTLSContext.Provider>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/useZKTLS.ts","../src/ZKTLSContext.tsx"],"names":["useState","useEffect","useMemo","createContext","useContext"],"mappings":";;;;;;AAsKO,IAAM,gBAAA,GAAmB,CAAC,MAAA,KAA8C;AAC7E,EAAA,MAAM,MAAA,GAAS,IAAI,eAAA,EAAgB;AACnC,EAAA,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AAC/C,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AAC3C,IAAA,MAAA,CAAO,GAAA,CAAI,GAAA,EAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EAC/B,CAAC,CAAA;AACD,EAAA,OAAO,OAAO,QAAA,EAAS;AACzB,CAAA;AAKO,IAAM,WAAW,MAAM;AAC5B,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAIA,eAAS,KAAK,CAAA;AACxD,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,MAAM,QAAQ,MAAM;AAClB,MAAA,gBAAA,CAAiB,IAAI,CAAA;AAAA,IACvB,CAAA;AACA,IAAA,MAAM,SAAA,GAAY,kBAAA;AAClB,IAAA,IAAI,OAAO,MAAA,CAAO,IAAA,KAAS,WAAA,EAAa;AAEtC,MAAA,KAAA,EAAM;AAAA,IACR,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,KAAK,CAAA;AACxC,MAAA,OAAO,MAAM;AACX,QAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,KAAK,CAAA;AAAA,MAC7C,CAAA;AAAA,IACF;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,OAAOC,cAAQ,MAAM;AACnB,IAAA,OAAO;AAAA;AAAA,MAEL,aAAA;AAAA;AAAA,MAEA,mBAAmB,YAAY;AAC7B,QAAA,IAAI,CAAC,MAAA,CAAO,IAAA,EAAM,OAAO,KAAA;AACzB,QAAA,OAAO,MAAA,CAAO,KAAM,iBAAA,EAAkB;AAAA,MACxC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAKA,uBAAuB,YAAY;AACjC,QAAA,OAAO,MAAM,MAAA,CAAO,IAAA,CAAM,qBAAA,EAAsB;AAAA,MAClD,CAAA;AAAA;AAAA,MAEA,YAAY,YAAY;AACtB,QAAA,OAAO,MAAM,MAAA,CAAO,IAAA,EAAM,UAAA,EAAW;AAAA,MACvC,CAAA;AAAA;AAAA,MAEA,YAAA,EAAc,OAAO,MAAA,KAAiC;AAEpD,QAAA,IAAI,OAAA;AACJ,QAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAiC,CAAC,QAAA,KAAa;AACjE,UAAA,OAAA,GAAU,QAAA;AAAA,QACZ,CAAC,CAAA;AAGD,QAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAM,iBAAA,CAAkB,CAAC,IAAA,KAAS;AACrD,UAAA,IAAI,CAAA,SAAA,EAAY,IAAA,CAAK,QAAQ,CAAA,CAAA,KAAO,OAAO,UAAA,EAAY;AACrD,YAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,UACd;AAAA,QACF,CAAC,CAAA;AAED,QAAA,MAAM,MAAA,CAAO,IAAA,CAAM,YAAA,CAAa,MAAM,CAAA;AAEtC,QAAA,OAAO,MAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,IAAA,KAAS;AAClC,UAAA,KAAA,EAAM;AACN,UAAA,OAAO,IAAA;AAAA,QACT,CAAC,CAAA;AAAA,MACH,CAAA;AAAA;AAAA,MAEA,iBAAA,EAAmB,CAAC,EAAA,KAA4B;AAC9C,QAAA,OAAO,MAAA,CAAO,IAAA,CAAM,iBAAA,CAAkB,EAAE,CAAA;AAAA,MAC1C,CAAA;AAAA;AAAA,MAEA,WAAA,EAAa,OAAO,KAAA,KAAkB;AACpC,QAAA,OAAO,MAAM,MAAA,CAAO,IAAA,CAAM,WAAA,CAAY,KAAK,CAAA;AAAA,MAC7C,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,cAAA,EAAgB,MAAe,OAAO,MAAA,CAAO,MAAM,MAAA,KAAW,UAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAc9D,MAAA,EAAQ,OACN,MAAA,KAC2C;AAC3C,QAAA,IAAI,OAAO,MAAA,CAAO,IAAA,EAAM,MAAA,KAAW,UAAA,EAAY;AAC7C,UAAA,MAAM,IAAI,KAAA;AAAA,YACR;AAAA,WACF;AAAA,QACF;AACA,QAAA,MAAM,WAAA,GAAc,iBAAiB,MAAM,CAAA;AAC3C,QAAA,OAAO,IAAI,OAAA,CAAuC,CAAC,OAAA,KAAY;AAC7D,UAAA,MAAA,CAAO,IAAA,CAAM,MAAA,CAAQ,WAAA,EAAa,OAAO,CAAA;AAAA,QAC3C,CAAC,CAAA;AAAA,MACH,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,oBAAA,EAAsB,OACpB,UAAA,KACkD;AAClD,QAAA,IAAI,OAAO,MAAA,CAAO,IAAA,EAAM,oBAAA,KAAyB,YAAY,OAAO,IAAA;AACpE,QAAA,OAAO,MAAA,CAAO,IAAA,CAAK,oBAAA,CAAqB,UAAU,CAAA;AAAA,MACpD;AAAA;AAAA,KAEF;AAAA,EACF,CAAA,EAAG,CAAC,aAAa,CAAC,CAAA;AACpB,CAAA;ACrRO,IAAM,YAAA,GAAeC,oBAA4C,MAAS;AAY1E,SAAS,eAAA,GAAkB;AAChC,EAAA,MAAM,OAAA,GAAUC,iBAAW,YAAY,CAAA;AACvC,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,MAAM,IAAI,MAAM,qDAAqD,CAAA;AAAA,EACvE;AACA,EAAA,OAAO,OAAA;AACT;AAEO,SAAS,aAAA,CAAc,EAAE,QAAA,EAAS,EAAuB;AAC9D,EAAA,MAAM,YAAY,QAAA,EAAS;AAE3B,EAAA,sCACG,YAAA,CAAa,QAAA,EAAb,EAAsB,KAAA,EAAO,WAC3B,QAAA,EACH,CAAA;AAEJ","file":"ZKTLSContext.cjs","sourcesContent":["/**\n * @fileoverview React hook and utilities for PeerAuth browser extension integration.\n *\n * The PeerAuth extension (formerly ZK-TLS) provides secure proof generation\n * for off-chain payment verification. This module provides:\n *\n * 1. Type definitions for extension API (window.peer)\n * 2. useZKTLS hook for React components\n * 3. The trusted-execution on-ramp helpers\n *\n * @remarks\n * The extension exposes `window.peer` (or deprecated `window.zktls`) for:\n * - Requesting connection (OAuth-like flow)\n * - Authenticating with payment providers (buyer trusted-execution capture)\n * - Fetching transaction metadata\n *\n * The Reclaim proof path (generateProof, proof encoding, proof types) was\n * removed in the next major version.\n *\n * @see {@link ZKTLSContext} for the React context provider\n */\n\nimport { useEffect, useMemo, useState } from \"react\"\nimport { type Hex } from \"viem\"\nimport { type ActionType, type PlatformKey, type ProviderKey } from \"@provex/utils/payment\"\n\ndeclare global {\n interface ZKTLS {\n requestConnection(): Promise<boolean>\n checkConnectionStatus(): Promise<Status>\n getVersion(): Promise<string>\n authenticate(inputs: AuthenticationInputs): Promise<void>\n openSidebar(route: string): Promise<void>\n onMetadataMessage(fn: (data: MetadataMessageResponse) => void): () => void\n /**\n * Trusted-execution on-ramp (PeerAuth v3+). The extension opens the\n * buyer's bank in a new tab, intercepts the authenticated session, calls\n * the zkp2p trusted-execution attestation service, and returns\n * ready-to-send `fulfillIntent` calldata through the callback. Replaces\n * the retired Reclaim proof path.\n *\n * Optional: older extension builds predate the on-ramp API, so guard\n * with a runtime presence check (`supportsOnramp`) before calling.\n *\n * @param queryString serialized on-ramp params (see {@link buildOnrampQuery})\n * @param callback invoked once the prepared transaction is ready\n */\n onramp?(\n queryString: string,\n callback: (result: PeerOnrampPreparedTransaction) => void,\n ): void\n /** Retrieve a previously prepared on-ramp transaction by intent hash. */\n getOnrampTransaction?(intentHash: string): Promise<PeerOnrampPreparedTransaction | null>\n }\n interface Window {\n /** @deprecated Use window.peer instead */\n zktls: ZKTLS | undefined\n /** PeerAuth extension API (replaces window.zktls) */\n peer: ZKTLS | undefined\n }\n}\n\n/** the status of the PeerAuth extension */\nexport type Status = 'connected' | 'disconnected' | 'pending'\n\n/** the individual metadata message sent by the PeerAuth extension */\nexport interface MetadataMessage {\n amount: number\n /** Currency code (e.g., 'USD', 'EUR') */\n currency?: string\n /**\n * Date of the transaction.\n * Can be a string in YYYYMMDD format, a number (YYYYMMDD or timestamp), or Date object.\n * The actual type depends on the extension implementation.\n */\n date: string | number | Date\n hidden: boolean\n originalIndex: number\n paymentId: number\n recipient: string\n}\n\n/** the response from the PeerAuth extension when a metadata message is received */\nexport interface MetadataMessageResponse {\n expiresAt: number\n platform: ProviderKey\n requestId: string\n metadata: MetadataMessage[]\n /**\n * Present only when `authenticate` was called with `captureMode: 'buyerTee'`.\n * Carries the bank session already encrypted toward the enclave — feed\n * `encryptedSessionMaterial` (plus the matched transaction's index) to the\n * trusted-execution verify endpoint.\n */\n buyerTeeCapture?: {\n encryptedSessionMaterial: string\n }\n /** Error surfaced by the extension during capture (e.g. missing platform). */\n errorMessage?: string\n}\n\n/** the inputs for the authenticate function */\nexport type AuthenticationInputs = {\n actionType: ActionType\n platform: PlatformKey\n /**\n * Session capture mode. `'buyerTee'` makes the extension intercept the bank\n * session and return it encrypted toward the trusted-execution enclave in\n * `MetadataMessageResponse.buyerTeeCapture`. The extension defaults the\n * attestation service URL when this is set.\n */\n captureMode?: 'buyerTee' | 'sellerCredential'\n /**\n * Enclave the extension establishes the Buyer TEE session with and encrypts\n * the captured session material toward (zkp2p 0.6.0 spec §7). Pass explicitly\n * for newer providers — relying on the extension's built-in default is what\n * left non-Revolut rails with \"no buyerTee capture\".\n */\n attestationServiceUrl?: string\n /** Attestation action type; defaults to `actionType` when omitted (spec §2). */\n attestationActionType?: ActionType\n}\n\n/**\n * Ready-to-send transaction the PeerAuth extension hands back once the\n * trusted-execution attestation service has signed the payment. The `data`\n * already embeds the enclave attestation, so the client signs and sends it\n * verbatim — no client-side proof encoding or gate re-signing.\n */\nexport type PeerOnrampPreparedTransaction = {\n intentHash: Hex\n status: 'calldata_ready'\n transaction: {\n to: Hex\n data: Hex\n /** Wei, as a decimal string (the extension keeps it out of JSON-number range). */\n value: string\n chainId: number\n }\n}\n\n/**\n * Structured on-ramp inputs. The extension looks the intent up from\n * `intentHash` (and the optional context fields) to resolve the chain,\n * contracts, and payment platform — we never pass contract addresses.\n */\nexport type PeerExtensionOnrampParams = {\n intentHash: string\n referrer?: string\n referrerLogo?: string\n inputCurrency?: string\n inputAmount?: string | number\n paymentPlatform?: string\n depositId?: string | number | bigint\n toToken?: string\n amountUsdc?: string | number | bigint\n recipientAddress?: string\n}\n\n/**\n * Serialize on-ramp params into the query string the extension's `onramp`\n * entry point expects. Mirrors the mapping `@zkp2p/sdk`'s\n * `peerExtensionSdk.onramp` performs: every defined field becomes one query\n * parameter, `undefined`/`null` fields are dropped, and `bigint` values are\n * stringified.\n */\nexport const buildOnrampQuery = (params: PeerExtensionOnrampParams): string => {\n const search = new URLSearchParams()\n Object.entries(params).forEach(([key, value]) => {\n if (value === undefined || value === null) return\n search.set(key, String(value))\n })\n return search.toString()\n}\n\nexport const extensionUrl = 'https://chromewebstore.google.com/detail/ijpgccednehjpeclfcllnjjcmiohdjih'\n\n/** React hook to interact with the PeerAuth extension */\nexport const useZKTLS = () => {\n const [isInitialized, setIsInitialized] = useState(false)\n useEffect(() => {\n const setup = () => {\n setIsInitialized(true)\n }\n const eventName = 'peer#initialized'\n if (typeof window.peer !== 'undefined') {\n // api is available\n setup()\n } else {\n window.addEventListener(eventName, setup)\n return () => {\n window.removeEventListener(eventName, setup)\n }\n }\n }, [])\n return useMemo(() => {\n return {\n /** check if the PeerAuth extension is initialized */\n isInitialized,\n /** request a connection to the PeerAuth extension */\n requestConnection: async () => {\n if (!window.peer) return false\n return window.peer!.requestConnection()\n },\n /**\n * check the connection status of the PeerAuth extension\n * @returns the connection status\n */\n checkConnectionStatus: async () => {\n return await window.peer!.checkConnectionStatus()\n },\n /** get the version of the PeerAuth extension */\n getVersion: async () => {\n return await window.peer?.getVersion()\n },\n /** authenticate with the PeerAuth extension */\n authenticate: async (inputs: AuthenticationInputs) => {\n // Create promise first to avoid race condition where message arrives before resolver is assigned\n let resolve: (value: MetadataMessageResponse) => void\n const promise = new Promise<MetadataMessageResponse>((resolver) => {\n resolve = resolver\n })\n\n // Now set up the listener - resolve is guaranteed to be the real resolver\n const unsub = window.peer!.onMetadataMessage((data) => {\n if (`transfer_${data.platform}` === inputs.actionType) {\n resolve(data)\n }\n })\n\n await window.peer!.authenticate(inputs)\n\n return await promise.then((data) => {\n unsub()\n return data\n })\n },\n /** subscribe to metadata messages */\n onMetadataMessage: (fn: (data: any) => void) => {\n return window.peer!.onMetadataMessage(fn)\n },\n /** open the PeerAuth sidebar */\n openSidebar: async (route: string) => {\n return await window.peer!.openSidebar(route)\n },\n /* v8 ignore start -- @preserve\n * Excluded from coverage on purpose: the extension's `window.peer.onramp`\n * API is retired (the buyer flow verifies through the zkp2p enclave\n * adapter instead) and no caller in this repository invokes\n * supportsOnramp, onramp or getOnrampTransaction. Testing them would\n * assert behaviour production never reaches. */\n /** Whether the connected extension exposes the trusted-execution on-ramp. */\n supportsOnramp: (): boolean => typeof window.peer?.onramp === 'function',\n /**\n * Begin the trusted-execution on-ramp and resolve with ready-to-send\n * `fulfillIntent` calldata once the extension has intercepted the bank\n * session and the zkp2p attestation service has signed the payment.\n *\n * The underlying extension API is callback-only with no error channel:\n * the extension surfaces progress and failures in its own sidebar/tab,\n * and only invokes the callback on success. The returned promise\n * therefore stays pending until the prepared transaction arrives — the\n * caller drives the user toward the PeerAuth window and may offer a\n * cancel affordance rather than racing a timeout against a buyer who is\n * still logging into their bank.\n */\n onramp: async (\n params: PeerExtensionOnrampParams,\n ): Promise<PeerOnrampPreparedTransaction> => {\n if (typeof window.peer?.onramp !== 'function') {\n throw new Error(\n 'This PeerAuth extension version does not support the trusted-execution on-ramp. Please update the extension.',\n )\n }\n const queryString = buildOnrampQuery(params)\n return new Promise<PeerOnrampPreparedTransaction>((resolve) => {\n window.peer!.onramp!(queryString, resolve)\n })\n },\n /**\n * Retrieve a previously prepared on-ramp transaction by intent hash.\n * Returns null when the extension lacks the API or has nothing prepared\n * yet — usable as a poll alongside {@link onramp} to recover a result\n * if the one-shot callback is missed.\n */\n getOnrampTransaction: async (\n intentHash: string,\n ): Promise<PeerOnrampPreparedTransaction | null> => {\n if (typeof window.peer?.getOnrampTransaction !== 'function') return null\n return window.peer.getOnrampTransaction(intentHash)\n },\n /* v8 ignore stop -- @preserve */\n }\n }, [isInitialized])\n}\n","/**\n * @fileoverview React context for PeerAuth extension state.\n *\n * Provides global access to the useZKTLS hook state throughout the\n * component tree, avoiding prop drilling for extension status.\n *\n * @see {@link useZKTLS} for the underlying hook\n */\n\nimport { createContext, useContext, type ReactNode } from 'react'\nimport { useZKTLS } from './useZKTLS'\n\n/**\n * Context type derived from useZKTLS hook return value.\n */\ntype ZKTLSContextType = ReturnType<typeof useZKTLS>\n\nexport const ZKTLSContext = createContext<ZKTLSContextType | undefined>(undefined)\n\ninterface ZKTLSProviderProps {\n children: ReactNode\n}\n\n/**\n * Hook to consume the ZKTLS context.\n * Must be used within a ZKTLSProvider.\n *\n * @throws Error if used outside of ZKTLSProvider\n */\nexport function useZKTLSContext() {\n const context = useContext(ZKTLSContext)\n if (context === undefined) {\n throw new Error('useZKTLSContext must be used within a ZKTLSProvider')\n }\n return context\n}\n\nexport function ZKTLSProvider({ children }: ZKTLSProviderProps) {\n const zktlsHook = useZKTLS()\n\n return (\n <ZKTLSContext.Provider value={zktlsHook}>\n {children}\n </ZKTLSContext.Provider>\n )\n}\n"]}
|
package/dist/ZKTLSContext.d.cts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
|
-
import { Status, AuthenticationInputs, MetadataMessageResponse,
|
|
4
|
+
import { Status, AuthenticationInputs, MetadataMessageResponse, PeerExtensionOnrampParams, PeerOnrampPreparedTransaction } from './useZKTLS.cjs';
|
|
5
5
|
import 'viem';
|
|
6
|
-
import '@provex/utils/intent';
|
|
7
|
-
import '@provex/utils/tokens';
|
|
8
6
|
import '@provex/utils/payment';
|
|
9
7
|
|
|
10
8
|
declare const ZKTLSContext: react.Context<{
|
|
@@ -13,13 +11,7 @@ declare const ZKTLSContext: react.Context<{
|
|
|
13
11
|
checkConnectionStatus: () => Promise<Status>;
|
|
14
12
|
getVersion: () => Promise<string | undefined>;
|
|
15
13
|
authenticate: (inputs: AuthenticationInputs) => Promise<MetadataMessageResponse>;
|
|
16
|
-
generateProof: (inputs: HexIntentGenerateProofInputs) => Promise<GenerateProofResponse>;
|
|
17
|
-
waitForProof: (proofId: string, onCurrent?: (notaryRequest: NotaryRequest | null) => void) => Promise<NotaryRequest>;
|
|
18
|
-
generateProofSeries: (inputs: GenerateProofInputsAbstracted, { progress: progressCallback }?: GenerateProofSeriesMutations) => Promise<NotaryRequest[]>;
|
|
19
14
|
onMetadataMessage: (fn: (data: any) => void) => () => void;
|
|
20
|
-
fetchProofById: (proofId: string) => Promise<NotaryRequest | null>;
|
|
21
|
-
fetchGeneratedProofs: (genProofResponses: GenerateProofResponse[]) => Promise<(NotaryRequest | null)[]>;
|
|
22
|
-
fetchProofs: () => Promise<FetchProofsResponse>;
|
|
23
15
|
openSidebar: (route: string) => Promise<void>;
|
|
24
16
|
supportsOnramp: () => boolean;
|
|
25
17
|
onramp: (params: PeerExtensionOnrampParams) => Promise<PeerOnrampPreparedTransaction>;
|
|
@@ -40,13 +32,7 @@ declare function useZKTLSContext(): {
|
|
|
40
32
|
checkConnectionStatus: () => Promise<Status>;
|
|
41
33
|
getVersion: () => Promise<string | undefined>;
|
|
42
34
|
authenticate: (inputs: AuthenticationInputs) => Promise<MetadataMessageResponse>;
|
|
43
|
-
generateProof: (inputs: HexIntentGenerateProofInputs) => Promise<GenerateProofResponse>;
|
|
44
|
-
waitForProof: (proofId: string, onCurrent?: (notaryRequest: NotaryRequest | null) => void) => Promise<NotaryRequest>;
|
|
45
|
-
generateProofSeries: (inputs: GenerateProofInputsAbstracted, { progress: progressCallback }?: GenerateProofSeriesMutations) => Promise<NotaryRequest[]>;
|
|
46
35
|
onMetadataMessage: (fn: (data: any) => void) => () => void;
|
|
47
|
-
fetchProofById: (proofId: string) => Promise<NotaryRequest | null>;
|
|
48
|
-
fetchGeneratedProofs: (genProofResponses: GenerateProofResponse[]) => Promise<(NotaryRequest | null)[]>;
|
|
49
|
-
fetchProofs: () => Promise<FetchProofsResponse>;
|
|
50
36
|
openSidebar: (route: string) => Promise<void>;
|
|
51
37
|
supportsOnramp: () => boolean;
|
|
52
38
|
onramp: (params: PeerExtensionOnrampParams) => Promise<PeerOnrampPreparedTransaction>;
|
package/dist/ZKTLSContext.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
|
-
import { Status, AuthenticationInputs, MetadataMessageResponse,
|
|
4
|
+
import { Status, AuthenticationInputs, MetadataMessageResponse, PeerExtensionOnrampParams, PeerOnrampPreparedTransaction } from './useZKTLS.js';
|
|
5
5
|
import 'viem';
|
|
6
|
-
import '@provex/utils/intent';
|
|
7
|
-
import '@provex/utils/tokens';
|
|
8
6
|
import '@provex/utils/payment';
|
|
9
7
|
|
|
10
8
|
declare const ZKTLSContext: react.Context<{
|
|
@@ -13,13 +11,7 @@ declare const ZKTLSContext: react.Context<{
|
|
|
13
11
|
checkConnectionStatus: () => Promise<Status>;
|
|
14
12
|
getVersion: () => Promise<string | undefined>;
|
|
15
13
|
authenticate: (inputs: AuthenticationInputs) => Promise<MetadataMessageResponse>;
|
|
16
|
-
generateProof: (inputs: HexIntentGenerateProofInputs) => Promise<GenerateProofResponse>;
|
|
17
|
-
waitForProof: (proofId: string, onCurrent?: (notaryRequest: NotaryRequest | null) => void) => Promise<NotaryRequest>;
|
|
18
|
-
generateProofSeries: (inputs: GenerateProofInputsAbstracted, { progress: progressCallback }?: GenerateProofSeriesMutations) => Promise<NotaryRequest[]>;
|
|
19
14
|
onMetadataMessage: (fn: (data: any) => void) => () => void;
|
|
20
|
-
fetchProofById: (proofId: string) => Promise<NotaryRequest | null>;
|
|
21
|
-
fetchGeneratedProofs: (genProofResponses: GenerateProofResponse[]) => Promise<(NotaryRequest | null)[]>;
|
|
22
|
-
fetchProofs: () => Promise<FetchProofsResponse>;
|
|
23
15
|
openSidebar: (route: string) => Promise<void>;
|
|
24
16
|
supportsOnramp: () => boolean;
|
|
25
17
|
onramp: (params: PeerExtensionOnrampParams) => Promise<PeerOnrampPreparedTransaction>;
|
|
@@ -40,13 +32,7 @@ declare function useZKTLSContext(): {
|
|
|
40
32
|
checkConnectionStatus: () => Promise<Status>;
|
|
41
33
|
getVersion: () => Promise<string | undefined>;
|
|
42
34
|
authenticate: (inputs: AuthenticationInputs) => Promise<MetadataMessageResponse>;
|
|
43
|
-
generateProof: (inputs: HexIntentGenerateProofInputs) => Promise<GenerateProofResponse>;
|
|
44
|
-
waitForProof: (proofId: string, onCurrent?: (notaryRequest: NotaryRequest | null) => void) => Promise<NotaryRequest>;
|
|
45
|
-
generateProofSeries: (inputs: GenerateProofInputsAbstracted, { progress: progressCallback }?: GenerateProofSeriesMutations) => Promise<NotaryRequest[]>;
|
|
46
35
|
onMetadataMessage: (fn: (data: any) => void) => () => void;
|
|
47
|
-
fetchProofById: (proofId: string) => Promise<NotaryRequest | null>;
|
|
48
|
-
fetchGeneratedProofs: (genProofResponses: GenerateProofResponse[]) => Promise<(NotaryRequest | null)[]>;
|
|
49
|
-
fetchProofs: () => Promise<FetchProofsResponse>;
|
|
50
36
|
openSidebar: (route: string) => Promise<void>;
|
|
51
37
|
supportsOnramp: () => boolean;
|
|
52
38
|
onramp: (params: PeerExtensionOnrampParams) => Promise<PeerOnrampPreparedTransaction>;
|
package/dist/ZKTLSContext.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ZKTLSContext, ZKTLSProvider, useZKTLSContext } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { ZKTLSContext, ZKTLSProvider, useZKTLSContext } from './chunk-B7RU2WKQ.js';
|
|
2
|
+
import './chunk-JU2T2TGY.js';
|
|
3
3
|
//# sourceMappingURL=ZKTLSContext.js.map
|
|
4
4
|
//# sourceMappingURL=ZKTLSContext.js.map
|