@proof-holdings/sdk 0.0.0-stage → 1.2.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/CHANGELOG.md +54 -0
- package/LICENSE +21 -0
- package/README.md +239 -2
- package/dist/cjs/client.d.ts +48 -0
- package/dist/cjs/client.d.ts.map +1 -0
- package/dist/cjs/client.js +73 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/credentials.d.ts +46 -0
- package/dist/cjs/credentials.d.ts.map +1 -0
- package/dist/cjs/credentials.js +137 -0
- package/dist/cjs/credentials.js.map +1 -0
- package/dist/cjs/crypto/hitl-crypto.d.ts +95 -0
- package/dist/cjs/crypto/hitl-crypto.d.ts.map +1 -0
- package/dist/cjs/crypto/hitl-crypto.js +338 -0
- package/dist/cjs/crypto/hitl-crypto.js.map +1 -0
- package/dist/cjs/errors.d.ts +52 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +121 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/http.d.ts +62 -0
- package/dist/cjs/http.d.ts.map +1 -0
- package/dist/cjs/http.js +192 -0
- package/dist/cjs/http.js.map +1 -0
- package/dist/cjs/index.d.ts +26 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +79 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/jwks/key-set-cache.d.ts +105 -0
- package/dist/cjs/jwks/key-set-cache.d.ts.map +1 -0
- package/dist/cjs/jwks/key-set-cache.js +277 -0
- package/dist/cjs/jwks/key-set-cache.js.map +1 -0
- package/dist/cjs/jwks/keyset.d.ts +139 -0
- package/dist/cjs/jwks/keyset.d.ts.map +1 -0
- package/dist/cjs/jwks/keyset.js +503 -0
- package/dist/cjs/jwks/keyset.js.map +1 -0
- package/dist/cjs/jwks/support.d.ts +9 -0
- package/dist/cjs/jwks/support.d.ts.map +1 -0
- package/dist/cjs/jwks/support.js +12 -0
- package/dist/cjs/jwks/support.js.map +1 -0
- package/dist/cjs/polling.d.ts +10 -0
- package/dist/cjs/polling.d.ts.map +1 -0
- package/dist/cjs/polling.js +74 -0
- package/dist/cjs/polling.js.map +1 -0
- package/dist/cjs/resources/auth-sessions.d.ts +41 -0
- package/dist/cjs/resources/auth-sessions.d.ts.map +1 -0
- package/dist/cjs/resources/auth-sessions.js +34 -0
- package/dist/cjs/resources/auth-sessions.js.map +1 -0
- package/dist/cjs/resources/authorizations.d.ts +23 -0
- package/dist/cjs/resources/authorizations.d.ts.map +1 -0
- package/dist/cjs/resources/authorizations.js +29 -0
- package/dist/cjs/resources/authorizations.js.map +1 -0
- package/dist/cjs/resources/circles.d.ts +38 -0
- package/dist/cjs/resources/circles.d.ts.map +1 -0
- package/dist/cjs/resources/circles.js +67 -0
- package/dist/cjs/resources/circles.js.map +1 -0
- package/dist/cjs/resources/confirmations.d.ts +111 -0
- package/dist/cjs/resources/confirmations.d.ts.map +1 -0
- package/dist/cjs/resources/confirmations.js +86 -0
- package/dist/cjs/resources/confirmations.js.map +1 -0
- package/dist/cjs/resources/delegations.d.ts +36 -0
- package/dist/cjs/resources/delegations.d.ts.map +1 -0
- package/dist/cjs/resources/delegations.js +47 -0
- package/dist/cjs/resources/delegations.js.map +1 -0
- package/dist/cjs/resources/hitl-chat-id.d.ts +42 -0
- package/dist/cjs/resources/hitl-chat-id.d.ts.map +1 -0
- package/dist/cjs/resources/hitl-chat-id.js +37 -0
- package/dist/cjs/resources/hitl-chat-id.js.map +1 -0
- package/dist/cjs/resources/hitl-keys.d.ts +13 -0
- package/dist/cjs/resources/hitl-keys.d.ts.map +1 -0
- package/dist/cjs/resources/hitl-keys.js +22 -0
- package/dist/cjs/resources/hitl-keys.js.map +1 -0
- package/dist/cjs/resources/hitl.d.ts +39 -0
- package/dist/cjs/resources/hitl.d.ts.map +1 -0
- package/dist/cjs/resources/hitl.js +58 -0
- package/dist/cjs/resources/hitl.js.map +1 -0
- package/dist/cjs/resources/me.d.ts +102 -0
- package/dist/cjs/resources/me.d.ts.map +1 -0
- package/dist/cjs/resources/me.js +85 -0
- package/dist/cjs/resources/me.js.map +1 -0
- package/dist/cjs/resources/profiles.d.ts +47 -0
- package/dist/cjs/resources/profiles.d.ts.map +1 -0
- package/dist/cjs/resources/profiles.js +70 -0
- package/dist/cjs/resources/profiles.js.map +1 -0
- package/dist/cjs/resources/proof-me.d.ts +48 -0
- package/dist/cjs/resources/proof-me.d.ts.map +1 -0
- package/dist/cjs/resources/proof-me.js +24 -0
- package/dist/cjs/resources/proof-me.js.map +1 -0
- package/dist/cjs/resources/proofs.d.ts +81 -0
- package/dist/cjs/resources/proofs.d.ts.map +1 -0
- package/dist/cjs/resources/proofs.js +437 -0
- package/dist/cjs/resources/proofs.js.map +1 -0
- package/dist/cjs/resources/public-profiles.d.ts +36 -0
- package/dist/cjs/resources/public-profiles.d.ts.map +1 -0
- package/dist/cjs/resources/public-profiles.js +49 -0
- package/dist/cjs/resources/public-profiles.js.map +1 -0
- package/dist/cjs/resources/sessions.d.ts +15 -0
- package/dist/cjs/resources/sessions.d.ts.map +1 -0
- package/dist/cjs/resources/sessions.js +26 -0
- package/dist/cjs/resources/sessions.js.map +1 -0
- package/dist/cjs/resources/templates.d.ts +25 -0
- package/dist/cjs/resources/templates.d.ts.map +1 -0
- package/dist/cjs/resources/templates.js +46 -0
- package/dist/cjs/resources/templates.js.map +1 -0
- package/dist/cjs/resources/verification-requests.d.ts +56 -0
- package/dist/cjs/resources/verification-requests.d.ts.map +1 -0
- package/dist/cjs/resources/verification-requests.js +61 -0
- package/dist/cjs/resources/verification-requests.js.map +1 -0
- package/dist/cjs/resources/verifications.d.ts +60 -0
- package/dist/cjs/resources/verifications.d.ts.map +1 -0
- package/dist/cjs/resources/verifications.js +91 -0
- package/dist/cjs/resources/verifications.js.map +1 -0
- package/dist/cjs/resources/webhook-deliveries.d.ts +15 -0
- package/dist/cjs/resources/webhook-deliveries.d.ts.map +1 -0
- package/dist/cjs/resources/webhook-deliveries.js +26 -0
- package/dist/cjs/resources/webhook-deliveries.js.map +1 -0
- package/dist/cjs/streaming.d.ts +87 -0
- package/dist/cjs/streaming.d.ts.map +1 -0
- package/dist/cjs/streaming.js +289 -0
- package/dist/cjs/streaming.js.map +1 -0
- package/dist/cjs/types.d.ts +1483 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +6 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/version.d.ts +2 -0
- package/dist/cjs/version.d.ts.map +1 -0
- package/dist/cjs/version.js +5 -0
- package/dist/cjs/version.js.map +1 -0
- package/dist/esm/client.d.ts +48 -0
- package/dist/esm/client.d.ts.map +1 -0
- package/dist/esm/client.js +69 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/credentials.d.ts +46 -0
- package/dist/esm/credentials.d.ts.map +1 -0
- package/dist/esm/credentials.js +127 -0
- package/dist/esm/credentials.js.map +1 -0
- package/dist/esm/crypto/hitl-crypto.d.ts +95 -0
- package/dist/esm/crypto/hitl-crypto.d.ts.map +1 -0
- package/dist/esm/crypto/hitl-crypto.js +321 -0
- package/dist/esm/crypto/hitl-crypto.js.map +1 -0
- package/dist/esm/errors.d.ts +52 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +106 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/http.d.ts +62 -0
- package/dist/esm/http.d.ts.map +1 -0
- package/dist/esm/http.js +187 -0
- package/dist/esm/http.js.map +1 -0
- package/dist/esm/index.d.ts +26 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +33 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/jwks/key-set-cache.d.ts +105 -0
- package/dist/esm/jwks/key-set-cache.d.ts.map +1 -0
- package/dist/esm/jwks/key-set-cache.js +268 -0
- package/dist/esm/jwks/key-set-cache.js.map +1 -0
- package/dist/esm/jwks/keyset.d.ts +139 -0
- package/dist/esm/jwks/keyset.d.ts.map +1 -0
- package/dist/esm/jwks/keyset.js +489 -0
- package/dist/esm/jwks/keyset.js.map +1 -0
- package/dist/esm/jwks/support.d.ts +9 -0
- package/dist/esm/jwks/support.d.ts.map +1 -0
- package/dist/esm/jwks/support.js +9 -0
- package/dist/esm/jwks/support.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/polling.d.ts +10 -0
- package/dist/esm/polling.d.ts.map +1 -0
- package/dist/esm/polling.js +71 -0
- package/dist/esm/polling.js.map +1 -0
- package/dist/esm/resources/auth-sessions.d.ts +41 -0
- package/dist/esm/resources/auth-sessions.d.ts.map +1 -0
- package/dist/esm/resources/auth-sessions.js +30 -0
- package/dist/esm/resources/auth-sessions.js.map +1 -0
- package/dist/esm/resources/authorizations.d.ts +23 -0
- package/dist/esm/resources/authorizations.d.ts.map +1 -0
- package/dist/esm/resources/authorizations.js +25 -0
- package/dist/esm/resources/authorizations.js.map +1 -0
- package/dist/esm/resources/circles.d.ts +38 -0
- package/dist/esm/resources/circles.d.ts.map +1 -0
- package/dist/esm/resources/circles.js +63 -0
- package/dist/esm/resources/circles.js.map +1 -0
- package/dist/esm/resources/confirmations.d.ts +111 -0
- package/dist/esm/resources/confirmations.d.ts.map +1 -0
- package/dist/esm/resources/confirmations.js +82 -0
- package/dist/esm/resources/confirmations.js.map +1 -0
- package/dist/esm/resources/delegations.d.ts +36 -0
- package/dist/esm/resources/delegations.d.ts.map +1 -0
- package/dist/esm/resources/delegations.js +43 -0
- package/dist/esm/resources/delegations.js.map +1 -0
- package/dist/esm/resources/hitl-chat-id.d.ts +42 -0
- package/dist/esm/resources/hitl-chat-id.d.ts.map +1 -0
- package/dist/esm/resources/hitl-chat-id.js +33 -0
- package/dist/esm/resources/hitl-chat-id.js.map +1 -0
- package/dist/esm/resources/hitl-keys.d.ts +13 -0
- package/dist/esm/resources/hitl-keys.d.ts.map +1 -0
- package/dist/esm/resources/hitl-keys.js +18 -0
- package/dist/esm/resources/hitl-keys.js.map +1 -0
- package/dist/esm/resources/hitl.d.ts +39 -0
- package/dist/esm/resources/hitl.d.ts.map +1 -0
- package/dist/esm/resources/hitl.js +54 -0
- package/dist/esm/resources/hitl.js.map +1 -0
- package/dist/esm/resources/me.d.ts +102 -0
- package/dist/esm/resources/me.d.ts.map +1 -0
- package/dist/esm/resources/me.js +81 -0
- package/dist/esm/resources/me.js.map +1 -0
- package/dist/esm/resources/profiles.d.ts +47 -0
- package/dist/esm/resources/profiles.d.ts.map +1 -0
- package/dist/esm/resources/profiles.js +66 -0
- package/dist/esm/resources/profiles.js.map +1 -0
- package/dist/esm/resources/proof-me.d.ts +48 -0
- package/dist/esm/resources/proof-me.d.ts.map +1 -0
- package/dist/esm/resources/proof-me.js +20 -0
- package/dist/esm/resources/proof-me.js.map +1 -0
- package/dist/esm/resources/proofs.d.ts +81 -0
- package/dist/esm/resources/proofs.d.ts.map +1 -0
- package/dist/esm/resources/proofs.js +433 -0
- package/dist/esm/resources/proofs.js.map +1 -0
- package/dist/esm/resources/public-profiles.d.ts +36 -0
- package/dist/esm/resources/public-profiles.d.ts.map +1 -0
- package/dist/esm/resources/public-profiles.js +45 -0
- package/dist/esm/resources/public-profiles.js.map +1 -0
- package/dist/esm/resources/sessions.d.ts +15 -0
- package/dist/esm/resources/sessions.d.ts.map +1 -0
- package/dist/esm/resources/sessions.js +22 -0
- package/dist/esm/resources/sessions.js.map +1 -0
- package/dist/esm/resources/templates.d.ts +25 -0
- package/dist/esm/resources/templates.d.ts.map +1 -0
- package/dist/esm/resources/templates.js +42 -0
- package/dist/esm/resources/templates.js.map +1 -0
- package/dist/esm/resources/verification-requests.d.ts +56 -0
- package/dist/esm/resources/verification-requests.d.ts.map +1 -0
- package/dist/esm/resources/verification-requests.js +57 -0
- package/dist/esm/resources/verification-requests.js.map +1 -0
- package/dist/esm/resources/verifications.d.ts +60 -0
- package/dist/esm/resources/verifications.d.ts.map +1 -0
- package/dist/esm/resources/verifications.js +87 -0
- package/dist/esm/resources/verifications.js.map +1 -0
- package/dist/esm/resources/webhook-deliveries.d.ts +15 -0
- package/dist/esm/resources/webhook-deliveries.d.ts.map +1 -0
- package/dist/esm/resources/webhook-deliveries.js +22 -0
- package/dist/esm/resources/webhook-deliveries.js.map +1 -0
- package/dist/esm/streaming.d.ts +87 -0
- package/dist/esm/streaming.d.ts.map +1 -0
- package/dist/esm/streaming.js +286 -0
- package/dist/esm/streaming.js.map +1 -0
- package/dist/esm/types.d.ts +1483 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +5 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/version.d.ts +2 -0
- package/dist/esm/version.d.ts.map +1 -0
- package/dist/esm/version.js +2 -0
- package/dist/esm/version.js.map +1 -0
- package/package.json +64 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Notable changes to [`@proof-holdings/sdk`](https://www.npmjs.com/package/@proof-holdings/sdk).
|
|
4
|
+
Source: [ProofHoldings/sdk-js](https://github.com/ProofHoldings/sdk-js).
|
|
5
|
+
|
|
6
|
+
## 1.2.0 — 2026-10-26
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- SMS sessions: `sessions.create({ channel: 'sms' })` now works, the same way as SMS sign-in. The
|
|
11
|
+
person texts a short code to one of our numbers; the session carries `sms_code`, `sms_message`
|
|
12
|
+
and `sms_dids` (`SessionSmsNumber` per region, each with its own QR), and `deep_link` is an `sms:`
|
|
13
|
+
link with the message pre-filled. An SMS proof carries `confidence: "standard"`.
|
|
14
|
+
- `CreateSessionParams.profile_id` names the sub-account a session is for; `Session.qr_text`.
|
|
15
|
+
|
|
16
|
+
- Message templates belong to a project (sub-account). Every `templates` method except `getDefaults`
|
|
17
|
+
takes an optional last argument `{ profileId }` (`TemplateProjectOptions`), sent as the `profile_id`
|
|
18
|
+
query parameter. Omitted, a project-bound API key uses its own project and any other key the
|
|
19
|
+
primary project; a project-bound key naming another project is refused with 403 `profile_mismatch`.
|
|
20
|
+
- `email_theme` and `support_email` on `Profile`, `CreateProfileParams` and `UpdateProfileParams`:
|
|
21
|
+
email branding is set per project.
|
|
22
|
+
- `TemplateGetResponse` carries `scope` (`project` or `default`) and `profile_id`;
|
|
23
|
+
`TemplateListResponse` and custom templates carry `profile_id`.
|
|
24
|
+
|
|
25
|
+
### Deprecated
|
|
26
|
+
|
|
27
|
+
- `CreateAuthorizationParams.business_name` and `CreateSessionParams.context` are marked
|
|
28
|
+
`@deprecated`. The server ignores both: messages name the sub-account (for a consent request, the
|
|
29
|
+
approval setup's).
|
|
30
|
+
|
|
31
|
+
- `profiles.listTemplates`, `updateTemplate`, `deleteTemplate` and `previewTemplate`. The server
|
|
32
|
+
retired `/api/v1/me/profiles/{id}/templates` (410 `endpoint_retired`); use the `templates` methods
|
|
33
|
+
with `{ profileId }`.
|
|
34
|
+
|
|
35
|
+
## 1.1.0 — 2026-10-14
|
|
36
|
+
|
|
37
|
+
The first release on npm.
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- `new Proof()` without a key resolves one: a non-empty `PROOF_API_KEY`, else the entry that
|
|
42
|
+
`npx @proof-holdings/mcp-server login` saved in `~/.proof-holdings/credentials` for the client's base
|
|
43
|
+
URL. The base URL is the `baseUrl` option, else `PROOF_BASE_URL`, else `https://api.proof.holdings`.
|
|
44
|
+
An explicit key behaves as before; an explicit empty key is an error.
|
|
45
|
+
- `proof.verifications.deleteDomainVerification(id)` deletes a domain verification attempt that is not
|
|
46
|
+
verified (pending, verifying or failed). A verified domain is refused with 409 `domain_verified`.
|
|
47
|
+
- Types for account deletion and export, identifier, domain and project removal, the artifact claim
|
|
48
|
+
lookup, and the Delegations section of a public profile.
|
|
49
|
+
- API-key listings carry `replaced_key_ids`: a key's usage covers every key it replaced.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- The README's runtime line: Node.js 18 or later. The SDK imports `node:fs`, `node:os`, `node:path`
|
|
54
|
+
and `node:zlib`, so it does not run in a browser.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Proof Holdings
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,240 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @proof-holdings/sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Official JavaScript/TypeScript SDK for the [proof.holdings](https://proof.holdings) verification API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @proof-holdings/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import Proof from '@proof-holdings/sdk';
|
|
15
|
+
|
|
16
|
+
const proof = new Proof('pk_live_...');
|
|
17
|
+
|
|
18
|
+
// Create a phone verification
|
|
19
|
+
const verification = await proof.verifications.create({
|
|
20
|
+
type: 'phone',
|
|
21
|
+
channel: 'whatsapp',
|
|
22
|
+
identifier: '+37069199199',
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
console.log('Deep link:', verification.challenge?.deep_link);
|
|
26
|
+
|
|
27
|
+
// Wait for user to verify
|
|
28
|
+
const result = await proof.verifications.waitForCompletion(verification.id);
|
|
29
|
+
|
|
30
|
+
if (result.status === 'verified') {
|
|
31
|
+
console.log('Proof token:', result.proof?.token);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- **Typed API client** covering all public endpoints
|
|
38
|
+
- **Built-in polling** — `waitForCompletion()` with configurable interval/timeout
|
|
39
|
+
- **Offline proof verification** — verify JWT proof tokens using JWKS public keys
|
|
40
|
+
- **Automatic retries** with exponential backoff for network/server errors
|
|
41
|
+
- **Error classes** with typed error codes from the API
|
|
42
|
+
- **ESM + CJS** dual output — works everywhere
|
|
43
|
+
|
|
44
|
+
## Resources
|
|
45
|
+
|
|
46
|
+
### Verifications
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// Create
|
|
50
|
+
const v = await proof.verifications.create({ type: 'phone', channel: 'telegram', identifier: '+1...' });
|
|
51
|
+
|
|
52
|
+
// Retrieve
|
|
53
|
+
const v = await proof.verifications.retrieve('verification_id');
|
|
54
|
+
|
|
55
|
+
// List (paginated)
|
|
56
|
+
const list = await proof.verifications.list({ status: 'verified', limit: 20 });
|
|
57
|
+
|
|
58
|
+
// Trigger DNS/HTTP check
|
|
59
|
+
await proof.verifications.verify('verification_id');
|
|
60
|
+
|
|
61
|
+
// Submit OTP code
|
|
62
|
+
await proof.verifications.submit('verification_id', 'A1B2C3');
|
|
63
|
+
|
|
64
|
+
// Poll until complete — uses exponential backoff per POLLING_CONTRACT.md.
|
|
65
|
+
// Defaults: 2s initial interval, 1.5× backoff, 30s max, 0–500ms jitter, 10min timeout.
|
|
66
|
+
const result = await proof.verifications.waitForCompletion('verification_id', {
|
|
67
|
+
interval: 2000, // initial poll interval in ms (default)
|
|
68
|
+
timeout: 600000, // 10 min timeout (default)
|
|
69
|
+
// backoff: 1.5, maxInterval: 30000, jitter: 500 — contract defaults
|
|
70
|
+
// signal: abortController.signal — optional AbortSignal for cancellation
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// WABA (WhatsApp Business) verification
|
|
74
|
+
const waba = await proof.verifications.create({
|
|
75
|
+
type: 'waba',
|
|
76
|
+
channel: 'waba_otp',
|
|
77
|
+
identifier: '+37069199199',
|
|
78
|
+
});
|
|
79
|
+
// OTP is sent via WhatsApp — submit with proof.verifications.submit(waba.id, code)
|
|
80
|
+
|
|
81
|
+
// Telegram Bot verification
|
|
82
|
+
const bot = await proof.verifications.create({
|
|
83
|
+
type: 'telegram_bot',
|
|
84
|
+
channel: 'telegram_bot_token',
|
|
85
|
+
identifier: '@mybusinessbot',
|
|
86
|
+
});
|
|
87
|
+
// Submit bot token with proof.verifications.submit(bot.id, botToken)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Verification Requests (Multi-Asset)
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
const request = await proof.verificationRequests.create({
|
|
94
|
+
assets: [
|
|
95
|
+
{ type: 'phone', required: true },
|
|
96
|
+
{ type: 'email', required: true },
|
|
97
|
+
{ type: 'domain', identifier: 'example.com', required: false },
|
|
98
|
+
],
|
|
99
|
+
redirect_url: 'https://yourapp.com/done',
|
|
100
|
+
callback_url: 'https://yourapp.com/webhooks',
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
console.log('Send user to:', request.verification_url);
|
|
104
|
+
|
|
105
|
+
const completed = await proof.verificationRequests.waitForCompletion(request.id);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Proofs
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// Online validation (checks revocation)
|
|
112
|
+
const result = await proof.proofs.validate(proofToken);
|
|
113
|
+
|
|
114
|
+
// Offline verification — no API call with your key. Reads two public documents: the JWKS for
|
|
115
|
+
// the signature, and the issuer's status list for revocation (checked by default).
|
|
116
|
+
const offline = await proof.proofs.verifyOffline(proofToken);
|
|
117
|
+
if (offline.valid) {
|
|
118
|
+
console.log('Verified:', offline.payload?.type, offline.payload?.verified_at);
|
|
119
|
+
} else {
|
|
120
|
+
// 'revoked' | 'suspended' | 'expired' | 'invalid' | 'status_unavailable'
|
|
121
|
+
// | 'key_revoked' | 'jwks_stale' | 'wrong_key_purpose' | 'outside_key_window'
|
|
122
|
+
// | 'token_lifetime_exceeded' | 'unknown_key' — see "Signing-key rotation" below
|
|
123
|
+
console.log('Refused:', offline.reason);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// `status_unavailable` means the revocation status could NOT be read — an unreachable list, one
|
|
127
|
+
// that failed its own checks, or a slot the list does not cover. It is a refusal to guess, not a
|
|
128
|
+
// claim that the proof is withdrawn. A token minted without a status-list slot stays valid and
|
|
129
|
+
// reports `revocation_checked: false`, exactly as the issuer's own `validate` answers for it.
|
|
130
|
+
|
|
131
|
+
// Signature only, for an air-gapped check against a warm key cache:
|
|
132
|
+
const signatureOnly = await proof.proofs.verifyOffline(proofToken, { checkRevocation: false });
|
|
133
|
+
console.log(signatureOnly.revocation_checked); // false — never assume it was checked
|
|
134
|
+
|
|
135
|
+
// Revoke a proof
|
|
136
|
+
await proof.proofs.revoke('verification_id', 'user_request');
|
|
137
|
+
|
|
138
|
+
// Get revocation list
|
|
139
|
+
const { revoked } = await proof.proofs.listRevoked();
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Signing-key rotation
|
|
143
|
+
|
|
144
|
+
`verifyOffline` fetches and caches the issuer's key set (JWKS) itself and follows its rotation rules.
|
|
145
|
+
The cached set is reused for 10 minutes; a `kid` it does not know triggers one refetch, at most
|
|
146
|
+
once every 30 seconds.
|
|
147
|
+
|
|
148
|
+
- **`key_revoked`** — the issuer revoked the key that signed the token. The result carries
|
|
149
|
+
`pull_hint: { issuer_origin, handle }`: where to fetch the re-signed token (`handle` is the proof's
|
|
150
|
+
`proof_id`, or a delegation's `sub`). The handle is read from the token itself, whose signature a
|
|
151
|
+
revoked key no longer vouches for: URL-encode it before building a request from it. A revocation
|
|
152
|
+
takes effect only after two key-set fetches at least 5 minutes apart both carry it, and is then kept
|
|
153
|
+
for a year.
|
|
154
|
+
- **`jwks_stale`** — the key set could not be refreshed and the cached copy is older than
|
|
155
|
+
`maxJwksAgeMs` (default 24 hours, at most 25 days; `new Proof(key, { maxJwksAgeMs })`). The result
|
|
156
|
+
carries `cache_age_seconds`. Call `refreshJWKS()` once the issuer is reachable.
|
|
157
|
+
- **`wrong_key_purpose`**, **`outside_key_window`**, **`token_lifetime_exceeded`** — the key belongs
|
|
158
|
+
to another token family, the token was signed outside the key's validity window, or it lives longer
|
|
159
|
+
than the key allows. **`unknown_key`** — no published key matches the token's `kid`.
|
|
160
|
+
|
|
161
|
+
Revoked-key tombstones are kept in memory only — they are not persisted, so a restarted process
|
|
162
|
+
learns them again from the issuer. `clearTombstones()` forgets them on purpose. `refreshJWKS()` makes
|
|
163
|
+
the next verification refetch the key set (and drops the cached status list); it does not forget
|
|
164
|
+
tombstones.
|
|
165
|
+
|
|
166
|
+
### Sessions (Phone-First Flow)
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
const session = await proof.sessions.create({ channel: 'telegram' });
|
|
170
|
+
console.log('QR code:', session.qr_code);
|
|
171
|
+
|
|
172
|
+
const completed = await proof.sessions.waitForCompletion(session.id);
|
|
173
|
+
console.log('Phone:', completed.phone_number);
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Webhook Deliveries
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
const deliveries = await proof.webhookDeliveries.list({ status: 'failed' });
|
|
180
|
+
await proof.webhookDeliveries.retry(deliveries.data[0].id);
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Error Handling
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
import { Proof, ValidationError, RateLimitError, AuthenticationError } from '@proof-holdings/sdk';
|
|
187
|
+
|
|
188
|
+
try {
|
|
189
|
+
await proof.verifications.create({ ... });
|
|
190
|
+
} catch (error) {
|
|
191
|
+
if (error instanceof ValidationError) {
|
|
192
|
+
console.error('Invalid params:', error.code, error.details);
|
|
193
|
+
} else if (error instanceof RateLimitError) {
|
|
194
|
+
console.error('Rate limited');
|
|
195
|
+
} else if (error instanceof AuthenticationError) {
|
|
196
|
+
console.error('Invalid API key');
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Configuration
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
const proof = new Proof('pk_live_...', {
|
|
205
|
+
baseUrl: 'https://api.proof.holdings', // default
|
|
206
|
+
timeout: 30000, // 30s request timeout (default)
|
|
207
|
+
maxRetries: 2, // retry failed requests (default)
|
|
208
|
+
maxJwksAgeMs: 86_400_000, // offline verification: 24h stale bound (default)
|
|
209
|
+
});
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Credentials
|
|
213
|
+
|
|
214
|
+
Sign in once with `npx @proof-holdings/mcp-server login` and construct the client with no key:
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
const proof = new Proof(); // or new Proof({ baseUrl: '...' })
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
When the key argument is omitted it is resolved in this order:
|
|
221
|
+
|
|
222
|
+
1. `PROOF_API_KEY`, when set and non-empty.
|
|
223
|
+
2. The entry for this client's base URL in `~/.proof-holdings/credentials`, the file the login
|
|
224
|
+
command writes. The file is keyed by base URL, so a key saved against staging is never sent
|
|
225
|
+
to production.
|
|
226
|
+
3. Otherwise construction throws, naming the three roads: pass the key, set `PROOF_API_KEY`, or
|
|
227
|
+
run `npx @proof-holdings/mcp-server login`.
|
|
228
|
+
|
|
229
|
+
The base URL is the `baseUrl` option, else a non-empty `PROOF_BASE_URL`, else
|
|
230
|
+
`https://api.proof.holdings`. An explicit key is used as given, and an explicit empty key
|
|
231
|
+
(`new Proof('')`) is an error — neither reads the environment or the file.
|
|
232
|
+
|
|
233
|
+
## Requirements
|
|
234
|
+
|
|
235
|
+
- Node.js 18+ (uses native `fetch`)
|
|
236
|
+
- Not for browsers: the SDK imports `node:fs`, `node:os`, `node:path` and `node:zlib`
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
MIT
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Verifications } from './resources/verifications.js';
|
|
2
|
+
import { VerificationRequests } from './resources/verification-requests.js';
|
|
3
|
+
import { Proofs } from './resources/proofs.js';
|
|
4
|
+
import { Sessions } from './resources/sessions.js';
|
|
5
|
+
import { WebhookDeliveries } from './resources/webhook-deliveries.js';
|
|
6
|
+
import { Confirmations } from './resources/confirmations.js';
|
|
7
|
+
import { AuthSessions } from './resources/auth-sessions.js';
|
|
8
|
+
import { Me } from './resources/me.js';
|
|
9
|
+
import { Hitl } from './resources/hitl.js';
|
|
10
|
+
import { HitlChatIdDiscovery } from './resources/hitl-chat-id.js';
|
|
11
|
+
import { HitlKeys } from './resources/hitl-keys.js';
|
|
12
|
+
import { Authorizations } from './resources/authorizations.js';
|
|
13
|
+
import { Templates } from './resources/templates.js';
|
|
14
|
+
import { Profiles } from './resources/profiles.js';
|
|
15
|
+
import { PublicProfiles } from './resources/public-profiles.js';
|
|
16
|
+
import { ProofMe } from './resources/proof-me.js';
|
|
17
|
+
import { Circles } from './resources/circles.js';
|
|
18
|
+
import { Delegations } from './resources/delegations.js';
|
|
19
|
+
import type { ProofOptions } from './types.js';
|
|
20
|
+
export declare class Proof {
|
|
21
|
+
readonly verifications: Verifications;
|
|
22
|
+
readonly verificationRequests: VerificationRequests;
|
|
23
|
+
readonly proofs: Proofs;
|
|
24
|
+
readonly sessions: Sessions;
|
|
25
|
+
readonly webhookDeliveries: WebhookDeliveries;
|
|
26
|
+
readonly confirmations: Confirmations;
|
|
27
|
+
readonly authSessions: AuthSessions;
|
|
28
|
+
readonly me: Me;
|
|
29
|
+
readonly hitl: Hitl;
|
|
30
|
+
readonly hitlChatIdDiscovery: HitlChatIdDiscovery;
|
|
31
|
+
readonly hitlKeys: HitlKeys;
|
|
32
|
+
readonly authorizations: Authorizations;
|
|
33
|
+
readonly templates: Templates;
|
|
34
|
+
readonly profiles: Profiles;
|
|
35
|
+
readonly publicProfiles: PublicProfiles;
|
|
36
|
+
readonly proofMe: ProofMe;
|
|
37
|
+
readonly circles: Circles;
|
|
38
|
+
readonly delegations: Delegations;
|
|
39
|
+
/**
|
|
40
|
+
* With a key: `new Proof('pk_live_…', options?)`, used as given. Without one — `new Proof()` or
|
|
41
|
+
* `new Proof(options)` — the key is resolved the way `npx @proof-holdings/mcp-server login`
|
|
42
|
+
* expects: a non-empty `PROOF_API_KEY`, else the entry saved for this client's base URL in
|
|
43
|
+
* `~/.proof-holdings/credentials`. An explicit empty key is an error and never reads either.
|
|
44
|
+
*/
|
|
45
|
+
constructor(apiKey?: string, options?: ProofOptions);
|
|
46
|
+
constructor(options?: ProofOptions);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM/C,qBAAa,KAAK;IAChB,SAAgB,aAAa,EAAE,aAAa,CAAC;IAC7C,SAAgB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3D,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,QAAQ,EAAE,QAAQ,CAAC;IACnC,SAAgB,iBAAiB,EAAE,iBAAiB,CAAC;IACrD,SAAgB,aAAa,EAAE,aAAa,CAAC;IAC7C,SAAgB,YAAY,EAAE,YAAY,CAAC;IAC3C,SAAgB,EAAE,EAAE,EAAE,CAAC;IACvB,SAAgB,IAAI,EAAE,IAAI,CAAC;IAC3B,SAAgB,mBAAmB,EAAE,mBAAmB,CAAC;IACzD,SAAgB,QAAQ,EAAE,QAAQ,CAAC;IACnC,SAAgB,cAAc,EAAE,cAAc,CAAC;IAC/C,SAAgB,SAAS,EAAE,SAAS,CAAC;IACrC,SAAgB,QAAQ,EAAE,QAAQ,CAAC;IACnC,SAAgB,cAAc,EAAE,cAAc,CAAC;IAC/C,SAAgB,OAAO,EAAE,OAAO,CAAC;IACjC,SAAgB,OAAO,EAAE,OAAO,CAAC;IACjC,SAAgB,WAAW,EAAE,WAAW,CAAC;IAEzC;;;;;OAKG;gBACS,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;gBACvC,OAAO,CAAC,EAAE,YAAY;CAkDnC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Proof = void 0;
|
|
4
|
+
const http_js_1 = require("./http.js");
|
|
5
|
+
const verifications_js_1 = require("./resources/verifications.js");
|
|
6
|
+
const verification_requests_js_1 = require("./resources/verification-requests.js");
|
|
7
|
+
const proofs_js_1 = require("./resources/proofs.js");
|
|
8
|
+
const sessions_js_1 = require("./resources/sessions.js");
|
|
9
|
+
const webhook_deliveries_js_1 = require("./resources/webhook-deliveries.js");
|
|
10
|
+
const confirmations_js_1 = require("./resources/confirmations.js");
|
|
11
|
+
const auth_sessions_js_1 = require("./resources/auth-sessions.js");
|
|
12
|
+
const me_js_1 = require("./resources/me.js");
|
|
13
|
+
const hitl_js_1 = require("./resources/hitl.js");
|
|
14
|
+
const hitl_chat_id_js_1 = require("./resources/hitl-chat-id.js");
|
|
15
|
+
const hitl_keys_js_1 = require("./resources/hitl-keys.js");
|
|
16
|
+
const authorizations_js_1 = require("./resources/authorizations.js");
|
|
17
|
+
const templates_js_1 = require("./resources/templates.js");
|
|
18
|
+
const profiles_js_1 = require("./resources/profiles.js");
|
|
19
|
+
const public_profiles_js_1 = require("./resources/public-profiles.js");
|
|
20
|
+
const proof_me_js_1 = require("./resources/proof-me.js");
|
|
21
|
+
const circles_js_1 = require("./resources/circles.js");
|
|
22
|
+
const delegations_js_1 = require("./resources/delegations.js");
|
|
23
|
+
const credentials_js_1 = require("./credentials.js");
|
|
24
|
+
const DEFAULT_TIMEOUT = 30000;
|
|
25
|
+
const DEFAULT_MAX_RETRIES = 2;
|
|
26
|
+
class Proof {
|
|
27
|
+
constructor(apiKeyOrOptions, maybeOptions) {
|
|
28
|
+
const options = typeof apiKeyOrOptions === 'object' && apiKeyOrOptions !== null ? apiKeyOrOptions : maybeOptions;
|
|
29
|
+
const explicit = typeof apiKeyOrOptions === 'string' ? apiKeyOrOptions : options?.apiKey;
|
|
30
|
+
const baseUrl = (0, credentials_js_1.resolveBaseUrl)(options?.baseUrl);
|
|
31
|
+
if (explicit === '') {
|
|
32
|
+
throw new Error('API key is required. Pass your key as the first argument: new Proof("pk_live_...")');
|
|
33
|
+
}
|
|
34
|
+
const resolved = (0, credentials_js_1.resolveApiKey)({ explicit, baseUrl });
|
|
35
|
+
if (!resolved.apiKey) {
|
|
36
|
+
throw new Error((0, credentials_js_1.missingKeyMessage)(baseUrl, resolved.notice));
|
|
37
|
+
}
|
|
38
|
+
const apiKey = resolved.apiKey;
|
|
39
|
+
const fetchFn = options?.fetch ?? globalThis.fetch;
|
|
40
|
+
if (!fetchFn) {
|
|
41
|
+
throw new Error('fetch is not available in this environment. ' +
|
|
42
|
+
'Provide a custom fetch implementation via options.fetch, ' +
|
|
43
|
+
'or use Node.js 18+ which includes native fetch.');
|
|
44
|
+
}
|
|
45
|
+
const http = new http_js_1.HttpClient({
|
|
46
|
+
apiKey,
|
|
47
|
+
baseUrl,
|
|
48
|
+
timeout: options?.timeout ?? DEFAULT_TIMEOUT,
|
|
49
|
+
maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
50
|
+
fetch: fetchFn,
|
|
51
|
+
});
|
|
52
|
+
this.verifications = new verifications_js_1.Verifications(http);
|
|
53
|
+
this.verificationRequests = new verification_requests_js_1.VerificationRequests(http);
|
|
54
|
+
this.proofs = new proofs_js_1.Proofs(http, { maxJwksAgeMs: options?.maxJwksAgeMs });
|
|
55
|
+
this.sessions = new sessions_js_1.Sessions(http);
|
|
56
|
+
this.webhookDeliveries = new webhook_deliveries_js_1.WebhookDeliveries(http);
|
|
57
|
+
this.confirmations = new confirmations_js_1.Confirmations(http);
|
|
58
|
+
this.authSessions = new auth_sessions_js_1.AuthSessions(http);
|
|
59
|
+
this.me = new me_js_1.Me(http);
|
|
60
|
+
this.hitl = new hitl_js_1.Hitl(http);
|
|
61
|
+
this.hitlChatIdDiscovery = new hitl_chat_id_js_1.HitlChatIdDiscovery(http);
|
|
62
|
+
this.hitlKeys = new hitl_keys_js_1.HitlKeys(http);
|
|
63
|
+
this.authorizations = new authorizations_js_1.Authorizations(http);
|
|
64
|
+
this.templates = new templates_js_1.Templates(http);
|
|
65
|
+
this.profiles = new profiles_js_1.Profiles(http);
|
|
66
|
+
this.publicProfiles = new public_profiles_js_1.PublicProfiles(http);
|
|
67
|
+
this.proofMe = new proof_me_js_1.ProofMe(http);
|
|
68
|
+
this.circles = new circles_js_1.Circles(http);
|
|
69
|
+
this.delegations = new delegations_js_1.Delegations(http);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.Proof = Proof;
|
|
73
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** The scoped command, never the bare bin name: through npx the unscoped name resolves to a package somebody else publishes. */
|
|
2
|
+
export declare const LOGIN_COMMAND = "npx @proof-holdings/mcp-server login";
|
|
3
|
+
export declare const DEFAULT_BASE_URL = "https://api.proof.holdings";
|
|
4
|
+
export interface StoredCredential {
|
|
5
|
+
api_key: string;
|
|
6
|
+
key_id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
environment: 'production' | 'test';
|
|
9
|
+
created_at: string;
|
|
10
|
+
}
|
|
11
|
+
export interface CredentialsFile {
|
|
12
|
+
version: 1;
|
|
13
|
+
credentials: Record<string, StoredCredential>;
|
|
14
|
+
}
|
|
15
|
+
export type KeySource = 'explicit' | 'env' | 'file' | 'none';
|
|
16
|
+
export interface ResolvedKey {
|
|
17
|
+
apiKey?: string;
|
|
18
|
+
source: KeySource;
|
|
19
|
+
/** Why the file could not be used, when it exists but was not read — never a key. */
|
|
20
|
+
notice?: string;
|
|
21
|
+
}
|
|
22
|
+
/** The file exists but cannot be read or is not a credentials file this version understands. */
|
|
23
|
+
export declare class CredentialsFileError extends Error {
|
|
24
|
+
constructor(message: string);
|
|
25
|
+
}
|
|
26
|
+
export declare function defaultCredentialsPath(): string;
|
|
27
|
+
/** Origin plus path, no trailing slash — the entry name `npx @proof-holdings/mcp-server login` saves under. */
|
|
28
|
+
export declare function credentialKey(baseUrl: string): string;
|
|
29
|
+
/** Explicit, else a non-empty PROOF_BASE_URL, else the default. */
|
|
30
|
+
export declare function resolveBaseUrl(explicit?: string, env?: NodeJS.ProcessEnv): string;
|
|
31
|
+
/** The parsed file, `null` when there is none, `CredentialsFileError` when it is unreadable or malformed. */
|
|
32
|
+
export declare function readCredentialsFile(file: string): CredentialsFile | null;
|
|
33
|
+
/**
|
|
34
|
+
* The chain: an explicit key as given (the constructor decides whether `''` is acceptable), else a
|
|
35
|
+
* non-empty `PROOF_API_KEY`, else the saved entry for exactly `baseUrl`, else none. A broken file or
|
|
36
|
+
* a base URL that is not a URL never throws here — it becomes a notice on the `none` answer.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveApiKey(opts: {
|
|
39
|
+
explicit?: string;
|
|
40
|
+
baseUrl: string;
|
|
41
|
+
file?: string;
|
|
42
|
+
env?: NodeJS.ProcessEnv;
|
|
43
|
+
}): ResolvedKey;
|
|
44
|
+
/** The one message a missing key produces, whatever road the caller tried. */
|
|
45
|
+
export declare function missingKeyMessage(baseUrl: string, notice?: string): string;
|
|
46
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/credentials.ts"],"names":[],"mappings":"AAiBA,gIAAgI;AAChI,eAAO,MAAM,aAAa,yCAAyC,CAAC;AACpE,eAAO,MAAM,gBAAgB,+BAA+B,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,YAAY,GAAG,MAAM,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,CAAC;IACX,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC/C;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,CAAC;IAClB,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,gGAAgG;AAChG,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,+GAA+G;AAC/G,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE9F;AAcD,6GAA6G;AAC7G,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAsBxE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,GAAG,WAAW,CAgC/H;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAM1E"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CredentialsFileError = exports.DEFAULT_BASE_URL = exports.LOGIN_COMMAND = void 0;
|
|
4
|
+
exports.defaultCredentialsPath = defaultCredentialsPath;
|
|
5
|
+
exports.credentialKey = credentialKey;
|
|
6
|
+
exports.resolveBaseUrl = resolveBaseUrl;
|
|
7
|
+
exports.readCredentialsFile = readCredentialsFile;
|
|
8
|
+
exports.resolveApiKey = resolveApiKey;
|
|
9
|
+
exports.missingKeyMessage = missingKeyMessage;
|
|
10
|
+
/**
|
|
11
|
+
* Where the key comes from when `new Proof()` is given none.
|
|
12
|
+
*
|
|
13
|
+
* The chain is the MCP server's (`mcp/src/credentials.ts`, the reference): a non-empty
|
|
14
|
+
* `PROOF_API_KEY`, else the entry `npx @proof-holdings/mcp-server login` saved for exactly this
|
|
15
|
+
* base URL in `~/.proof-holdings/credentials`, else none. It runs ONLY when the key argument is
|
|
16
|
+
* omitted — an explicit key is used as given, and an explicit empty one is the caller's error and
|
|
17
|
+
* never reads the environment or the file (a multi-tenant host passing a tenant's key must not
|
|
18
|
+
* fall through to its own). The shared cases in `sdks/shared/fixtures/credentials/cases.json`
|
|
19
|
+
* hold this module and the other three SDKs to the reference.
|
|
20
|
+
*
|
|
21
|
+
* Node built-ins only, like the reference: the client imports this on every construction.
|
|
22
|
+
*/
|
|
23
|
+
const node_fs_1 = require("node:fs");
|
|
24
|
+
const node_os_1 = require("node:os");
|
|
25
|
+
const node_path_1 = require("node:path");
|
|
26
|
+
/** The scoped command, never the bare bin name: through npx the unscoped name resolves to a package somebody else publishes. */
|
|
27
|
+
exports.LOGIN_COMMAND = 'npx @proof-holdings/mcp-server login';
|
|
28
|
+
exports.DEFAULT_BASE_URL = 'https://api.proof.holdings';
|
|
29
|
+
/** The file exists but cannot be read or is not a credentials file this version understands. */
|
|
30
|
+
class CredentialsFileError extends Error {
|
|
31
|
+
constructor(message) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = 'CredentialsFileError';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.CredentialsFileError = CredentialsFileError;
|
|
37
|
+
function defaultCredentialsPath() {
|
|
38
|
+
return (0, node_path_1.join)((0, node_os_1.homedir)(), '.proof-holdings', 'credentials');
|
|
39
|
+
}
|
|
40
|
+
/** Origin plus path, no trailing slash — the entry name `npx @proof-holdings/mcp-server login` saves under. */
|
|
41
|
+
function credentialKey(baseUrl) {
|
|
42
|
+
const url = new URL(baseUrl);
|
|
43
|
+
return url.origin + url.pathname.replace(/\/+$/, '');
|
|
44
|
+
}
|
|
45
|
+
/** Explicit, else a non-empty PROOF_BASE_URL, else the default. */
|
|
46
|
+
function resolveBaseUrl(explicit, env = process.env) {
|
|
47
|
+
return explicit ?? (env.PROOF_BASE_URL || exports.DEFAULT_BASE_URL);
|
|
48
|
+
}
|
|
49
|
+
function isStoredCredential(value) {
|
|
50
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
51
|
+
return false;
|
|
52
|
+
const v = value;
|
|
53
|
+
return (typeof v.api_key === 'string' && v.api_key.startsWith('pk_') &&
|
|
54
|
+
typeof v.key_id === 'string' &&
|
|
55
|
+
typeof v.name === 'string' &&
|
|
56
|
+
typeof v.created_at === 'string' &&
|
|
57
|
+
(v.environment === 'production' || v.environment === 'test'));
|
|
58
|
+
}
|
|
59
|
+
/** The parsed file, `null` when there is none, `CredentialsFileError` when it is unreadable or malformed. */
|
|
60
|
+
function readCredentialsFile(file) {
|
|
61
|
+
let raw;
|
|
62
|
+
try {
|
|
63
|
+
raw = (0, node_fs_1.readFileSync)(file, 'utf8');
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
if (e.code === 'ENOENT')
|
|
67
|
+
return null;
|
|
68
|
+
throw new CredentialsFileError(`cannot read ${file}: ${e.message}`);
|
|
69
|
+
}
|
|
70
|
+
let parsed;
|
|
71
|
+
try {
|
|
72
|
+
parsed = JSON.parse(raw);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
throw new CredentialsFileError(`${file} is not valid JSON`);
|
|
76
|
+
}
|
|
77
|
+
const p = parsed;
|
|
78
|
+
if (!p || typeof p !== 'object' || p.version !== 1 || !p.credentials || typeof p.credentials !== 'object' || Array.isArray(p.credentials)) {
|
|
79
|
+
throw new CredentialsFileError(`${file} is not a version 1 Proof credentials file`);
|
|
80
|
+
}
|
|
81
|
+
for (const [key, value] of Object.entries(p.credentials)) {
|
|
82
|
+
if (!isStoredCredential(value))
|
|
83
|
+
throw new CredentialsFileError(`${file} has a malformed entry for ${key}`);
|
|
84
|
+
}
|
|
85
|
+
return p;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The chain: an explicit key as given (the constructor decides whether `''` is acceptable), else a
|
|
89
|
+
* non-empty `PROOF_API_KEY`, else the saved entry for exactly `baseUrl`, else none. A broken file or
|
|
90
|
+
* a base URL that is not a URL never throws here — it becomes a notice on the `none` answer.
|
|
91
|
+
*/
|
|
92
|
+
function resolveApiKey(opts) {
|
|
93
|
+
if (typeof opts.explicit === 'string')
|
|
94
|
+
return { apiKey: opts.explicit, source: 'explicit' };
|
|
95
|
+
const env = opts.env ?? process.env;
|
|
96
|
+
if (env.PROOF_API_KEY)
|
|
97
|
+
return { apiKey: env.PROOF_API_KEY, source: 'env' };
|
|
98
|
+
let file;
|
|
99
|
+
try {
|
|
100
|
+
file = opts.file ?? defaultCredentialsPath();
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// No home directory to look in (a sandbox without one): the same answer as no file.
|
|
104
|
+
return { source: 'none' };
|
|
105
|
+
}
|
|
106
|
+
let contents;
|
|
107
|
+
try {
|
|
108
|
+
contents = readCredentialsFile(file);
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
return {
|
|
112
|
+
source: 'none',
|
|
113
|
+
notice: `ignoring the saved credentials — ${e.message}. Fix or delete ${file}, then run ${exports.LOGIN_COMMAND}.`,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (!contents)
|
|
117
|
+
return { source: 'none' };
|
|
118
|
+
let key;
|
|
119
|
+
try {
|
|
120
|
+
key = credentialKey(opts.baseUrl);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return {
|
|
124
|
+
source: 'none',
|
|
125
|
+
notice: `the base URL ${JSON.stringify(opts.baseUrl)} is not a URL, so the saved credentials in ${file} were not read.`,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const entry = contents.credentials[key];
|
|
129
|
+
return entry ? { apiKey: entry.api_key, source: 'file' } : { source: 'none' };
|
|
130
|
+
}
|
|
131
|
+
/** The one message a missing key produces, whatever road the caller tried. */
|
|
132
|
+
function missingKeyMessage(baseUrl, notice) {
|
|
133
|
+
return (`API key is required. Pass your key as the first argument: new Proof("pk_live_..."), ` +
|
|
134
|
+
`set PROOF_API_KEY, or run \`${exports.LOGIN_COMMAND}\` to save one for ${baseUrl}.` +
|
|
135
|
+
(notice ? ` ${notice}` : ''));
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/credentials.ts"],"names":[],"mappings":"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"}
|