@terminal3/t3n-sdk 1.2.1 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,12 +7,21 @@
7
7
  import { T3nClientConfig } from "./config";
8
8
  import { type ContractResponseSchema } from "./contract-response";
9
9
  import { SessionId, Did, SessionStatus, AuthInput, HandshakeResult } from "../types";
10
+ import { KycPollOptions, KycStatus } from "../types/kyc";
10
11
  /**
11
12
  * Main T3n SDK Client
12
13
  */
13
14
  export declare class T3nClient {
14
15
  private readonly config;
15
16
  private readonly transport;
17
+ /**
18
+ * Resolved node base URL. Snapshotted in the constructor so the
19
+ * typed contract wrappers (`kycStatus`, `getSelfEthAddress`, …)
20
+ * can call `getScriptVersion()` against the same host the
21
+ * transport talks to. Used only by the `script_version: "latest"`
22
+ * resolution path in {@link executeUserContract}.
23
+ */
24
+ private readonly effectiveBaseUrl;
16
25
  /**
17
26
  * Server-minted session ID, set by {@link handshake} from the
18
27
  * `Session-Id` response header (pentest M-1 / MAT-983). `null`
@@ -108,6 +117,32 @@ export declare class T3nClient {
108
117
  * @throws {ContractResponseError} when the response is not valid JSON
109
118
  */
110
119
  executeAndDecode<T = unknown>(payload: unknown, schema?: ContractResponseSchema<T>): Promise<T>;
120
+ /**
121
+ * Build the canonical `ExecuteActionRequest` shape the server
122
+ * expects in `node/primitives/src/action.rs::ExecuteActionRequest`
123
+ * (`script_name`, `script_version`, `function_name`, `input`,
124
+ * optional `pii_did`) and dispatch it through {@link execute}.
125
+ *
126
+ * Two pieces of glue live here that every typed user-contract
127
+ * wrapper would otherwise duplicate:
128
+ *
129
+ * 1. **Field naming.** The server deserialises strictly into
130
+ * `script_name` / `script_version` / `function_name` —
131
+ * sending `contract` / `version` / `function` produces
132
+ * `Invalid action request: missing field …` 400s. Centralising
133
+ * the names here means every wrapper agrees with the server.
134
+ * 2. **`"latest"` resolution.** `script_version` is `SemVer` on
135
+ * the server, so a literal `"latest"` cannot be parsed. We
136
+ * fetch the registered current version via
137
+ * `GET /api/contracts/current?name=…` (cached per script name
138
+ * in `getScriptVersion`) and forward the resolved
139
+ * `MAJOR.MINOR.PATCH` string.
140
+ *
141
+ * Wrappers that need PII delegation can extend this helper
142
+ * later — current call sites are all SelfOnly so `pii_did` stays
143
+ * implicit.
144
+ */
145
+ private executeUserContract;
111
146
  /**
112
147
  * Return the authenticated user's Ethereum address from their
113
148
  * T3N-hosted per-user wallet, as a 0x-prefixed lowercase hex string.
@@ -182,6 +217,57 @@ export declare class T3nClient {
182
217
  * the response cannot be decoded.
183
218
  */
184
219
  removeUserWithWalletAbandonment(): Promise<unknown>;
220
+ /**
221
+ * One-shot poll of `tee:user/contracts::kyc-status`.
222
+ *
223
+ * Returns the current snapshot of the authenticated user's Level 2
224
+ * KYC state — see [[KycStatus]] for the four possible terminal /
225
+ * non-terminal values. The caller usually wants
226
+ * [[kycStatusPoll]] (which loops with §8.4 cadence until a
227
+ * terminal status arrives), but the bare snapshot is useful for
228
+ * pages that need to render the user's standing without waiting
229
+ * (e.g. account-status views, "did the user finish KYC last time
230
+ * they were here?" gates).
231
+ *
232
+ * Phase one default — `providerId` defaults to `"veriff"` (the
233
+ * contract applies the same default when the field is absent),
234
+ * so the most common call site is `await t3n.kycStatus()`.
235
+ *
236
+ * @param providerId optional provider id, mirrored on the wire as
237
+ * `input.provider_id`. Omit for phase-one MetaMask flows.
238
+ * @throws if unauthenticated, if the node rejects the action
239
+ * (e.g. `precondition_failed:` when no `create-kyc-provider-session`
240
+ * row exists yet), or if the response shape is unexpected.
241
+ */
242
+ kycStatus(providerId?: string): Promise<KycStatus>;
243
+ /**
244
+ * Poll `kyc-status` until a terminal status arrives or the
245
+ * configured timeout elapses.
246
+ *
247
+ * Cadence defaults to T3-TS-026 §8.4: 2-second interval for the
248
+ * first 30 seconds, then 5 seconds, with a 5-minute hard cap.
249
+ * Override via `opts.cadence` if you need different numbers
250
+ * (e.g. tests that don't want to wait the full 30 seconds before
251
+ * the slow window kicks in). [[KycStatusTimeoutError]] is thrown
252
+ * if the timeout elapses without reaching a terminal state.
253
+ *
254
+ * `opts.signal` cancels the loop synchronously — the helper
255
+ * stops sleeping and rejects with the abort reason; an
256
+ * already-in-flight `kycStatus()` request is allowed to settle
257
+ * but its result is discarded.
258
+ *
259
+ * `opts.onUpdate` fires once per snapshot, including
260
+ * intermediate `pending` ones. Errors thrown from the callback
261
+ * are swallowed so a misbehaving UI handler can't strand the
262
+ * poll loop.
263
+ *
264
+ * @throws [[KycStatusTimeoutError]] when the cadence's
265
+ * `timeoutMs` elapses without a terminal status.
266
+ * @throws the abort reason when `opts.signal` is aborted.
267
+ * @throws the underlying RPC error when the contract or
268
+ * transport raises (e.g. session expiry mid-poll).
269
+ */
270
+ kycStatusPoll(opts?: KycPollOptions): Promise<KycStatus>;
185
271
  /**
186
272
  * The server-minted session ID once handshake has completed, or
187
273
  * `null` beforehand (pentest M-1 / MAT-983).
@@ -16,6 +16,8 @@ export type { Transport, JsonRpcRequest, JsonRpcResponse } from "./client";
16
16
  export { HttpTransport, MockTransport } from "./client";
17
17
  export type { SessionId, Did, OidcCredentials, AuthInput, EthAuthInput, OidcAuthInput, GuestToHostHandler, GuestToHostHandlers, } from "./types";
18
18
  export { SessionStatus, AuthMethod, createEthAuthInput, createOidcAuthInput, } from "./types";
19
+ export type { KycStatus, KycStatusKind, KycPollOptions, KycPollCadence, } from "./types/kyc";
20
+ export { DEFAULT_KYC_POLL_CADENCE, TERMINAL_KYC_STATUSES, KycStatusTimeoutError, } from "./types/kyc";
19
21
  export { metamask_sign, metamask_get_address, eth_get_address, createDefaultHandlers, createMlKemPublicKeyHandler, createRandomHandler, } from "./client/handlers";
20
22
  export type { WasmComponent, ClientHandshake, ClientAuth, SessionCrypto, WasmNextResult, } from "./wasm";
21
23
  export { loadWasmComponent } from "./wasm";
@@ -0,0 +1,135 @@
1
+ /**
2
+ * KYC types for the `tee:user/contracts::kyc-status` short-poll
3
+ * function added in MAT-1202.
4
+ *
5
+ * The shape mirrors `tee_contracts/user/src/kyc_status.rs::KycStatusResponse`.
6
+ * Keep the two in sync — the bytes go straight from the contract
7
+ * through the JSON-RPC envelope into [[T3nClient.kycStatus]].
8
+ */
9
+ import { T3nError } from "../utils/errors";
10
+ /**
11
+ * Terminal status for a Level 2 KYC verification, plus `pending`.
12
+ *
13
+ * - `pending` — provider has not delivered a verdict yet, or the
14
+ * webhook arrived but the post-action VC issuance hasn't completed.
15
+ * - `verified` — provider approved AND a VC has been issued. `vcIds`
16
+ * carries the issued credential ids.
17
+ * - `rejected` — provider declined / required resubmission /
18
+ * expired / the user abandoned the flow. `error` may carry a
19
+ * provider-supplied reason.
20
+ * - `orphan` — a Veriff webhook arrived with a `vendorData` that
21
+ * couldn't be matched to any user (T3-TS-024 §3.4). Should not
22
+ * happen in the MetaMask flow but the contract surfaces it for
23
+ * completeness.
24
+ */
25
+ export type KycStatusKind = "pending" | "verified" | "rejected" | "orphan";
26
+ /**
27
+ * Snapshot returned by `tee:user/contracts::kyc-status`.
28
+ *
29
+ * Field names use camelCase on the SDK boundary even though the
30
+ * wire is snake_case — the wrapper rewrites keys at the client edge
31
+ * so callers don't see the JSON shape leaking through.
32
+ */
33
+ export interface KycStatus {
34
+ /** Terminal status if reached, otherwise `pending`. */
35
+ status: KycStatusKind;
36
+ /**
37
+ * Provider being polled. Echoed back so callers that didn't
38
+ * supply one see the contract's default (`"veriff"` in phase one).
39
+ */
40
+ provider: string;
41
+ /**
42
+ * Unix-millis of the latest contract-visible event:
43
+ * VC issuance time, attestation arrival time, session-row
44
+ * `started_at_ms`, or orphan-record arrival time. Best-effort —
45
+ * `undefined` when no source carries a usable timestamp.
46
+ */
47
+ updatedAt?: number;
48
+ /**
49
+ * VC ids appended for this provider, in append order. Empty for
50
+ * `pending` / `rejected` / `orphan`.
51
+ */
52
+ vcIds: string[];
53
+ /**
54
+ * Provider-supplied reason for `rejected`, when available.
55
+ */
56
+ error?: string;
57
+ }
58
+ /**
59
+ * Polling cadence for [[T3nClient.kycStatusPoll]]. Defaults match
60
+ * T3-TS-026 §8.4: poll fast for the first 30 seconds, then back
61
+ * off, and bail after 5 minutes.
62
+ */
63
+ export interface KycPollCadence {
64
+ /** Poll interval in ms while `elapsed < switchAtMs`. Default: 2000. */
65
+ fastMs: number;
66
+ /** Poll interval in ms once `elapsed >= switchAtMs`. Default: 5000. */
67
+ slowMs: number;
68
+ /** Elapsed-ms threshold to switch from fast to slow cadence. Default: 30_000. */
69
+ switchAtMs: number;
70
+ /**
71
+ * Maximum total time to spend polling before rejecting with
72
+ * [[KycStatusTimeoutError]]. Default: 300_000 (5 minutes).
73
+ */
74
+ timeoutMs: number;
75
+ }
76
+ /**
77
+ * Optional knobs for [[T3nClient.kycStatusPoll]]. Most callers won't
78
+ * touch any of these — the §8.4 defaults are baked in.
79
+ */
80
+ export interface KycPollOptions {
81
+ /**
82
+ * Cancellation signal. When aborted, the helper rejects with
83
+ * `signal.reason` (or a generic `AbortError` if the consumer
84
+ * didn't supply a reason). The currently-in-flight `kycStatus()`
85
+ * call also receives the signal so it can short-circuit.
86
+ */
87
+ signal?: AbortSignal;
88
+ /**
89
+ * Called with every snapshot the helper receives, including
90
+ * non-terminal `pending` ones. Useful for surfacing intermediate
91
+ * UI states (e.g. "still waiting on provider…"). Errors thrown
92
+ * from this callback are caught and ignored — they must not
93
+ * sink the poll loop.
94
+ */
95
+ onUpdate?: (status: KycStatus) => void;
96
+ /**
97
+ * Override one or more cadence fields. Anything not specified
98
+ * uses the §8.4 defaults from [[DEFAULT_KYC_POLL_CADENCE]].
99
+ */
100
+ cadence?: Partial<KycPollCadence>;
101
+ /**
102
+ * Provider id to poll. Defaults to the contract default
103
+ * (`"veriff"` in phase one). Mirrored on the wire as
104
+ * `input.provider_id`.
105
+ */
106
+ providerId?: string;
107
+ }
108
+ /**
109
+ * Default cadence used by [[T3nClient.kycStatusPoll]] when the caller
110
+ * doesn't override `cadence.*`. Matches T3-TS-026 §8.4 verbatim.
111
+ */
112
+ export declare const DEFAULT_KYC_POLL_CADENCE: KycPollCadence;
113
+ /**
114
+ * Subset of [[KycStatusKind]] that ends a poll. `pending` is the
115
+ * only non-terminal value.
116
+ */
117
+ export declare const TERMINAL_KYC_STATUSES: ReadonlySet<KycStatusKind>;
118
+ /**
119
+ * Thrown by [[T3nClient.kycStatusPoll]] when the cadence's
120
+ * `timeoutMs` elapses without a terminal status arriving. The
121
+ * `lastStatus` field is the most recent (necessarily `pending`)
122
+ * snapshot the helper saw, useful for surfacing "we tried for N
123
+ * minutes but Veriff is still working" UX.
124
+ */
125
+ export declare class KycStatusTimeoutError extends T3nError {
126
+ /** The §8.4 timeout the helper exhausted. */
127
+ readonly timeoutMs: number;
128
+ /** The last `pending` snapshot before timeout, if any. */
129
+ readonly lastStatus?: KycStatus | undefined;
130
+ constructor(
131
+ /** The §8.4 timeout the helper exhausted. */
132
+ timeoutMs: number,
133
+ /** The last `pending` snapshot before timeout, if any. */
134
+ lastStatus?: KycStatus | undefined);
135
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@terminal3/t3n-sdk",
3
- "version": "1.2.1",
3
+ "version": "1.3.2",
4
4
  "type": "module",
5
5
  "description": "T3n TypeScript SDK - A minimal SDK that mirrors the server's RPC handler approach",
6
6
  "main": "dist/index.js",
@@ -107,7 +107,8 @@
107
107
  "overrides": {
108
108
  "rollup": ">=4.59.0",
109
109
  "esbuild": ">=0.25.0",
110
- "minimatch": ">=9.0.7"
110
+ "minimatch": ">=9.0.7",
111
+ "postcss": ">=8.5.10"
111
112
  }
112
113
  }
113
- }
114
+ }