@terminal3/t3n-sdk 4.32.0 → 4.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -933,1299 +933,932 @@ declare class ContractResponseError extends T3nError {
933
933
  declare function parseContractResponse<T = unknown>(raw: string, schema?: ContractResponseSchema<T>): T;
934
934
 
935
935
  /**
936
- * Org-data wire types mirroring the org-data contract wire shapes.
937
- *
938
- * Plain TypeScript interfaces (no zod) — the SDK does not use a
939
- * validation library for domain types; see the existing `types/` files.
936
+ * Agent-auth grants — the standing on-chain authority a user delegates to
937
+ * an agent (envelope-free authorisation).
940
938
  *
941
- * Each response type below is paired with a shallow runtime predicate
942
- * (`isMutationResponse`, `isOrgPolicyMeta`, etc.) so the org-data client
943
- * can `assertShape` the decoded payload before returning to callers.
944
- * Predicates check the top-level structure only; nested elements
945
- * (e.g. each `BoundGrant` inside `OrgContractGrants.grants`) are not
946
- * deeply validated — see `utils/shape.ts` for the rationale.
939
+ * `AGENT_AUTH_MAP` is keyed by the *user* DID — one policy document per
940
+ * user, global across orgs, with at most one entry per agent DID. Reads
941
+ * (`agent-auth-get`) and writes (`agent-auth-update`) on
942
+ * `tee:authorisations/contracts` (the policy's owning contract) are
943
+ * **SelfOnly**: only the user, authenticated as themselves, may read or
944
+ * write their own grants. This is the user-approval
945
+ * proof the per-call delegation credential's `user_sig` used to carry.
946
+ *
947
+ * The write shape gained `scopes` + a validity window: the
948
+ * agent's delegated org-data scopes, and an optional `[valid_from_secs,
949
+ * valid_until_secs]` window. The ≤ cap *length* check is enforced contract-
950
+ * side at write time; the expiry gate is host-side at read time.
951
+ *
952
+ * The merge below is a script-level union (R59): writing a grant for one
953
+ * `(agent_did, script_name)` preserves every other script row on that
954
+ * agent's entry, and every other agent's entry, unchanged.
955
+ */
956
+ /** A single script grant in the camelCase write-request shape. */
957
+ interface AgentAuthScriptGrant {
958
+ /** Contract name, or `"*"`. */
959
+ scriptName: string;
960
+ /** Optional semver requirement; `null` to match any version. */
961
+ versionReq?: string | null;
962
+ /** Functions the agent may invoke on this contract. */
963
+ functions: string[];
964
+ /** Org-data scopes delegated to the agent for the contract functions to
965
+ * read on its behalf. */
966
+ scopes?: string[];
967
+ /** Direct-read scopes the agent may enumerate itself, via whichever read
968
+ * function the contract exposes for direct enumeration. A strict subset of
969
+ * `scopes` (enforced contract-side). */
970
+ readScopes?: string[];
971
+ /** Optional validity-window start (unix seconds). */
972
+ validFromSecs?: number | null;
973
+ /** NEW: optional validity-window end (unix seconds). */
974
+ validUntilSecs?: number | null;
975
+ /** Egress hosts the agent may reach for this contract. */
976
+ allowedHosts: string[];
977
+ }
978
+ /** One agent's entry in the write-request shape. */
979
+ interface AgentAuthEntry {
980
+ agentDid: string;
981
+ scripts: AgentAuthScriptGrant[];
982
+ }
983
+ /**
984
+ * The full agent-auth policy document in the camelCase write shape:
985
+ * the per-agent grants plus the document-level discovery grants.
947
986
  *
948
- * Reference: the org-data wire contract.
987
+ * `discoverDids` (contract wire: `discover_dids`) is the
988
+ * list of DIDs the user lets their registered agents *enumerate the
989
+ * contracts of* via `listContracts`: an org DID grants org-mode discovery,
990
+ * the user's own DID grants self-mode discovery. It lives at document
991
+ * level — not on a script grant — because discovery must surface contracts
992
+ * the agent cannot yet call. The node's discovery gate additionally
993
+ * requires the calling agent to be named in `agents` (subject binding), so
994
+ * an unregistered agent discovers nothing regardless of this list.
949
995
  */
996
+ interface AgentAuthPolicy {
997
+ agents: AgentAuthEntry[];
998
+ discoverDids: string[];
999
+ }
950
1000
  /**
951
- * Validity time-box on an agent-edge grant — serialised under the JSON key
952
- * `window`. Both bounds are optional unix-seconds; an omitted bound is
953
- * defaulted contract-side (`valid_from_secs` → now, `valid_until_secs` → now +
954
- * operator cap). Mirrors the org-data `Validity` wire shape. Absent bounds
955
- * are omitted from the wire (never sent as `null`).
1001
+ * Parse a full `agent-auth-get` response (the stored snake_case policy
1002
+ * document) into the camelCase write shape, including the document-level
1003
+ * `discover_dids`. A `null` / absent response is the empty policy.
956
1004
  */
957
- interface Validity {
958
- valid_from_secs?: number;
959
- valid_until_secs?: number;
1005
+ declare function parseAgentAuthPolicy(response: unknown): AgentAuthPolicy;
1006
+ /** Extract the `agents` array from an `agent-auth-get` response. */
1007
+ declare function parseAgentAuthGet(response: unknown): AgentAuthEntry[];
1008
+ interface AgentAuthMergeResult {
1009
+ /** Full merged `agents` list, ready for `agent-auth-update`. */
1010
+ agents: AgentAuthEntry[];
1011
+ /** `"<agentDid> → <scriptName>"` rows preserved from the existing policy. */
1012
+ preservedRows: string[];
960
1013
  }
1014
+ /** Input to the full-document write {@link T3nClient.agentAuthUpdate}. The
1015
+ * document IS the new state: an empty `agents` list revokes all agent
1016
+ * access, and an omitted / empty `discoverDids` persists an empty
1017
+ * discovery-grant list (the contract has no per-field merge). Mirrors the
1018
+ * contract `AgentAuthPolicy`. */
1019
+ interface AgentAuthUpdateInput {
1020
+ agents: AgentAuthEntry[];
1021
+ /** Document-level discovery grants — see {@link AgentAuthPolicy}. */
1022
+ discoverDids?: string[];
1023
+ }
1024
+ /**
1025
+ * Serialise a camelCase policy document to the contract's canonical
1026
+ * snake_case `agent-auth-update` wire (`agent_did` / `script_name` /
1027
+ * `version_req` / `read_scopes` / `valid_from_secs` / `valid_until_secs` /
1028
+ * `allowed_hosts` / `discover_dids`), so neither write path relies on the
1029
+ * contract's compatibility aliases. Absent optionals are omitted (never
1030
+ * sent as `null`); empty `scopes` / `read_scopes` are omitted (the
1031
+ * contract defaults both to empty). `functions` and `allowed_hosts` are
1032
+ * always emitted — the contract requires explicit functions (`["*"]` =
1033
+ * all) and reads an absent `allowed_hosts` as deny-all egress. The
1034
+ * document-level `discover_dids` (strictly snake_case — the contract
1035
+ * defines no camelCase alias for it) is emitted only when non-empty; the
1036
+ * contract defaults an absent list to empty.
1037
+ */
1038
+ declare function toAgentAuthUpdateWire(agents: AgentAuthEntry[], discoverDids?: string[]): {
1039
+ agents: Array<{
1040
+ agent_did: string;
1041
+ scripts: Array<Record<string, unknown>>;
1042
+ }>;
1043
+ discover_dids?: string[];
1044
+ };
1045
+ /**
1046
+ * Order-preserving deduplicating union of discovery-grant DID lists —
1047
+ * the read-merge-write counterpart of {@link mergeAgentAuthEntries} for
1048
+ * the document-level `discoverDids` (the contract rejects duplicate
1049
+ * entries, so the union must dedupe).
1050
+ */
1051
+ declare function mergeDiscoverDids(existing: string[], additions: string[]): string[];
1052
+ /**
1053
+ * Merge new agent entries into the existing policy with script-level union
1054
+ * semantics: for an agent DID present on both sides, script rows whose
1055
+ * `scriptName` is not being written are preserved; rows with a matching
1056
+ * `scriptName` are replaced by the new grant. Entries for other agent DIDs
1057
+ * pass through unchanged.
1058
+ */
1059
+ declare function mergeAgentAuthEntries(existing: AgentAuthEntry[], newEntries: AgentAuthEntry[]): AgentAuthMergeResult;
1060
+
961
1061
  /**
962
- * A grantee-bound capability grant — the element of BOTH grant-management
963
- * surfaces: the org edge (`org-policy-set-grants` input / `org-grants-get`
964
- * output) and the flat agent edge (`agent-auth-get` output / `agent-auth-update`
965
- * input). Stored inline on the unified `ROLE_ASSIGNMENTS_MAP` edge record.
1062
+ * KYC types for the `tee:user/contracts::kyc-status` short-poll
1063
+ * function.
966
1064
  *
967
- * Mirrors the org-data `BoundGrant` wire shape verbatim (snake_case, no casing
968
- * transform): `grantee` followed by the flattened capability body. The org edge
969
- * populates only `functions` + `scopes`; the agent edge additionally carries the
970
- * qualifiers `version_req` / `read_scopes` / `allowed_hosts` and the validity
971
- * `window`. All qualifier fields are optional and omitted from the wire when
972
- * absent (never sent as `null`), so an org grant simply leaves them unset.
1065
+ * The shape mirrors the `kyc-status` wire response.
1066
+ * The bytes go straight from the contract
1067
+ * through the JSON-RPC envelope into [[T3nClient.kycStatus]].
973
1068
  */
974
- interface BoundGrant {
975
- /** The principal (`did:t3n:<40-hex>`) this grant applies to — a user or an
976
- * agent DID. */
977
- grantee: string;
978
- /** Target contract id (canonical name, e.g. `"tee:z-payroll/contracts"`), or
979
- * `"*"`. On a read this echoes the queried contract. */
980
- contract_id: string;
981
- /** WIT function names the grantee may invoke (e.g. `"set-records"`; `["*"]`
982
- * matches all). */
983
- functions: string[];
984
- /** Data scope paths the grantee may access (e.g. `"example/records"`). */
985
- scopes: string[];
986
- /** Agent edge only: optional semver requirement; omitted matches any version. */
987
- version_req?: string;
988
- /** Agent edge only: direct-read scopes the grantee may enumerate itself — a
989
- * subset of `scopes` (enforced contract-side). */
990
- read_scopes?: string[];
991
- /** Agent edge only: egress hosts the grantee may reach for this contract. */
992
- allowed_hosts?: string[];
993
- /** Agent edge only: optional validity time-box. */
994
- window?: Validity;
995
- }
1069
+
996
1070
  /**
997
- * Policy record for an organisation's data tier.
1071
+ * Terminal status for a Level 2 KYC verification, plus `pending`.
998
1072
  *
999
- * Mirrors the org-data policy-meta wire shape.
1073
+ * - `pending` — provider has not delivered a verdict yet, or the
1074
+ * webhook arrived but the post-action VC issuance hasn't completed.
1075
+ * - `verified` — provider approved AND a VC has been issued. `vcIds`
1076
+ * carries the issued credential ids.
1077
+ * - `rejected` — provider declined / required resubmission /
1078
+ * expired / the user abandoned the flow. `error` may carry a
1079
+ * provider-supplied reason.
1080
+ * - `orphan` — a Veriff webhook arrived with a `vendorData` that
1081
+ * couldn't be matched to any user. Should not
1082
+ * happen in the MetaMask flow but the contract surfaces it for
1083
+ * completeness.
1000
1084
  */
1001
- interface OrgPolicyMeta {
1002
- /** DIDs (`did:t3n:<40-hex>`) of users authorised to manage policy and read data. */
1003
- admins: string[];
1004
- /** Maximum number of admins allowed for this org. */
1005
- max_admins: number;
1006
- /** Unix timestamp (secs) when the policy was first created. */
1007
- created_at_secs: number;
1008
- /** Unix timestamp (secs) of the most recent policy update. */
1009
- updated_at_secs: number;
1010
- /**
1011
- * Per-org ceiling on delegation-credential validity (seconds).
1012
- *
1013
- * Absent when no org-level cap is set — the contract omits the field
1014
- * (never serialises null) and the cluster-wide
1015
- * `delegation.max_credential_validity_secs` governs instead. When set,
1016
- * the effective cap is `min(max_credential_validity_secs, cluster_ceiling)`.
1017
- */
1018
- max_credential_validity_secs?: number;
1019
- }
1020
- /** Shallow runtime guard for {@link OrgPolicyMeta}. */
1021
- declare function isOrgPolicyMeta(value: unknown): value is OrgPolicyMeta;
1085
+ type KycStatusKind = "pending" | "verified" | "rejected" | "orphan";
1022
1086
  /**
1023
- * Effective org policy view returned by `org-policy-view`.
1087
+ * Snapshot returned by `tee:user/contracts::kyc-status`.
1024
1088
  *
1025
- * Readable by any authenticated session (non-sensitive metadata).
1026
- * Returns the **effective** credential validity cap:
1027
- * `min(org.max_credential_validity_secs, cluster_ceiling)`, equal to the
1028
- * cluster ceiling when the org has not set a per-org cap. The contract
1029
- * always returns a value (or errors) — the field is never null.
1089
+ * Field names use camelCase on the SDK boundary even though the
1090
+ * wire is snake_case — the wrapper rewrites keys at the client edge
1091
+ * so callers don't see the JSON shape leaking through.
1030
1092
  */
1031
- interface OrgPolicyView {
1093
+ interface KycStatus {
1094
+ /** Terminal status if reached, otherwise `pending`. */
1095
+ status: KycStatusKind;
1032
1096
  /**
1033
- * Effective delegation-credential validity cap in seconds:
1034
- * `min(org value, cluster ceiling)`, equal to the cluster ceiling when the
1035
- * org has not set a per-org cap. Always present — mirrors the contract's
1036
- * `PolicyViewResponse.effective_validity_secs` (org-data `org-policy-view`).
1097
+ * Provider being polled. Echoed back so callers that didn't
1098
+ * supply one see the contract's default (`"veriff"` in phase one).
1037
1099
  */
1038
- effective_validity_secs: number;
1100
+ provider: string;
1101
+ /**
1102
+ * Unix-millis of the latest contract-visible event:
1103
+ * VC issuance time, attestation arrival time, session-row
1104
+ * `started_at_ms`, or orphan-record arrival time. Best-effort —
1105
+ * `undefined` when no source carries a usable timestamp.
1106
+ */
1107
+ updatedAt?: number;
1108
+ /**
1109
+ * VC ids appended for this provider, in append order. Empty for
1110
+ * `pending` / `rejected` / `orphan`.
1111
+ */
1112
+ vcIds: string[];
1113
+ /**
1114
+ * Provider-supplied reason for `rejected`, when available.
1115
+ */
1116
+ error?: string;
1039
1117
  }
1040
- /** Shallow runtime guard for {@link OrgPolicyView}. */
1041
- declare function isOrgPolicyView(value: unknown): value is OrgPolicyView;
1042
1118
  /**
1043
- * Caller-scoped admin status returned by `org-am-i-admin`.
1044
- *
1045
- * Reports only whether the **calling** session's DID is in the org's admin
1046
- * list — never the roster itself (contrast {@link OrgPolicyMeta}, returned by
1047
- * the admin-gated `org-policy-get`). Readable by any authenticated session.
1048
- * Mirrors the org-data `AmIAdminResponse` wire shape.
1119
+ * Polling cadence for [[T3nClient.kycStatusPoll]]. Defaults:
1120
+ * poll fast for the first 30 seconds, then back
1121
+ * off, and bail after 5 minutes.
1049
1122
  */
1050
- interface OrgAdminStatus {
1051
- /** Whether the calling session is an admin of the queried org. */
1052
- is_admin: boolean;
1123
+ interface KycPollCadence {
1124
+ /** Poll interval in ms while `elapsed < switchAtMs`. Default: 2000. */
1125
+ fastMs: number;
1126
+ /** Poll interval in ms once `elapsed >= switchAtMs`. Default: 5000. */
1127
+ slowMs: number;
1128
+ /** Elapsed-ms threshold to switch from fast to slow cadence. Default: 30_000. */
1129
+ switchAtMs: number;
1130
+ /**
1131
+ * Maximum total time to spend polling before rejecting with
1132
+ * [[KycStatusTimeoutError]]. Default: 300_000 (5 minutes).
1133
+ */
1134
+ timeoutMs: number;
1053
1135
  }
1054
- /** Shallow runtime guard for {@link OrgAdminStatus}. */
1055
- declare function isOrgAdminStatus(value: unknown): value is OrgAdminStatus;
1056
1136
  /**
1057
- * Standard response returned by all policy write and data mutation operations.
1058
- *
1059
- * Mirrors the org-data `MutationResponse` wire shape.
1137
+ * Optional knobs for [[T3nClient.kycStatusPoll]]. Most callers won't
1138
+ * touch any of these — the cadence defaults are baked in.
1060
1139
  */
1061
- interface MutationResponse {
1140
+ interface KycPollOptions {
1062
1141
  /**
1063
- * `"created"`, `"updated"`, `"deleted"`, or — for the agent-card mutations —
1064
- * `"published"` / `"unpublished"`.
1142
+ * Cancellation signal. When aborted, the helper rejects with
1143
+ * `signal.reason` (or a generic `AbortError` if the consumer
1144
+ * didn't supply a reason). The currently-in-flight `kycStatus()`
1145
+ * call also receives the signal so it can short-circuit.
1065
1146
  */
1066
- status: string;
1067
- /** Hex-encoded entry ID; present on data write/delete operations. */
1068
- entry_id?: string;
1069
- /** Whether the target key existed before deletion; present on single-entry deletes. */
1070
- deleted?: boolean;
1071
- /** Number of entries removed; present on `org-data-delete-scope`. */
1072
- deleted_entries?: number;
1073
- tx_hash: string | null;
1147
+ signal?: AbortSignal;
1148
+ /**
1149
+ * Called with every snapshot the helper receives, including
1150
+ * non-terminal `pending` ones. Useful for surfacing intermediate
1151
+ * UI states (e.g. "still waiting on provider…"). Errors thrown
1152
+ * from this callback are caught and ignored — they must not
1153
+ * sink the poll loop.
1154
+ */
1155
+ onUpdate?: (status: KycStatus) => void;
1156
+ /**
1157
+ * Override one or more cadence fields. Anything not specified
1158
+ * uses the defaults from [[DEFAULT_KYC_POLL_CADENCE]].
1159
+ */
1160
+ cadence?: Partial<KycPollCadence>;
1161
+ /**
1162
+ * Provider id to poll. Defaults to the contract default
1163
+ * (`"veriff"` in phase one). Mirrored on the wire as
1164
+ * `input.provider_id`.
1165
+ */
1166
+ providerId?: string;
1074
1167
  }
1075
1168
  /**
1076
- * Shallow runtime guard for {@link MutationResponse}.
1077
- *
1078
- * Only the always-present fields are checked — `status` is mandatory on
1079
- * every mutation; `tx_hash` is non-optional but nullable. The optional
1080
- * fields (`entry_id`, `deleted`, `deleted_entries`) are not validated
1081
- * because their presence depends on which mutation ran.
1169
+ * Default cadence used by [[T3nClient.kycStatusPoll]] when the caller
1170
+ * doesn't override `cadence.*`.
1082
1171
  */
1083
- declare function isMutationResponse(value: unknown): value is MutationResponse;
1172
+ declare const DEFAULT_KYC_POLL_CADENCE: KycPollCadence;
1084
1173
  /**
1085
- * Response type alias for org-writers-get.
1086
- *
1087
- * The wire body is `{ writers: string[] }` where each entry is
1088
- * `did:t3n:<40-hex>`.
1174
+ * Subset of [[KycStatusKind]] that ends a poll. `pending` is the
1175
+ * only non-terminal value.
1089
1176
  */
1090
- interface OrgWriters {
1091
- writers: string[];
1092
- }
1093
- /** Shallow runtime guard for {@link OrgWriters}. */
1094
- declare function isOrgWriters(value: unknown): value is OrgWriters;
1177
+ declare const TERMINAL_KYC_STATUSES: ReadonlySet<KycStatusKind>;
1095
1178
  /**
1096
- * Response type alias for org-grants-get.
1097
- *
1098
- * The wire body echoes the `contract_id` alongside the grant list.
1179
+ * Thrown by [[T3nClient.kycStatusPoll]] when the cadence's
1180
+ * `timeoutMs` elapses without a terminal status arriving. The
1181
+ * `lastStatus` field is the most recent (necessarily `pending`)
1182
+ * snapshot the helper saw, useful for surfacing "we tried for N
1183
+ * minutes but Veriff is still working" UX.
1099
1184
  */
1100
- interface OrgContractGrants {
1101
- contract_id: string;
1102
- grants: BoundGrant[];
1185
+ declare class KycStatusTimeoutError extends T3nError {
1186
+ /** The timeout (ms) the helper exhausted before a terminal status arrived. */
1187
+ readonly timeoutMs: number;
1188
+ /** The last `pending` snapshot before timeout, if any. */
1189
+ readonly lastStatus?: KycStatus | undefined;
1190
+ constructor(
1191
+ /** The timeout (ms) the helper exhausted before a terminal status arrived. */
1192
+ timeoutMs: number,
1193
+ /** The last `pending` snapshot before timeout, if any. */
1194
+ lastStatus?: KycStatus | undefined);
1103
1195
  }
1196
+
1104
1197
  /**
1105
- * Shallow runtime guard for {@link OrgContractGrants}.
1198
+ * Wire types for the explicit `otp-request` /
1199
+ * `otp-verify` / slim `user-upsert` exports on `tee:user/contracts`
1200
+ * (`tee:user@2.0.0`).
1106
1201
  *
1107
- * Validates the immediate envelope (`contract_id: string`, `grants:
1108
- * array`) without recursing into each `BoundGrant`. The Rust contract
1109
- * is the source of truth for grant element shape; widening the predicate
1110
- * here would create maintenance churn against benign field additions.
1202
+ * Pre-2.0.0 the user contract dispatched OTP request and OTP verify
1203
+ * implicitly from the input shape of a single `user-upsert` call.
1204
+ * 2.0.0 splits that surface into three explicit functions; the
1205
+ * shapes here mirror the OTP / user-upsert wire contract.
1206
+ *
1207
+ * Bytes flow directly from the contract
1208
+ * through the JSON-RPC envelope into the SDK wrappers
1209
+ * (`T3nClient.otpRequest`, `T3nClient.otpVerify`,
1210
+ * `T3nClient.submitUserInput`).
1111
1211
  */
1112
- declare function isOrgContractGrants(value: unknown): value is OrgContractGrants;
1212
+
1113
1213
  /**
1114
- * One grant inside a role: a capability body (functions + scopes, without the
1115
- * grantee, which is bound at assignment time) plus the target contract.
1116
- * Mirrors the org-data `RoleGrant` wire shape.
1214
+ * OTP delivery channel. Matches the `OtpContactChannel` Rust enum
1215
+ * with `serde(rename_all = "snake_case")`.
1117
1216
  */
1118
- interface RoleGrant {
1119
- /** Target contract (canonical name, e.g. `"tee:z-payroll/contracts"`). */
1120
- contract_id: string;
1121
- /** WIT function names this grant confers. */
1122
- functions: string[];
1123
- /** Data scope paths this grant confers (canonicalised lowercase). */
1124
- scopes: string[];
1125
- }
1217
+ type OtpChannel = "email" | "sms";
1126
1218
  /**
1127
- * A role: a named bundle of grants and/or composed sub-roles.
1128
- * Mirrors the org-data `RoleDefinition` wire shape.
1219
+ * Discriminated OTP contact target. Mirrors the Rust `OtpRequest` enum
1220
+ * (`email_channel` / `sms_channel` on the wire). Exactly one branch is
1221
+ * set — no parallel optional email + phone with a separate channel tag.
1222
+ *
1223
+ * The legacy `keys.generic_api.otp_channel` body shadow was removed
1224
+ * in 2.0.0 — the contract rejects calls carrying it with a
1225
+ * `legacy_field` error.
1129
1226
  */
1130
- interface RoleDefinition {
1131
- /** Org-unique role identifier (slug; function-name grammar). */
1132
- role_id: string;
1133
- /** Human-facing label. */
1134
- label: string;
1135
- /** Composite: other role ids in the same org whose grants this role confers. */
1136
- includes: string[];
1137
- /** Grants this role confers directly. */
1138
- grants: RoleGrant[];
1139
- }
1227
+ type OtpRequestInput = {
1228
+ emailChannel: {
1229
+ emailAddress: string;
1230
+ };
1231
+ } | {
1232
+ smsChannel: {
1233
+ phoneNumber: string;
1234
+ };
1235
+ };
1140
1236
  /**
1141
- * The roles assigned to one grantee within one org.
1142
- * Mirrors the org-data `RoleAssignments` wire shape.
1237
+ * Response returned by `otp-request`. Mirrors the OTP wire response.
1238
+ *
1239
+ * - `contact` echoes the OTP destination so clients that race
1240
+ * multiple channels can correlate replies.
1241
+ * - `expiresAtSec` is the Unix-second TTL the host minted for the
1242
+ * pending OTP. Absent in `skip_otp` test environments.
1243
+ * - `status` is `"otp_pending"` on the happy path. `"otp_failed"`
1244
+ * only appears on retry without a fresh request — usually you
1245
+ * shouldn't see it on `otp-request`.
1246
+ * - `txHash` is the host-enriched ledger ref for the OTP-pending
1247
+ * write (the contract leaves it `null`; the host injects).
1248
+ * - `isNewProfile` is `true` on a fresh DID's first OTP request —
1249
+ * read this to detect "did the user just register".
1143
1250
  */
1144
- interface RoleAssignments {
1145
- /** Assigned role ids. */
1146
- roles: string[];
1147
- }
1148
- /** Response for `org-role-get`; `role` is `null` when the id is unknown. */
1149
- interface RoleGetResponse {
1150
- role: RoleDefinition | null;
1251
+ interface OtpRequestResult {
1252
+ contact: string;
1253
+ channel: OtpChannel;
1254
+ expiresAtSec?: number;
1255
+ status?: string;
1256
+ txHash?: string;
1257
+ isNewProfile?: boolean;
1151
1258
  }
1152
- /** Shallow runtime guard for {@link RoleGetResponse}. */
1153
- declare function isRoleGetResponse(value: unknown): value is RoleGetResponse;
1154
- /** Response for `org-role-assignments-get`. */
1155
- interface RoleAssignmentsResponse {
1156
- /** Echoed back so callers don't need to track which request this answers. */
1157
- grantee_did: string;
1158
- /** The grantee's assigned role ids (empty when none). */
1159
- roles: string[];
1259
+ /**
1260
+ * Input to `T3nClient.otpVerify`. `otpCode` is mandatory; `request`
1261
+ * repeats the same discriminated contact shape as {@link OtpRequestInput}.
1262
+ */
1263
+ interface OtpVerifyInput {
1264
+ otpCode: string;
1265
+ request: OtpRequestInput;
1160
1266
  }
1161
- /** Shallow runtime guard for {@link RoleAssignmentsResponse}. */
1162
- declare function isRoleAssignmentsResponse(value: unknown): value is RoleAssignmentsResponse;
1163
1267
  /**
1164
- * Input for `listAgents` — the org plus optional pagination. Omit both `cursor`
1165
- * and `limit` for the first page at the default limit; pass a previous
1166
- * response's `next_cursor` back as `cursor` to fetch the following page.
1268
+ * Suggestion surfaced when the bind-target contact already belongs
1269
+ * to another DID. The contract refuses to silently steal the
1270
+ * authenticator; the caller must resolve the merge (typically via
1271
+ * `merge-profiles`) before re-attempting verify.
1167
1272
  */
1168
- interface ListAgentsInput {
1169
- orgDid: string;
1170
- /** Opaque cursor from a previous response's `next_cursor`. */
1171
- cursor?: string;
1172
- /** Maximum agents to return in this page. */
1173
- limit?: number;
1273
+ interface OtpMergeSuggestion {
1274
+ existingDid: string;
1275
+ currentDid: string;
1276
+ email?: string;
1277
+ phone?: string;
1278
+ channel: OtpChannel;
1174
1279
  }
1175
1280
  /**
1176
- * One org-owned agent in a {@link ListAgentsResponse}: the agent's DID, its
1177
- * display name, and the number of distinct contracts it can access via a direct
1178
- * grant. Mirrors the org-data `AgentSummary` wire shape. The name comes from the
1179
- * agent's private card (falling back to the DID), so the FE no longer needs to
1180
- * fetch each `public:agent_cards` entry to render the roster.
1281
+ * Response returned by `otp-verify`. Mirrors the OTP-verify wire response.
1282
+ *
1283
+ * - `email` is populated on `channel = "email"` success;
1284
+ * `phone` on `channel = "sms"` success. Mutually exclusive on
1285
+ * the happy path.
1286
+ * - `status` carries `"otp_failed"` / `"otp_expired"` on retry; the
1287
+ * happy path leaves it `undefined`.
1288
+ * - `mergeSuggestion` is set when the contact-to-bind is already
1289
+ * owned by another DID. Wire it into your merge UX.
1181
1290
  */
1182
- interface AgentSummary {
1183
- /** The agent's DID (`did:t3n:<40-hex>`). */
1291
+ interface OtpVerifyResult {
1292
+ txHash?: string;
1184
1293
  did: string;
1185
- /** The agent's display name, from its private card (DID when unavailable). */
1186
- name: string;
1187
- /** Count of distinct contracts the agent holds a direct grant on. */
1188
- contract_count: number;
1189
- }
1190
- /** Response for `org-data-list-agents`. */
1191
- interface ListAgentsResponse {
1192
- /** One PAGE of the org's org-owned agents, sorted by DID. */
1193
- agents: AgentSummary[];
1194
- /** Opaque cursor for the next page; absent on the last page. */
1195
- next_cursor?: string;
1294
+ channel: OtpChannel;
1295
+ email?: string;
1296
+ phone?: string;
1297
+ status?: string;
1298
+ mergeSuggestion?: OtpMergeSuggestion;
1299
+ isNewProfile?: boolean;
1196
1300
  }
1197
- /** A human member's org role. The closed wire domain of {@link HumanMember}. */
1198
- type MemberRole = "admin" | "member";
1199
1301
  /**
1200
- * Input for `listHumanMembers` — the org plus optional pagination. Omit both
1201
- * `cursor` and `limit` for the first page at the default limit; pass a previous
1202
- * response's `next_cursor` back as `cursor` to fetch the following page.
1302
+ * Level-1 user-input fields accepted by the slim `user-upsert`. Field names
1303
+ * are the on-the-wire names — `submitUserInput` sends this object verbatim,
1304
+ * so keys must match the contract exactly (snake_case). The canonical Level-1
1305
+ * set is the six fields below; the shape is intentionally open so callers can
1306
+ * add provider-specific fields the contract knows how to merge.
1307
+ *
1308
+ * `email_address` / `phone_number` are normally bound via the OTP roundtrip
1309
+ * before `submitUserInput`, but the contract accepts them directly here too.
1203
1310
  */
1204
- interface ListHumanMembersInput {
1205
- orgDid: string;
1206
- /** Opaque cursor from a previous response's `next_cursor`. */
1207
- cursor?: string;
1208
- /** Maximum members to return in this page. */
1209
- limit?: number;
1311
+ interface UserInputProfile {
1312
+ first_name?: string;
1313
+ last_name?: string;
1314
+ country_of_residence?: string;
1315
+ document_issuance_country?: string;
1316
+ ssn?: string;
1317
+ address?: string;
1318
+ email_address?: string;
1319
+ phone_number?: string;
1320
+ campaign_code?: string;
1321
+ role?: string;
1322
+ [key: string]: unknown;
1210
1323
  }
1211
1324
  /**
1212
- * One direct human member: DID plus org role. No profile PII (name/email are
1213
- * out of scope and owned by `tee:user`). Mirrors the org-data `HumanMember`
1214
- * wire shape.
1325
+ * Input to `T3nClient.submitUserInput`. Maps onto the slim
1326
+ * `user-upsert` request shape: `{ profile, organisation_did?,
1327
+ * attestations?, keys? }`.
1215
1328
  */
1216
- interface HumanMember {
1217
- /** The member's DID (`did:t3n:<40-hex>`). */
1218
- did: string;
1219
- /** The member's org role. */
1220
- role: MemberRole;
1221
- }
1222
- /** Response for `org-data-list-human-members`. */
1223
- interface ListHumanMembersResponse {
1224
- /** One PAGE of the org's direct human members, sorted by DID. */
1225
- members: HumanMember[];
1226
- /** Opaque cursor for the next page; absent on the last page. */
1227
- next_cursor?: string;
1228
- }
1229
- /** Shallow runtime guard for {@link ListHumanMembersResponse}. */
1230
- declare function isListHumanMembersResponse(value: unknown): value is ListHumanMembersResponse;
1231
- /** Shallow runtime guard for {@link ListAgentsResponse}. */
1232
- declare function isListAgentsResponse(value: unknown): value is ListAgentsResponse;
1233
- /** Response for `org-data-list`. */
1234
- interface DataListResponse {
1235
- /** Hex-encoded entry IDs for this page. */
1236
- entry_ids: string[];
1237
- /** Offset to pass for the next page. `null` when this is the last page. */
1238
- next_offset: number | null;
1239
- /** Total number of entries in the scope (across all pages). */
1240
- total: number;
1329
+ interface SubmitUserInputArgs {
1330
+ profile: UserInputProfile;
1331
+ organisationDid?: string;
1332
+ attestations?: unknown;
1333
+ keys?: Record<string, unknown>;
1334
+ /**
1335
+ * KYC webhook orphan-attestation flow. When set, the contract
1336
+ * skips the email-not-verified gate and only records the
1337
+ * attestation if the DID has no profile yet.
1338
+ * Most callers should leave this `undefined`.
1339
+ */
1340
+ requireExistingUser?: boolean;
1341
+ /**
1342
+ * Testnet self-admit. When `true`, the contract additionally
1343
+ * runs the self-admit side-effect after the profile commit: writes
1344
+ * the caller's DID into `idx:_tenants` + `idx:_tenant_quotas` and
1345
+ * mints any operator-configured welcome credits. Inspect the
1346
+ * `tenantAdmit` field on the response for the outcome.
1347
+ *
1348
+ * Testnet-only. Production clusters return
1349
+ * `tenantAdmit.status = "refused"` with
1350
+ * `reason = "not_testnet" | "self_admit_disabled" | "not_eth_derived"`.
1351
+ * The profile commit always succeeds regardless of the inner outcome.
1352
+ *
1353
+ * Most callers should leave this `undefined`.
1354
+ */
1355
+ becomeDevTenant?: boolean;
1241
1356
  }
1242
- /** Shallow runtime guard for {@link DataListResponse}. */
1243
- declare function isDataListResponse(value: unknown): value is DataListResponse;
1244
- /** Secret shape discriminator (mirrors the contract `SecretKind`). */
1245
- type SecretKind = "single_value" | "json";
1246
- /** Metadata common to every {@link SecretView} entry. */
1247
- interface SecretViewBase {
1248
- /** Secret name (the `(org, name)` key tail). */
1249
- name: string;
1250
- /** Monotonic version, bumped on each value rotation and ACL edit. */
1251
- version: number;
1252
- /** Unix seconds of the most recent write. */
1253
- updated_at_secs: number;
1357
+ /**
1358
+ * Testnet self-admit projection from `user-upsert`. Present only
1359
+ * when the caller set `becomeDevTenant: true` on the request.
1360
+ *
1361
+ * - `status: "admitted"` — first call for this DID; tenant record
1362
+ * committed and (if configured) welcome credits minted into
1363
+ * `grantedCredits`.
1364
+ * - `status: "already-admitted"` — replay; idempotent no-op.
1365
+ * - `status: "refused"` — the cluster declined the self-admit;
1366
+ * `reason` is the machine-readable cause (`not_testnet`,
1367
+ * `self_admit_disabled`, `not_eth_derived`), `detail` is a
1368
+ * human-readable string.
1369
+ */
1370
+ type TenantAdmitStatus = "admitted" | "already-admitted" | "refused";
1371
+ interface TenantAdmitProjection {
1372
+ status: TenantAdmitStatus;
1373
+ grantedCredits?: string;
1374
+ reason?: string;
1375
+ detail?: string;
1254
1376
  }
1255
1377
  /**
1256
- * The redacted per-secret summary `org-secret-list` returns — a discriminated
1257
- * union on `kind`. The value is NEVER present: a single-value exposes only its
1258
- * last four characters and a json secret only its sorted top-level field names.
1378
+ * Response shape returned by the slim `user-upsert`. Carries the
1379
+ * post-merge tx hash plus the Level-1 merge diagnostics
1380
+ * (`refusedFields`, `mergeSuggestion`) the pre-2.0.0 omnibus
1381
+ * `UpsertResponse` already surfaced.
1259
1382
  */
1260
- type SecretView = (SecretViewBase & {
1261
- kind: "single_value";
1262
- /** Last four characters of the value (whole value when ≤ 4 chars). */
1263
- last4: string;
1264
- }) | (SecretViewBase & {
1265
- kind: "json";
1266
- /** Sorted top-level object field names (keys only, no values). */
1267
- field_names: string[];
1268
- });
1269
- /** Shallow runtime guard for {@link SecretView}. */
1270
- declare function isSecretView(value: unknown): value is SecretView;
1271
- /**
1272
- * Full secret record returned by `org-secret-get` — the value IS included
1273
- * (the deliberate read-back path the READ axis exists for), along with all
1274
- * three ACLs.
1275
- */
1276
- interface SecretRecord {
1277
- name: string;
1278
- kind: SecretKind;
1279
- /** The value as text: the scalar for a single-value, canonical JSON object for a json secret. */
1280
- value: string;
1281
- version: number;
1282
- /** READ axis — DIDs allowed to read the value back. */
1283
- reader_dids: string[];
1284
- /** READ axis — role ids allowed to read the value back. */
1285
- reader_roles: string[];
1286
- /** MANAGE axis — DIDs allowed to rotate the value. */
1287
- manager_dids: string[];
1288
- /** MANAGE axis — role ids allowed to rotate the value. */
1289
- manager_roles: string[];
1290
- /** USE axis — canonical contract ids allowed to have the value injected. */
1291
- contract_allowlist: string[];
1292
- created_at_secs: number;
1293
- updated_at_secs: number;
1294
- /** DID of the caller who last wrote the record. */
1295
- updated_by: string;
1296
- }
1297
- /** Shallow runtime guard for {@link SecretRecord}. */
1298
- declare function isSecretRecord(value: unknown): value is SecretRecord;
1299
- /** Response for `org-secret-list`: redacted per-kind views, no values. */
1300
- interface SecretListResponse {
1301
- secrets: SecretView[];
1302
- }
1303
- /** Shallow runtime guard for {@link SecretListResponse}. */
1304
- declare function isSecretListResponse(value: unknown): value is SecretListResponse;
1305
- /** Response for `org-data-get`. */
1306
- interface DataGetResponse {
1307
- entry_id: string;
1308
- /** Hex-encoded raw payload bytes. */
1309
- payload_hex: string;
1383
+ interface SubmitUserInputResult {
1384
+ txHash?: string;
1385
+ refusedFields?: string[];
1386
+ mergeSuggestion?: OtpMergeSuggestion;
1387
+ userFound?: boolean;
1388
+ /**
1389
+ * Testnet self-admit projection. Present only when the caller
1390
+ * set `becomeDevTenant: true` on the request.
1391
+ */
1392
+ tenantAdmit?: TenantAdmitProjection;
1310
1393
  }
1311
- /** Shallow runtime guard for {@link DataGetResponse}. */
1312
- declare function isDataGetResponse(value: unknown): value is DataGetResponse;
1313
1394
  /**
1314
- * Return shape of `agentCardGet` — composed client-side from the generic
1315
- * `org-data-get` read of the card's entry (there is no card-specific read
1316
- * operation on the contract). To check whether a public copy exists, probe
1317
- * the anonymous `GET /api/agent-card/{did}` endpoint.
1395
+ * Discriminator for {@link UserUpsertError}. Mirrors the
1396
+ * `UserUpsertError` wire enum and its `<code>:<detail>` wire
1397
+ * format. Branch with a `switch` over `kind`.
1398
+ *
1399
+ * - `EmailNotVerified` — the slim `user-upsert` was called against
1400
+ * a DID that has no verified email and no proving authenticator.
1401
+ * Run `otpRequest` + `otpVerify` first (or accept an
1402
+ * OIDC/Email-authed session).
1403
+ * - `LegacyField` — caller passed a pre-2.0.0 dispatch field
1404
+ * (`otp_code` to a non-verify export, or
1405
+ * `keys.generic_api.otp_channel` anywhere). Migrate the call
1406
+ * site to the new explicit functions.
1407
+ * - `UserNotFound` — `requireExistingUser` was set but no profile
1408
+ * exists for the DID. The attestation is recorded for audit;
1409
+ * no profile created.
1318
1410
  */
1319
- interface AgentCardResponse {
1320
- /** The agent whose card this is (`did:t3n:<40-hex>`). */
1321
- agent_did: string;
1322
- /** The stored card JSON body, verbatim. */
1323
- card: string;
1324
- }
1325
- /** Shallow runtime guard for {@link AgentCardResponse}. */
1326
- declare function isAgentCardResponse(value: unknown): value is AgentCardResponse;
1411
+ type UserUpsertErrorKind = "EmailNotVerified" | "LegacyField" | "UserNotFound";
1327
1412
  /**
1328
- * Legacy direct-route org-data envelope shape retained for compatibility.
1413
+ * Typed wrapper for the `<code>:<detail>` errors the slim
1414
+ * `user-upsert` and the OTP entry points emit. `kind` is the
1415
+ * structured discriminator the SDK derives from the error code
1416
+ * prefix; `code` and `detail` retain the wire components for
1417
+ * fall-through logging.
1329
1418
  *
1330
- * This mirrors the removed `/api/user-contract/execute` body format from
1331
- * the transitional transport. New callers should use `OrgDataClient`,
1332
- * which now dispatches through authenticated `/api/rpc` +
1333
- * `action.execute` instead.
1419
+ * Throw site: `T3nClient.submitUserInput` (and friends) when the
1420
+ * contract returns a string error matching the
1421
+ * `<code>:<detail>` shape.
1334
1422
  */
1335
- interface OrgDataActionWire {
1336
- nonce: string;
1337
- user_did: string;
1338
- authenticator_id: string;
1339
- contract_id: string;
1340
- function: string;
1341
- args_hash: string;
1342
- expires_at_secs: number;
1343
- signature: string;
1423
+ declare class UserUpsertError extends T3nError {
1424
+ readonly kind: UserUpsertErrorKind | "Unknown";
1425
+ readonly detail: string;
1426
+ constructor(code: string, detail: string);
1427
+ /**
1428
+ * Try to parse a contract error string into a `UserUpsertError`.
1429
+ * Returns `null` if `raw` doesn't match the `<code>:<detail>`
1430
+ * shape — caller falls back to a generic error.
1431
+ */
1432
+ static fromWire(raw: string): UserUpsertError | null;
1344
1433
  }
1345
1434
 
1346
1435
  /**
1347
- * Agent-auth grants — the standing on-chain authority a user delegates to
1348
- * an agent (envelope-free authorisation).
1436
+ * Token-metering wire shapes.
1349
1437
  *
1350
- * The document is one flat list of {@link BoundGrant} rows plus the
1351
- * document-level discovery grants: `{ grants, discover_dids }`. Each grant's
1352
- * `grantee` is the agent DID it authorises, so there is no per-agent grouping —
1353
- * a user's whole delegation surface is the single `grants` array. Reads
1354
- * (`agent-auth-get`) and writes (`agent-auth-update`) on
1355
- * `tee:authorisations/contracts` (the policy's owning contract) are
1356
- * **SelfOnly**: only the user, authenticated as themselves, may read or write
1357
- * their own grants. This is the user-approval proof the per-call delegation
1358
- * credential's `user_sig` used to carry.
1359
- *
1360
- * A grant carries `functions`, the agent's delegated org-data `scopes`, the
1361
- * direct-enumerable `read_scopes`, egress `allowed_hosts`, an optional semver
1362
- * `version_req`, and an optional validity `window`. The ≤ cap *length* check is
1363
- * enforced contract-side at write time; the expiry gate is host-side at read
1364
- * time.
1365
- *
1366
- * The SDK is a literal snake_case mirror of the wire: {@link BoundGrant} IS the
1367
- * wire grant shape, so reads and writes pass through untouched — there is no
1368
- * casing transform. The only glue here is the read-merge-write helper
1369
- * ({@link mergeGrants}) that lets a single-grant write preserve every other row
1370
- * (the contract has no per-field merge; the document IS the new state).
1438
+ * Mirrors the token-metering wire contract. `u128` fields land on the
1439
+ * wire as JSON numbers (same convention as the existing
1440
+ * `token.get-balance` response) — JS clients with histories that
1441
+ * exceed 2⁵³ tokens should switch to a streaming JSON parser; the
1442
+ * common case fits in `number` losslessly.
1371
1443
  */
1372
-
1373
1444
  /**
1374
- * The full agent-auth policy document — the shape of BOTH the `agent-auth-get`
1375
- * output and the `agent-auth-update` input (they are identical). A flat list of
1376
- * grant rows plus the document-level discovery grants; mirrors the contract
1377
- * `AgentAuthDoc` wire shape verbatim (snake_case).
1378
- *
1379
- * `discover_dids` is the list of DIDs the user lets their registered agents
1380
- * *enumerate the contracts of* via `listContracts`: an org DID grants org-mode
1381
- * discovery, the user's own DID grants self-mode discovery. It lives at document
1382
- * level — not on a grant — because discovery must surface contracts the agent
1383
- * cannot yet call. The node's discovery gate additionally requires the calling
1384
- * agent to be the `grantee` of at least one grant (subject binding), so an
1385
- * unregistered agent discovers nothing regardless of this list.
1386
- *
1387
- * The document IS the new state on a write: an empty `grants` list revokes all
1388
- * agent access, and an empty `discover_dids` persists an empty discovery-grant
1389
- * list (there is no per-field merge). Use {@link mergeGrants} /
1390
- * {@link mergeDiscoverDids} to read-merge-write a single grant without dropping
1391
- * the rest.
1392
- */
1393
- interface AgentAuthDoc {
1394
- /** Every standing agent-edge grant, each keyed by its `grantee` agent DID. */
1395
- grants: BoundGrant[];
1396
- /** Document-level discovery grants (`did:t3n:<40-hex>` entries). */
1397
- discover_dids: string[];
1398
- }
1399
- /**
1400
- * Decode an `agent-auth-get` response into an {@link AgentAuthDoc}. The wire is
1401
- * already snake_case, so grant rows pass through unchanged — this only defaults
1402
- * a `null` / absent response (the empty policy) and a missing field to an empty
1403
- * list. NOT a casing transform.
1404
- */
1405
- declare function parseAgentAuthDoc(response: unknown): AgentAuthDoc;
1406
- interface GrantsMergeResult {
1407
- /** Full merged grant list, ready for `agent-auth-update`. */
1408
- grants: BoundGrant[];
1409
- /** `"<grantee> → <contract_id>"` rows preserved from the existing policy. */
1410
- preservedRows: string[];
1445
+ * The token `BalanceRow` wire shape — caller's credit row.
1446
+ *
1447
+ * `available` and `reserved` are `u128` on the server; the wire
1448
+ * format is a JSON number. Callers should not assume bigint until
1449
+ * the SDK migrates to a streaming parser (tracked separately).
1450
+ *
1451
+ * ⚠️ Amounts are in **base units** (`1 token = `
1452
+ * {@link BASE_UNITS_PER_TOKEN}), not whole tokens. Use
1453
+ * {@link formatTokens} to display them.
1454
+ */
1455
+ interface BalanceRow {
1456
+ /** Spendable balance, in base units (see {@link formatTokens}). */
1457
+ available: number;
1458
+ /** Reserved balance, in base units. */
1459
+ reserved: number;
1460
+ last_settled_seq_no: number;
1461
+ version: number;
1462
+ credit_exhausted: boolean;
1411
1463
  }
1412
1464
  /**
1413
- * Merge new grant rows into the existing flat list with `(grantee, contract_id)`
1414
- * union semantics: an existing row whose `(grantee, contract_id)` matches a new
1415
- * row is replaced; every other existing row is preserved (and reported in
1416
- * `preservedRows` as an audit aid). New rows for a `(grantee, contract_id)` not
1417
- * already present are appended.
1465
+ * The token-tx-kind wire alphabet (snake_case). Every
1466
+ * value listed here is accepted by the server-side
1467
+ * `token.get-usage` `kinds` filter.
1418
1468
  */
1419
- declare function mergeGrants(existing: BoundGrant[], additions: BoundGrant[]): GrantsMergeResult;
1469
+ type TokenTxKind = "mint" | "burn" | "charge" | "transfer" | "bridge_mint_attest" | "bridge_burn_attest";
1420
1470
  /**
1421
- * Order-preserving deduplicating union of discovery-grant DID lists — the
1422
- * read-merge-write counterpart of {@link mergeGrants} for the document-level
1423
- * `discover_dids` (the contract rejects duplicate entries, so the union must
1424
- * dedupe).
1471
+ * Per-caller view direction. `"in"` = caller's balance went up;
1472
+ * `"out"` = caller's balance went down. Derived host-side from
1473
+ * `(caller_did, tx.src, tx.dst)`; the same `seq_no` appears in both
1474
+ * parties' usage feeds with opposite directions on a transfer.
1425
1475
  */
1426
- declare function mergeDiscoverDids(existing: string[], additions: string[]): string[];
1427
-
1476
+ type Direction = "in" | "out";
1428
1477
  /**
1429
- * KYC types for the `tee:user/contracts::kyc-status` short-poll
1430
- * function.
1431
- *
1432
- * The shape mirrors the `kyc-status` wire response.
1433
- * The bytes go straight from the contract
1434
- * through the JSON-RPC envelope into [[T3nClient.kycStatus]].
1478
+ * Discriminated union mirroring the charge-reason wire union.
1479
+ * Present only when the row's `kind === "charge"`.
1435
1480
  */
1436
-
1481
+ type ChargeReason = {
1482
+ kind: "contract_register";
1483
+ script_name: string;
1484
+ version: string;
1485
+ } | {
1486
+ kind: "invocation";
1487
+ script_name: string;
1488
+ function: string;
1489
+ fuel_consumed: number;
1490
+ fuel_tokens: number;
1491
+ host_call_count: number;
1492
+ host_call_tokens: number;
1493
+ } | {
1494
+ kind: "kv_bytes";
1495
+ map: string;
1496
+ } | {
1497
+ kind: "cas_bytes";
1498
+ backend: string;
1499
+ } | {
1500
+ kind: "outbox_egress";
1501
+ upstream: string;
1502
+ };
1437
1503
  /**
1438
- * Terminal status for a Level 2 KYC verification, plus `pending`.
1504
+ * One row in the caller's usage feed — a per-caller projection of
1505
+ * the underlying `TokenTx`. `counterparty` is the other party from
1506
+ * the caller's perspective: `tx.dst` on outbound entries, `tx.src`
1507
+ * on inbound. `null` when the underlying tx has no counterparty
1508
+ * (mints have no `src`; burns and charges have no `dst`).
1509
+ */
1510
+ interface UsageEntry {
1511
+ seq_no: number;
1512
+ kind: TokenTxKind;
1513
+ /** Amount moved, in base units (`1 token = `{@link BASE_UNITS_PER_TOKEN}); see {@link formatTokens}. */
1514
+ amount: number;
1515
+ timestamp_ms: number;
1516
+ direction: Direction;
1517
+ counterparty?: string | null;
1518
+ reason?: ChargeReason | null;
1519
+ note?: string | null;
1520
+ }
1521
+ /**
1522
+ * Response shape of `token.get-usage` — caller's balance plus a
1523
+ * paginated slice of their most-recent `token:tx_log` entries.
1439
1524
  *
1440
- * - `pending` — provider has not delivered a verdict yet, or the
1441
- * webhook arrived but the post-action VC issuance hasn't completed.
1442
- * - `verified` — provider approved AND a VC has been issued. `vcIds`
1443
- * carries the issued credential ids.
1444
- * - `rejected` — provider declined / required resubmission /
1445
- * expired / the user abandoned the flow. `error` may carry a
1446
- * provider-supplied reason.
1447
- * - `orphan` — a Veriff webhook arrived with a `vendorData` that
1448
- * couldn't be matched to any user. Should not
1449
- * happen in the MetaMask flow but the contract surfaces it for
1450
- * completeness.
1525
+ * `next_cursor` is the inclusive upper-bound `seq_no` to pass back
1526
+ * as `after_seq` to fetch the next page. `null` (or absent) means
1527
+ * the caller's history is fully drained.
1451
1528
  */
1452
- type KycStatusKind = "pending" | "verified" | "rejected" | "orphan";
1529
+ interface UsagePage {
1530
+ balance: BalanceRow;
1531
+ entries: UsageEntry[];
1532
+ next_cursor?: number | null;
1533
+ }
1453
1534
  /**
1454
- * Snapshot returned by `tee:user/contracts::kyc-status`.
1535
+ * Request shape — all fields optional. `limit` clamps to
1536
+ * `1..=200` server-side; out-of-range values snap silently to the
1537
+ * bounds. `kinds: []` is treated as "no filter".
1538
+ */
1539
+ interface GetUsageOptions {
1540
+ limit?: number;
1541
+ after_seq?: number;
1542
+ kinds?: TokenTxKind[];
1543
+ }
1544
+
1545
+ /**
1546
+ * Tenant audit-event wire shapes.
1455
1547
  *
1456
- * Field names use camelCase on the SDK boundary even though the
1457
- * wire is snake_case — the wrapper rewrites keys at the client edge
1458
- * so callers don't see the JSON shape leaking through.
1548
+ * Mirrors `tenant_types::AuditEvent` and the `audit.get-mine` response
1549
+ * (`service::tenant_logs::{AuditBatch, AuditPage}`). A tenant contract
1550
+ * emits an audit event via the `logging::audit` host call; the host
1551
+ * stamps the identity fields (`subject` / `actor` / `vc_id`) from the
1552
+ * verified dispatch context, so a contract can never forge who acted or
1553
+ * on whom. Events are permanent (encrypted, append-only) and scoped to a
1554
+ * user — distinct from the evicting debug ring read via `getContractLogs`.
1459
1555
  */
1460
- interface KycStatus {
1461
- /** Terminal status if reached, otherwise `pending`. */
1462
- status: KycStatusKind;
1463
- /**
1464
- * Provider being polled. Echoed back so callers that didn't
1465
- * supply one see the contract's default (`"veriff"` in phase one).
1466
- */
1467
- provider: string;
1468
- /**
1469
- * Unix-millis of the latest contract-visible event:
1470
- * VC issuance time, attestation arrival time, session-row
1471
- * `started_at_ms`, or orphan-record arrival time. Best-effort —
1472
- * `undefined` when no source carries a usable timestamp.
1473
- */
1474
- updatedAt?: number;
1475
- /**
1476
- * VC ids appended for this provider, in append order. Empty for
1477
- * `pending` / `rejected` / `orphan`.
1478
- */
1479
- vcIds: string[];
1480
- /**
1481
- * Provider-supplied reason for `rejected`, when available.
1482
- */
1483
- error?: string;
1484
- }
1485
1556
  /**
1486
- * Polling cadence for [[T3nClient.kycStatusPoll]]. Defaults:
1487
- * poll fast for the first 30 seconds, then back
1488
- * off, and bail after 5 minutes.
1557
+ * One host-stamped audit event. `subject` / `actor` are canonical DID
1558
+ * strings. On a self-call `actor === subject` and `vc_id` is `null`; on a
1559
+ * delegated call `actor` is the agent and `vc_id` is the delegation
1560
+ * credential. The remaining fields are supplied verbatim by the contract.
1489
1561
  */
1490
- interface KycPollCadence {
1491
- /** Poll interval in ms while `elapsed < switchAtMs`. Default: 2000. */
1492
- fastMs: number;
1493
- /** Poll interval in ms once `elapsed >= switchAtMs`. Default: 5000. */
1494
- slowMs: number;
1495
- /** Elapsed-ms threshold to switch from fast to slow cadence. Default: 30_000. */
1496
- switchAtMs: number;
1497
- /**
1498
- * Maximum total time to spend polling before rejecting with
1499
- * [[KycStatusTimeoutError]]. Default: 300_000 (5 minutes).
1500
- */
1501
- timeoutMs: number;
1562
+ interface AuditEvent {
1563
+ /** Cluster-deterministic flush timestamp (ms). */
1564
+ ts_ms: number;
1565
+ /** The user whose data the call touched (host-stamped `pii_did`). */
1566
+ subject: string;
1567
+ /** The agent (delegated) or user (self-call) who acted (host-stamped). */
1568
+ actor: string;
1569
+ /** Delegation credential id on a delegated call; `null` on a self-call. */
1570
+ vc_id?: string | null;
1571
+ /** Contract-supplied: what happened, e.g. `"kyc.approve"`. */
1572
+ action: string;
1573
+ /** Contract-supplied: what it acted on, e.g. `"user-profile"`. */
1574
+ target: string;
1575
+ /** Contract-supplied: the result, e.g. `"success"` / `"denied"`. */
1576
+ outcome: string;
1577
+ /** Contract-supplied: optional free-text / JSON detail. */
1578
+ details?: string | null;
1502
1579
  }
1503
1580
  /**
1504
- * Optional knobs for [[T3nClient.kycStatusPoll]]. Most callers won't
1505
- * touch any of these — the cadence defaults are baked in.
1581
+ * One archived batch — the events committed in a single tenant dispatch.
1582
+ * Every event in a batch shares the same `subject` / `actor` / `vc_id`.
1506
1583
  */
1507
- interface KycPollOptions {
1508
- /**
1509
- * Cancellation signal. When aborted, the helper rejects with
1510
- * `signal.reason` (or a generic `AbortError` if the consumer
1511
- * didn't supply a reason). The currently-in-flight `kycStatus()`
1512
- * call also receives the signal so it can short-circuit.
1513
- */
1514
- signal?: AbortSignal;
1515
- /**
1516
- * Called with every snapshot the helper receives, including
1517
- * non-terminal `pending` ones. Useful for surfacing intermediate
1518
- * UI states (e.g. "still waiting on provider…"). Errors thrown
1519
- * from this callback are caught and ignored — they must not
1520
- * sink the poll loop.
1521
- */
1522
- onUpdate?: (status: KycStatus) => void;
1523
- /**
1524
- * Override one or more cadence fields. Anything not specified
1525
- * uses the defaults from [[DEFAULT_KYC_POLL_CADENCE]].
1526
- */
1527
- cadence?: Partial<KycPollCadence>;
1584
+ interface AuditBatch {
1585
+ /** Hex of the archive key — usable directly as `cursor` for the next page. */
1586
+ key: string;
1528
1587
  /**
1529
- * Provider id to poll. Defaults to the contract default
1530
- * (`"veriff"` in phase one). Mirrored on the wire as
1531
- * `input.provider_id`.
1588
+ * Host-stamped: did the emitting dispatch's contract transaction
1589
+ * commit? `false` means the call rolled back or trapped, so an event's
1590
+ * `outcome: "success"` in this batch is the contract's *claim*, not a
1591
+ * committed fact — filter on this when you need only durable events.
1532
1592
  */
1533
- providerId?: string;
1593
+ committed: boolean;
1594
+ events: AuditEvent[];
1534
1595
  }
1535
1596
  /**
1536
- * Default cadence used by [[T3nClient.kycStatusPoll]] when the caller
1537
- * doesn't override `cadence.*`.
1538
- */
1539
- declare const DEFAULT_KYC_POLL_CADENCE: KycPollCadence;
1540
- /**
1541
- * Subset of [[KycStatusKind]] that ends a poll. `pending` is the
1542
- * only non-terminal value.
1597
+ * `audit.get-mine` response — a page of audit batches, newest scan order.
1598
+ * `next_cursor` is present (a key hex) when more batches remain; `null`
1599
+ * once the scan reaches the end.
1543
1600
  */
1544
- declare const TERMINAL_KYC_STATUSES: ReadonlySet<KycStatusKind>;
1601
+ interface AuditPage {
1602
+ batches: AuditBatch[];
1603
+ next_cursor?: string | null;
1604
+ }
1545
1605
  /**
1546
- * Thrown by [[T3nClient.kycStatusPoll]] when the cadence's
1547
- * `timeoutMs` elapses without a terminal status arriving. The
1548
- * `lastStatus` field is the most recent (necessarily `pending`)
1549
- * snapshot the helper saw, useful for surfacing "we tried for N
1550
- * minutes but Veriff is still working" UX.
1606
+ * Request shape for {@link T3nClient.getAuditEvents} — all fields
1607
+ * optional. Omit `pii_did` to read your own trail (all actors); set it to
1608
+ * another user's DID to read, as a delegated agent, the events you
1609
+ * performed for them — admitted only while that user's agent-auth grant
1610
+ * to you is live. `cursor` is the `next_cursor` from a prior page.
1551
1611
  */
1552
- declare class KycStatusTimeoutError extends T3nError {
1553
- /** The timeout (ms) the helper exhausted before a terminal status arrived. */
1554
- readonly timeoutMs: number;
1555
- /** The last `pending` snapshot before timeout, if any. */
1556
- readonly lastStatus?: KycStatus | undefined;
1557
- constructor(
1558
- /** The timeout (ms) the helper exhausted before a terminal status arrived. */
1559
- timeoutMs: number,
1560
- /** The last `pending` snapshot before timeout, if any. */
1561
- lastStatus?: KycStatus | undefined);
1612
+ interface GetAuditEventsOptions {
1613
+ pii_did?: string;
1614
+ limit?: number;
1615
+ cursor?: string;
1562
1616
  }
1563
1617
 
1564
1618
  /**
1565
- * Wire types for the explicit `otp-request` /
1566
- * `otp-verify` / slim `user-upsert` exports on `tee:user/contracts`
1567
- * (`tee:user@2.0.0`).
1619
+ * Agent-activity audit-log wire shapes (the node's `auditlog` RPC).
1568
1620
  *
1569
- * Pre-2.0.0 the user contract dispatched OTP request and OTP verify
1570
- * implicitly from the input shape of a single `user-upsert` call.
1571
- * 2.0.0 splits that surface into three explicit functions; the
1572
- * shapes here mirror the OTP / user-upsert wire contract.
1621
+ * Mirrors `service::activity_audit::{ActivityReport, ReportEntry}` and
1622
+ * `primitives::audit_log::AuditLogEntry`. One entry per audited contract
1623
+ * dispatch — who called, for whom, which contract + function, and how it
1624
+ * ended. Entries are reconstructed from the append-only ledger on read, so
1625
+ * `seq_no` (the ledger index) and `hash` are derived server-side rather than
1626
+ * stored with the record.
1573
1627
  *
1574
- * Bytes flow directly from the contract
1575
- * through the JSON-RPC envelope into the SDK wrappers
1576
- * (`T3nClient.otpRequest`, `T3nClient.otpVerify`,
1577
- * `T3nClient.submitUserInput`).
1578
- */
1579
-
1580
- /**
1581
- * OTP delivery channel. Matches the `OtpContactChannel` Rust enum
1582
- * with `serde(rename_all = "snake_case")`.
1628
+ * Scope is the caller's **own organisation**, resolved node-side from the
1629
+ * session DID: there is no scope parameter, and a page carries **every
1630
+ * member's** activity in that org, not just the caller's own. Metadata only —
1631
+ * DIDs, never display names, call arguments, or payloads.
1583
1632
  */
1584
- type OtpChannel = "email" | "sms";
1585
1633
  /**
1586
- * Discriminated OTP contact target. Mirrors the Rust `OtpRequest` enum
1587
- * (`email_channel` / `sms_channel` on the wire). Exactly one branch is
1588
- * set — no parallel optional email + phone with a separate channel tag.
1589
- *
1590
- * The legacy `keys.generic_api.otp_channel` body shadow was removed
1591
- * in 2.0.0 — the contract rejects calls carrying it with a
1592
- * `legacy_field` error.
1634
+ * Whether the actor is a registered agent or a human / self principal.
1635
+ * Decided node-side by an existence check on the actor DID in the agent
1636
+ * registry — never inferred from the DID's shape.
1593
1637
  */
1594
- type OtpRequestInput = {
1595
- emailChannel: {
1596
- emailAddress: string;
1597
- };
1598
- } | {
1599
- smsChannel: {
1600
- phoneNumber: string;
1601
- };
1602
- };
1638
+ type ActivityCallerType = "agent" | "human";
1603
1639
  /**
1604
- * Response returned by `otp-request`. Mirrors the OTP wire response.
1640
+ * Host-stamped outcome of an audited dispatch.
1605
1641
  *
1606
- * - `contact` echoes the OTP destination so clients that race
1607
- * multiple channels can correlate replies.
1608
- * - `expiresAtSec` is the Unix-second TTL the host minted for the
1609
- * pending OTP. Absent in `skip_otp` test environments.
1610
- * - `status` is `"otp_pending"` on the happy path. `"otp_failed"`
1611
- * only appears on retry without a fresh request — usually you
1612
- * shouldn't see it on `otp-request`.
1613
- * - `txHash` is the host-enriched ledger ref for the OTP-pending
1614
- * write (the contract leaves it `null`; the host injects).
1615
- * - `isNewProfile` is `true` on a fresh DID's first OTP request —
1616
- * read this to detect "did the user just register".
1642
+ * - `success` — the business transaction committed.
1643
+ * - `denied` — authorisation refused the call.
1644
+ * - `error` — the call was allowed but failed / rolled back.
1617
1645
  */
1618
- interface OtpRequestResult {
1619
- contact: string;
1620
- channel: OtpChannel;
1621
- expiresAtSec?: number;
1622
- status?: string;
1623
- txHash?: string;
1624
- isNewProfile?: boolean;
1646
+ type ActivityOutcome = "success" | "denied" | "error";
1647
+ /** One audited call. */
1648
+ interface ActivityEntry {
1649
+ /**
1650
+ * Ledger index of the entry — its unique, ordered id. Use it as the row key
1651
+ * and as the ordering key: it is monotonic, whereas {@link timestamp_ms} is
1652
+ * per-node wall clock.
1653
+ */
1654
+ seq_no: number;
1655
+ /** Hex SHA-256 of the stored entry (64 chars) — read-time tamper evidence. */
1656
+ hash: string;
1657
+ /**
1658
+ * Call time in Unix ms, stamped on the node that took the request. NOT a
1659
+ * cluster-assigned time, so entries from different nodes can be skewed by
1660
+ * their clock offset — order by {@link seq_no}, not by this.
1661
+ */
1662
+ timestamp_ms: number;
1663
+ /** Agent vs human, from the agent-registry check on {@link actor}. */
1664
+ caller_type: ActivityCallerType;
1665
+ /** DID that actually invoked the contract. */
1666
+ actor: string;
1667
+ /**
1668
+ * DID of the owner the caller acted for. Equals {@link actor} on a self /
1669
+ * own-authority call — never null.
1670
+ */
1671
+ on_behalf_of: string;
1672
+ /**
1673
+ * Organisation the acting principal belongs to — the report's scope key, so
1674
+ * it is identical on every row of a page. Falls back to `on_behalf_of` when
1675
+ * that principal is in no organisation.
1676
+ */
1677
+ org: string;
1678
+ /** Contract that ran, e.g. `tee:user/contracts`. */
1679
+ contract: string;
1680
+ /** Contract function invoked, e.g. `user-upsert`. */
1681
+ function: string;
1682
+ /** success / denied / error — host-stamped from the dispatch result. */
1683
+ outcome: ActivityOutcome;
1684
+ /**
1685
+ * Role ids the acting authority carried at call time: the actor's role in
1686
+ * the organisation on a self-call, the roles the owner granted the agent on
1687
+ * a delegated call. Omitted when the authority carried no role (direct
1688
+ * grants, an individual, or an entry recorded before roles were captured).
1689
+ * On a `denied` entry this is the caller's *claimed* authority, not a
1690
+ * validated one.
1691
+ */
1692
+ roles?: string[];
1625
1693
  }
1626
1694
  /**
1627
- * Input to `T3nClient.otpVerify`. `otpCode` is mandatory; `request`
1628
- * repeats the same discriminated contact shape as {@link OtpRequestInput}.
1629
- */
1630
- interface OtpVerifyInput {
1631
- otpCode: string;
1632
- request: OtpRequestInput;
1633
- }
1634
- /**
1635
- * Suggestion surfaced when the bind-target contact already belongs
1636
- * to another DID. The contract refuses to silently steal the
1637
- * authenticator; the caller must resolve the merge (typically via
1638
- * `merge-profiles`) before re-attempting verify.
1639
- */
1640
- interface OtpMergeSuggestion {
1641
- existingDid: string;
1642
- currentDid: string;
1643
- email?: string;
1644
- phone?: string;
1645
- channel: OtpChannel;
1646
- }
1647
- /**
1648
- * Response returned by `otp-verify`. Mirrors the OTP-verify wire response.
1649
- *
1650
- * - `email` is populated on `channel = "email"` success;
1651
- * `phone` on `channel = "sms"` success. Mutually exclusive on
1652
- * the happy path.
1653
- * - `status` carries `"otp_failed"` / `"otp_expired"` on retry; the
1654
- * happy path leaves it `undefined`.
1655
- * - `mergeSuggestion` is set when the contact-to-bind is already
1656
- * owned by another DID. Wire it into your merge UX.
1657
- */
1658
- interface OtpVerifyResult {
1659
- txHash?: string;
1660
- did: string;
1661
- channel: OtpChannel;
1662
- email?: string;
1663
- phone?: string;
1664
- status?: string;
1665
- mergeSuggestion?: OtpMergeSuggestion;
1666
- isNewProfile?: boolean;
1667
- }
1668
- /**
1669
- * Level-1 user-input fields accepted by the slim `user-upsert`. Field names
1670
- * are the on-the-wire names — `submitUserInput` sends this object verbatim,
1671
- * so keys must match the contract exactly (snake_case). The canonical Level-1
1672
- * set is the six fields below; the shape is intentionally open so callers can
1673
- * add provider-specific fields the contract knows how to merge.
1674
- *
1675
- * `email_address` / `phone_number` are normally bound via the OTP roundtrip
1676
- * before `submitUserInput`, but the contract accepts them directly here too.
1695
+ * One page of the organisation's activity report — **newest first**, i.e.
1696
+ * descending `seq_no`.
1677
1697
  */
1678
- interface UserInputProfile {
1679
- first_name?: string;
1680
- last_name?: string;
1681
- country_of_residence?: string;
1682
- document_issuance_country?: string;
1683
- ssn?: string;
1684
- address?: string;
1685
- email_address?: string;
1686
- phone_number?: string;
1687
- campaign_code?: string;
1688
- role?: string;
1689
- [key: string]: unknown;
1698
+ interface ActivityReport {
1699
+ entries: ActivityEntry[];
1700
+ /**
1701
+ * Cursor to resume from — pass it back as
1702
+ * {@link GetActivityLogOptions.before_seq}. `null` once the requested window
1703
+ * is exhausted.
1704
+ *
1705
+ * A live cursor with **fewer rows than `limit`, or none at all**, is normal:
1706
+ * the node also caps how much ledger one call decrypts, and that cap can trip
1707
+ * before the window ends. Page until this is `null`, never on a short or
1708
+ * empty page.
1709
+ */
1710
+ next_seq: number | null;
1690
1711
  }
1691
- /**
1692
- * Input to `T3nClient.submitUserInput`. Maps onto the slim
1693
- * `user-upsert` request shape: `{ profile, organisation_did?,
1694
- * attestations?, keys? }`.
1695
- */
1696
- interface SubmitUserInputArgs {
1697
- profile: UserInputProfile;
1698
- organisationDid?: string;
1699
- attestations?: unknown;
1700
- keys?: Record<string, unknown>;
1712
+ /** Params for one activity-report page. All optional; `{}` is valid. */
1713
+ interface GetActivityLogOptions {
1714
+ /** Window start, Unix ms, inclusive. Defaults to 0 (no lower bound). */
1715
+ from_ms?: number;
1716
+ /** Window end, Unix ms, inclusive. Defaults to unbounded. */
1717
+ to_ms?: number;
1701
1718
  /**
1702
- * KYC webhook orphan-attestation flow. When set, the contract
1703
- * skips the email-not-verified gate and only records the
1704
- * attestation if the DID has no profile yet.
1705
- * Most callers should leave this `undefined`.
1719
+ * Cursor, inclusive — the highest `seq_no` this page may return. Omitted ⇒
1720
+ * start at the newest entry in the window. Pages walk downwards, so this is
1721
+ * the previous page's {@link ActivityReport.next_seq}.
1706
1722
  */
1707
- requireExistingUser?: boolean;
1723
+ before_seq?: number;
1708
1724
  /**
1709
- * Testnet self-admit. When `true`, the contract additionally
1710
- * runs the self-admit side-effect after the profile commit: writes
1711
- * the caller's DID into `idx:_tenants` + `idx:_tenant_quotas` and
1712
- * mints any operator-configured welcome credits. Inspect the
1713
- * `tenantAdmit` field on the response for the outcome.
1714
- *
1715
- * Testnet-only. Production clusters return
1716
- * `tenantAdmit.status = "refused"` with
1717
- * `reason = "not_testnet" | "self_admit_disabled" | "not_eth_derived"`.
1718
- * The profile commit always succeeds regardless of the inner outcome.
1725
+ * Rows returned this page. Clamped server-side to 1–1000 (default 200).
1719
1726
  *
1720
- * Most callers should leave this `undefined`.
1727
+ * A page can still be shorter than this (or empty) with a live `next_seq` —
1728
+ * the node's own scan cap can trip first. See {@link ActivityReport.next_seq}.
1721
1729
  */
1722
- becomeDevTenant?: boolean;
1730
+ limit?: number;
1723
1731
  }
1732
+
1724
1733
  /**
1725
- * Testnet self-admit projection from `user-upsert`. Present only
1726
- * when the caller set `becomeDevTenant: true` on the request.
1734
+ * Contract-discovery wire shapes.
1727
1735
  *
1728
- * - `status: "admitted"` — first call for this DID; tenant record
1729
- * committed and (if configured) welcome credits minted into
1730
- * `grantedCredits`.
1731
- * - `status: "already-admitted"` — replay; idempotent no-op.
1732
- * - `status: "refused"` — the cluster declined the self-admit;
1733
- * `reason` is the machine-readable cause (`not_testnet`,
1734
- * `self_admit_disabled`, `not_eth_derived`), `detail` is a
1735
- * human-readable string.
1736
+ * Field-for-field mirrors of the node's `contracts.list` and `delegation.check`
1737
+ * JSON-RPC responses (`service::contract_discovery::{ListedContract,
1738
+ * ListContractsResponse}` and `service::grant_check::{GrantRef,
1739
+ * GrantCheckResponse}`). Both methods are session-authenticated plaintext reads
1740
+ * dispatched over `/api/rpc` — the same posture as `token.get-usage` — so the
1741
+ * SDK wrappers return the parsed `result` object directly.
1736
1742
  */
1737
- type TenantAdmitStatus = "admitted" | "already-admitted" | "refused";
1738
- interface TenantAdmitProjection {
1739
- status: TenantAdmitStatus;
1740
- grantedCredits?: string;
1741
- reason?: string;
1742
- detail?: string;
1743
+ /** The navigable starting points of the discovery funnel. */
1744
+ type ListContractsScope = "core" | "org" | "self";
1745
+ /** Params for `contracts.list` (every field optional; `{}` lists core). */
1746
+ interface ListContractsParams {
1747
+ /** `"core"` (default) | `"org"` | `"self"`. */
1748
+ scope?: ListContractsScope;
1749
+ /** Target org DID (required for scope `"org"`). */
1750
+ org_did?: string;
1751
+ /** The member the agent acts for (required for scope `"org"` / `"self"`). */
1752
+ pii_did?: string;
1753
+ /** Page offset (defaults to 0 server-side). */
1754
+ offset?: number;
1755
+ /** Page size (defaults + clamped server-side). */
1756
+ limit?: number;
1743
1757
  }
1744
- /**
1745
- * Response shape returned by the slim `user-upsert`. Carries the
1746
- * post-merge tx hash plus the Level-1 merge diagnostics
1747
- * (`refusedFields`, `mergeSuggestion`) the pre-2.0.0 omnibus
1748
- * `UpsertResponse` already surfaced.
1749
- */
1750
- interface SubmitUserInputResult {
1751
- txHash?: string;
1752
- refusedFields?: string[];
1753
- mergeSuggestion?: OtpMergeSuggestion;
1754
- userFound?: boolean;
1758
+ /** Contract kind — `"core"` platform system contract, `"tenant"` z-space. */
1759
+ type ContractKind = "core" | "tenant";
1760
+ /** One contract as presented by `contracts.list`. */
1761
+ interface ListedContract {
1762
+ /** Canonical name: `tee:<name>` for core, `z:<tid>:<tail>` for tenant. */
1763
+ name: string;
1764
+ kind: ContractKind;
1765
+ /** Current registered version; `null` when the contract is not registered. */
1766
+ version: string | null;
1767
+ /** Descriptor summary, or empty when no descriptor is published. */
1768
+ summary: string;
1769
+ /** Descriptor tags, or empty. */
1770
+ tags: string[];
1771
+ /** Owning DID: the org DID (org mode) or the member's own DID (self mode). */
1772
+ owner_org_did?: string;
1755
1773
  /**
1756
- * Testnet self-admit projection. Present only when the caller
1757
- * set `becomeDevTenant: true` on the request.
1774
+ * Human-facing short name: the trailing segment of `name` (`payroll` from
1775
+ * `z:<tid>:payroll`, `user` from `tee:user`). Present this to people instead
1776
+ * of the full canonical `name`, which remains the dispatch key.
1758
1777
  */
1759
- tenantAdmit?: TenantAdmitProjection;
1778
+ short_name: string;
1779
+ }
1780
+ /** Response body for `contracts.list`. */
1781
+ interface ListContractsResult {
1782
+ scope: string;
1783
+ contracts: ListedContract[];
1784
+ next_offset: number | null;
1785
+ }
1786
+ /** Which standing grant a satisfied/missing entry refers to. */
1787
+ type DelegationGrantKind = "agent_auth" | "user_grant";
1788
+ /** Params for `delegation.check` (the generic capability read). */
1789
+ interface GrantCheckParams {
1790
+ /** The target contract whose requirements are checked. */
1791
+ contract: string;
1792
+ /** The member the agent wants to act for (the subject). */
1793
+ pii_did: string;
1794
+ /** Functions the intended action needs. */
1795
+ functions: string[];
1796
+ /** Org-data scopes the intended action needs. */
1797
+ scopes: string[];
1798
+ }
1799
+ /** One grant requirement — satisfied or missing. */
1800
+ interface DelegationGrantRef {
1801
+ grant: DelegationGrantKind;
1802
+ /** The target contract's canonical name. */
1803
+ contract: string;
1804
+ functions: string[];
1805
+ scopes: string[];
1760
1806
  }
1761
1807
  /**
1762
- * Discriminator for {@link UserUpsertError}. Mirrors the
1763
- * `UserUpsertError` wire enum and its `<code>:<detail>` wire
1764
- * format. Branch with a `switch` over `kind`.
1808
+ * Response for `delegation.check`: the `agent_auth ∩ UserGrant` verdict.
1765
1809
  *
1766
- * - `EmailNotVerified` — the slim `user-upsert` was called against
1767
- * a DID that has no verified email and no proving authenticator.
1768
- * Run `otpRequest` + `otpVerify` first (or accept an
1769
- * OIDC/Email-authed session).
1770
- * - `LegacyField` — caller passed a pre-2.0.0 dispatch field
1771
- * (`otp_code` to a non-verify export, or
1772
- * `keys.generic_api.otp_channel` anywhere). Migrate the call
1773
- * site to the new explicit functions.
1774
- * - `UserNotFound` — `requireExistingUser` was set but no profile
1775
- * exists for the DID. The attestation is recorded for audit;
1776
- * no profile created.
1810
+ * `disclosed` is `true` only when the agent is registered under `pii_did`, so
1811
+ * org-side status was safe to disclose; `false` yields the uniform,
1812
+ * non-disclosive verdict (`authorised:false, satisfied:[], missing:[]`) that is
1813
+ * byte-invariant to the requested capability (R5 anti-enumeration).
1777
1814
  */
1778
- type UserUpsertErrorKind = "EmailNotVerified" | "LegacyField" | "UserNotFound";
1815
+ interface GrantCheckResult {
1816
+ authorised: boolean;
1817
+ disclosed: boolean;
1818
+ satisfied: DelegationGrantRef[];
1819
+ missing: DelegationGrantRef[];
1820
+ }
1821
+
1779
1822
  /**
1780
- * Typed wrapper for the `<code>:<detail>` errors the slim
1781
- * `user-upsert` and the OTP entry points emit. `kind` is the
1782
- * structured discriminator the SDK derives from the error code
1783
- * prefix; `code` and `detail` retain the wire components for
1784
- * fall-through logging.
1823
+ * T3n Client - Main SDK class
1785
1824
  *
1786
- * Throw site: `T3nClient.submitUserInput` (and friends) when the
1787
- * contract returns a string error matching the
1788
- * `<code>:<detail>` shape.
1825
+ * Provides a simple interface for establishing secure sessions with T3n nodes.
1826
+ * All cryptographic complexity is handled in WASM components.
1789
1827
  */
1790
- declare class UserUpsertError extends T3nError {
1791
- readonly kind: UserUpsertErrorKind | "Unknown";
1792
- readonly detail: string;
1793
- constructor(code: string, detail: string);
1794
- /**
1795
- * Try to parse a contract error string into a `UserUpsertError`.
1796
- * Returns `null` if `raw` doesn't match the `<code>:<detail>`
1797
- * shape — caller falls back to a generic error.
1798
- */
1799
- static fromWire(raw: string): UserUpsertError | null;
1800
- }
1801
-
1802
- /**
1803
- * Token-metering wire shapes.
1804
- *
1805
- * Mirrors the token-metering wire contract. `u128` fields land on the
1806
- * wire as JSON numbers (same convention as the existing
1807
- * `token.get-balance` response) — JS clients with histories that
1808
- * exceed 2⁵³ tokens should switch to a streaming JSON parser; the
1809
- * common case fits in `number` losslessly.
1810
- */
1811
- /**
1812
- * The token `BalanceRow` wire shape — caller's credit row.
1813
- *
1814
- * `available` and `reserved` are `u128` on the server; the wire
1815
- * format is a JSON number. Callers should not assume bigint until
1816
- * the SDK migrates to a streaming parser (tracked separately).
1817
- *
1818
- * ⚠️ Amounts are in **base units** (`1 token = `
1819
- * {@link BASE_UNITS_PER_TOKEN}), not whole tokens. Use
1820
- * {@link formatTokens} to display them.
1821
- */
1822
- interface BalanceRow {
1823
- /** Spendable balance, in base units (see {@link formatTokens}). */
1824
- available: number;
1825
- /** Reserved balance, in base units. */
1826
- reserved: number;
1827
- last_settled_seq_no: number;
1828
- version: number;
1829
- credit_exhausted: boolean;
1830
- }
1831
- /**
1832
- * The token-tx-kind wire alphabet (snake_case). Every
1833
- * value listed here is accepted by the server-side
1834
- * `token.get-usage` `kinds` filter.
1835
- */
1836
- type TokenTxKind = "mint" | "burn" | "charge" | "transfer" | "bridge_mint_attest" | "bridge_burn_attest";
1837
- /**
1838
- * Per-caller view direction. `"in"` = caller's balance went up;
1839
- * `"out"` = caller's balance went down. Derived host-side from
1840
- * `(caller_did, tx.src, tx.dst)`; the same `seq_no` appears in both
1841
- * parties' usage feeds with opposite directions on a transfer.
1842
- */
1843
- type Direction = "in" | "out";
1844
- /**
1845
- * Discriminated union mirroring the charge-reason wire union.
1846
- * Present only when the row's `kind === "charge"`.
1847
- */
1848
- type ChargeReason = {
1849
- kind: "contract_register";
1850
- script_name: string;
1851
- version: string;
1852
- } | {
1853
- kind: "invocation";
1854
- script_name: string;
1855
- function: string;
1856
- fuel_consumed: number;
1857
- fuel_tokens: number;
1858
- host_call_count: number;
1859
- host_call_tokens: number;
1860
- } | {
1861
- kind: "kv_bytes";
1862
- map: string;
1863
- } | {
1864
- kind: "cas_bytes";
1865
- backend: string;
1866
- } | {
1867
- kind: "outbox_egress";
1868
- upstream: string;
1869
- };
1870
- /**
1871
- * One row in the caller's usage feed — a per-caller projection of
1872
- * the underlying `TokenTx`. `counterparty` is the other party from
1873
- * the caller's perspective: `tx.dst` on outbound entries, `tx.src`
1874
- * on inbound. `null` when the underlying tx has no counterparty
1875
- * (mints have no `src`; burns and charges have no `dst`).
1876
- */
1877
- interface UsageEntry {
1878
- seq_no: number;
1879
- kind: TokenTxKind;
1880
- /** Amount moved, in base units (`1 token = `{@link BASE_UNITS_PER_TOKEN}); see {@link formatTokens}. */
1881
- amount: number;
1882
- timestamp_ms: number;
1883
- direction: Direction;
1884
- counterparty?: string | null;
1885
- reason?: ChargeReason | null;
1886
- note?: string | null;
1887
- }
1888
- /**
1889
- * Response shape of `token.get-usage` — caller's balance plus a
1890
- * paginated slice of their most-recent `token:tx_log` entries.
1891
- *
1892
- * `next_cursor` is the inclusive upper-bound `seq_no` to pass back
1893
- * as `after_seq` to fetch the next page. `null` (or absent) means
1894
- * the caller's history is fully drained.
1895
- */
1896
- interface UsagePage {
1897
- balance: BalanceRow;
1898
- entries: UsageEntry[];
1899
- next_cursor?: number | null;
1900
- }
1901
- /**
1902
- * Request shape — all fields optional. `limit` clamps to
1903
- * `1..=200` server-side; out-of-range values snap silently to the
1904
- * bounds. `kinds: []` is treated as "no filter".
1905
- */
1906
- interface GetUsageOptions {
1907
- limit?: number;
1908
- after_seq?: number;
1909
- kinds?: TokenTxKind[];
1910
- }
1911
1828
 
1912
1829
  /**
1913
- * Tenant audit-event wire shapes.
1914
- *
1915
- * Mirrors `tenant_types::AuditEvent` and the `audit.get-mine` response
1916
- * (`service::tenant_logs::{AuditBatch, AuditPage}`). A tenant contract
1917
- * emits an audit event via the `logging::audit` host call; the host
1918
- * stamps the identity fields (`subject` / `actor` / `vc_id`) from the
1919
- * verified dispatch context, so a contract can never forge who acted or
1920
- * on whom. Events are permanent (encrypted, append-only) and scoped to a
1921
- * user — distinct from the evicting debug ring read via `getContractLogs`.
1922
- */
1923
- /**
1924
- * One host-stamped audit event. `subject` / `actor` are canonical DID
1925
- * strings. On a self-call `actor === subject` and `vc_id` is `null`; on a
1926
- * delegated call `actor` is the agent and `vc_id` is the delegation
1927
- * credential. The remaining fields are supplied verbatim by the contract.
1928
- */
1929
- interface AuditEvent {
1930
- /** Cluster-deterministic flush timestamp (ms). */
1931
- ts_ms: number;
1932
- /** The user whose data the call touched (host-stamped `pii_did`). */
1933
- subject: string;
1934
- /** The agent (delegated) or user (self-call) who acted (host-stamped). */
1935
- actor: string;
1936
- /** Delegation credential id on a delegated call; `null` on a self-call. */
1937
- vc_id?: string | null;
1938
- /** Contract-supplied: what happened, e.g. `"kyc.approve"`. */
1939
- action: string;
1940
- /** Contract-supplied: what it acted on, e.g. `"user-profile"`. */
1941
- target: string;
1942
- /** Contract-supplied: the result, e.g. `"success"` / `"denied"`. */
1943
- outcome: string;
1944
- /** Contract-supplied: optional free-text / JSON detail. */
1945
- details?: string | null;
1946
- }
1947
- /**
1948
- * One archived batch — the events committed in a single tenant dispatch.
1949
- * Every event in a batch shares the same `subject` / `actor` / `vc_id`.
1830
+ * Main T3n SDK Client
1950
1831
  */
1951
- interface AuditBatch {
1952
- /** Hex of the archive key — usable directly as `cursor` for the next page. */
1953
- key: string;
1832
+ declare class T3nClient {
1833
+ private readonly config;
1834
+ private readonly transport;
1954
1835
  /**
1955
- * Host-stamped: did the emitting dispatch's contract transaction
1956
- * commit? `false` means the call rolled back or trapped, so an event's
1957
- * `outcome: "success"` in this batch is the contract's *claim*, not a
1958
- * committed fact — filter on this when you need only durable events.
1836
+ * Resolved node base URL. Snapshotted in the constructor so the
1837
+ * typed contract wrappers (`kycStatus`, `getSelfEthAddress`, …)
1838
+ * can call `getScriptVersion()` against the same host the
1839
+ * transport talks to. Used only by the `script_version: "latest"`
1840
+ * resolution path in {@link executeUserContract}.
1959
1841
  */
1960
- committed: boolean;
1961
- events: AuditEvent[];
1962
- }
1963
- /**
1964
- * `audit.get-mine` response — a page of audit batches, newest scan order.
1965
- * `next_cursor` is present (a key hex) when more batches remain; `null`
1966
- * once the scan reaches the end.
1967
- */
1968
- interface AuditPage {
1969
- batches: AuditBatch[];
1970
- next_cursor?: string | null;
1971
- }
1972
- /**
1973
- * Request shape for {@link T3nClient.getAuditEvents} — all fields
1974
- * optional. Omit `pii_did` to read your own trail (all actors); set it to
1975
- * another user's DID to read, as a delegated agent, the events you
1976
- * performed for them — admitted only while that user's agent-auth grant
1977
- * to you is live. `cursor` is the `next_cursor` from a prior page.
1978
- */
1979
- interface GetAuditEventsOptions {
1980
- pii_did?: string;
1981
- limit?: number;
1982
- cursor?: string;
1983
- }
1984
-
1985
- /**
1986
- * Agent-activity audit-log wire shapes (the node's `auditlog` RPC).
1987
- *
1988
- * Mirrors `service::activity_audit::{ActivityReport, ReportEntry}` and
1989
- * `primitives::audit_log::AuditLogEntry`. One entry per audited contract
1990
- * dispatch — who called, for whom, which contract + function, and how it
1991
- * ended. Entries are reconstructed from the append-only ledger on read, so
1992
- * `seq_no` (the ledger index) and `hash` are derived server-side rather than
1993
- * stored with the record.
1994
- *
1995
- * Scope is the caller's **own organisation**, resolved node-side from the
1996
- * session DID: there is no scope parameter, and a page carries **every
1997
- * member's** activity in that org, not just the caller's own. Metadata only —
1998
- * DIDs, never display names, call arguments, or payloads.
1999
- */
2000
- /**
2001
- * Whether the actor is a registered agent or a human / self principal.
2002
- * Decided node-side by an existence check on the actor DID in the agent
2003
- * registry — never inferred from the DID's shape.
2004
- */
2005
- type ActivityCallerType = "agent" | "human";
2006
- /**
2007
- * Host-stamped outcome of an audited dispatch.
2008
- *
2009
- * - `success` — the business transaction committed.
2010
- * - `denied` — authorisation refused the call.
2011
- * - `error` — the call was allowed but failed / rolled back.
2012
- */
2013
- type ActivityOutcome = "success" | "denied" | "error";
2014
- /** One audited call. */
2015
- interface ActivityEntry {
1842
+ private readonly effectiveBaseUrl;
2016
1843
  /**
2017
- * Ledger index of the entry — its unique, ordered id. Use it as the row key
2018
- * and as the ordering key: it is monotonic, whereas {@link timestamp_ms} is
2019
- * per-node wall clock.
1844
+ * Server-minted session ID, set by {@link handshake} from the
1845
+ * `Session-Id` response header. `null`
1846
+ * until the handshake completes. Client code cannot set it — a
1847
+ * client-supplied session id is rejected, closing the
1848
+ * session-fixation vector.
2020
1849
  */
2021
- seq_no: number;
2022
- /** Hex SHA-256 of the stored entry (64 chars) — read-time tamper evidence. */
2023
- hash: string;
1850
+ private sessionId;
2024
1851
  /**
2025
- * Call time in Unix ms, stamped on the node that took the request. NOT a
2026
- * cluster-assigned time, so entries from different nodes can be skewed by
2027
- * their clock offset — order by {@link seq_no}, not by this.
1852
+ * Set by {@link sendRpcRequest} when an `auth.handshake` RPC is
1853
+ * actually issued. Decouples the "flow completed without talking
1854
+ * to a server" case (unit-test mocks that only exercise handler
1855
+ * delegation) from the real "server must mint the id" invariant:
1856
+ * we only enforce the mint requirement when a round-trip happened.
2028
1857
  */
2029
- timestamp_ms: number;
2030
- /** Agent vs human, from the agent-registry check on {@link actor}. */
2031
- caller_type: ActivityCallerType;
2032
- /** DID that actually invoked the contract. */
2033
- actor: string;
2034
- /**
2035
- * DID of the owner the caller acted for. Equals {@link actor} on a self /
2036
- * own-authority call — never null.
2037
- */
2038
- on_behalf_of: string;
2039
- /**
2040
- * Organisation the acting principal belongs to — the report's scope key, so
2041
- * it is identical on every row of a page. Falls back to `on_behalf_of` when
2042
- * that principal is in no organisation.
2043
- */
2044
- org: string;
2045
- /** Contract that ran, e.g. `tee:user/contracts`. */
2046
- contract: string;
2047
- /** Contract function invoked, e.g. `user-upsert`. */
2048
- function: string;
2049
- /** success / denied / error — host-stamped from the dispatch result. */
2050
- outcome: ActivityOutcome;
2051
- /**
2052
- * Role ids the acting authority carried at call time: the actor's role in
2053
- * the organisation on a self-call, the roles the owner granted the agent on
2054
- * a delegated call. Omitted when the authority carried no role (direct
2055
- * grants, an individual, or an entry recorded before roles were captured).
2056
- * On a `denied` entry this is the caller's *claimed* authority, not a
2057
- * validated one.
2058
- */
2059
- roles?: string[];
2060
- }
2061
- /**
2062
- * One page of the organisation's activity report — **newest first**, i.e.
2063
- * descending `seq_no`.
2064
- */
2065
- interface ActivityReport {
2066
- entries: ActivityEntry[];
2067
- /**
2068
- * Cursor to resume from — pass it back as
2069
- * {@link GetActivityLogOptions.before_seq}. `null` once the requested window
2070
- * is exhausted.
2071
- *
2072
- * A live cursor with **fewer rows than `limit`, or none at all**, is normal:
2073
- * the node also caps how much ledger one call decrypts, and that cap can trip
2074
- * before the window ends. Page until this is `null`, never on a short or
2075
- * empty page.
2076
- */
2077
- next_seq: number | null;
2078
- }
2079
- /** Params for one activity-report page. All optional; `{}` is valid. */
2080
- interface GetActivityLogOptions {
2081
- /** Window start, Unix ms, inclusive. Defaults to 0 (no lower bound). */
2082
- from_ms?: number;
2083
- /** Window end, Unix ms, inclusive. Defaults to unbounded. */
2084
- to_ms?: number;
2085
- /**
2086
- * Cursor, inclusive — the highest `seq_no` this page may return. Omitted ⇒
2087
- * start at the newest entry in the window. Pages walk downwards, so this is
2088
- * the previous page's {@link ActivityReport.next_seq}.
2089
- */
2090
- before_seq?: number;
2091
- /**
2092
- * Rows returned this page. Clamped server-side to 1–1000 (default 200).
2093
- *
2094
- * A page can still be shorter than this (or empty) with a live `next_seq` —
2095
- * the node's own scan cap can trip first. See {@link ActivityReport.next_seq}.
2096
- */
2097
- limit?: number;
2098
- }
2099
-
2100
- /**
2101
- * Contract-discovery wire shapes.
2102
- *
2103
- * Field-for-field mirrors of the node's `contracts.list` and `delegation.check`
2104
- * JSON-RPC responses (`service::contract_discovery::{ListedContract,
2105
- * ListContractsResponse}` and `service::grant_check::{GrantRef,
2106
- * GrantCheckResponse}`). Both methods are session-authenticated plaintext reads
2107
- * dispatched over `/api/rpc` — the same posture as `token.get-usage` — so the
2108
- * SDK wrappers return the parsed `result` object directly.
2109
- */
2110
- /** The navigable starting points of the discovery funnel. */
2111
- type ListContractsScope = "core" | "org" | "self";
2112
- /** Params for `contracts.list` (every field optional; `{}` lists core). */
2113
- interface ListContractsParams {
2114
- /** `"core"` (default) | `"org"` | `"self"`. */
2115
- scope?: ListContractsScope;
2116
- /** Target org DID (required for scope `"org"`). */
2117
- org_did?: string;
2118
- /** The member the agent acts for (required for scope `"org"` / `"self"`). */
2119
- pii_did?: string;
2120
- /** Page offset (defaults to 0 server-side). */
2121
- offset?: number;
2122
- /** Page size (defaults + clamped server-side). */
2123
- limit?: number;
2124
- }
2125
- /** Contract kind — `"core"` platform system contract, `"tenant"` z-space. */
2126
- type ContractKind = "core" | "tenant";
2127
- /** One contract as presented by `contracts.list`. */
2128
- interface ListedContract {
2129
- /** Canonical name: `tee:<name>` for core, `z:<tid>:<tail>` for tenant. */
2130
- name: string;
2131
- kind: ContractKind;
2132
- /** Current registered version; `null` when the contract is not registered. */
2133
- version: string | null;
2134
- /** Descriptor summary, or empty when no descriptor is published. */
2135
- summary: string;
2136
- /** Descriptor tags, or empty. */
2137
- tags: string[];
2138
- /** Owning DID: the org DID (org mode) or the member's own DID (self mode). */
2139
- owner_org_did?: string;
2140
- /**
2141
- * Human-facing short name: the trailing segment of `name` (`payroll` from
2142
- * `z:<tid>:payroll`, `user` from `tee:user`). Present this to people instead
2143
- * of the full canonical `name`, which remains the dispatch key.
2144
- */
2145
- short_name: string;
2146
- }
2147
- /** Response body for `contracts.list`. */
2148
- interface ListContractsResult {
2149
- scope: string;
2150
- contracts: ListedContract[];
2151
- next_offset: number | null;
2152
- }
2153
- /** Which standing grant a satisfied/missing entry refers to. */
2154
- type DelegationGrantKind = "agent_auth" | "org_grant";
2155
- /** Params for `delegation.check` (the generic capability read). */
2156
- interface GrantCheckParams {
2157
- /** The target contract whose requirements are checked. */
2158
- contract: string;
2159
- /** The member the agent wants to act for (the subject). */
2160
- pii_did: string;
2161
- /** Functions the intended action needs. */
2162
- functions: string[];
2163
- /** Org-data scopes the intended action needs. */
2164
- scopes: string[];
2165
- }
2166
- /** One grant requirement — satisfied or missing. */
2167
- interface DelegationGrantRef {
2168
- grant: DelegationGrantKind;
2169
- /** The target contract's canonical name. */
2170
- contract: string;
2171
- functions: string[];
2172
- scopes: string[];
2173
- }
2174
- /**
2175
- * Response for `delegation.check`: the `agent_auth ∩ org_grant` verdict.
2176
- *
2177
- * `disclosed` is `true` only when the agent is registered under `pii_did`, so
2178
- * org-side status was safe to disclose; `false` yields the uniform,
2179
- * non-disclosive verdict (`authorised:false, satisfied:[], missing:[]`) that is
2180
- * byte-invariant to the requested capability (R5 anti-enumeration).
2181
- */
2182
- interface GrantCheckResult {
2183
- authorised: boolean;
2184
- disclosed: boolean;
2185
- satisfied: DelegationGrantRef[];
2186
- missing: DelegationGrantRef[];
2187
- }
2188
-
2189
- /**
2190
- * T3n Client - Main SDK class
2191
- *
2192
- * Provides a simple interface for establishing secure sessions with T3n nodes.
2193
- * All cryptographic complexity is handled in WASM components.
2194
- */
2195
-
2196
- /**
2197
- * Main T3n SDK Client
2198
- */
2199
- declare class T3nClient {
2200
- private readonly config;
2201
- private readonly transport;
2202
- /**
2203
- * Resolved node base URL. Snapshotted in the constructor so the
2204
- * typed contract wrappers (`kycStatus`, `getSelfEthAddress`, …)
2205
- * can call `getContractVersion()` against the same host the
2206
- * transport talks to. Used only by the `contract_version: "latest"`
2207
- * resolution path in {@link executeUserContract}.
2208
- */
2209
- private readonly effectiveBaseUrl;
2210
- /**
2211
- * Server-minted session ID, set by {@link handshake} from the
2212
- * `Session-Id` response header. `null`
2213
- * until the handshake completes. Client code cannot set it — a
2214
- * client-supplied session id is rejected, closing the
2215
- * session-fixation vector.
2216
- */
2217
- private sessionId;
2218
- /**
2219
- * Set by {@link sendRpcRequest} when an `auth.handshake` RPC is
2220
- * actually issued. Decouples the "flow completed without talking
2221
- * to a server" case (unit-test mocks that only exercise handler
2222
- * delegation) from the real "server must mint the id" invariant:
2223
- * we only enforce the mint requirement when a round-trip happened.
2224
- */
2225
- private handshakeSentRpc;
2226
- private readonly logger;
2227
- private readonly encryption;
2228
- private status;
1858
+ private handshakeSentRpc;
1859
+ private readonly logger;
1860
+ private readonly encryption;
1861
+ private status;
2229
1862
  /**
2230
1863
  * In-flight WASM state-machine bytes. Holds the opaque state
2231
1864
  * returned by `flow[method].next()` between iterations of
@@ -2402,7 +2035,7 @@ declare class T3nClient {
2402
2035
  * Generic capability check (`delegation.check`) — the
2403
2036
  * node-backed source for the MCP `checkDelegation` funnel tool.
2404
2037
  *
2405
- * Returns the `agent_auth ∩ org_grant` verdict for `(agent, contract,
2038
+ * Returns the `agent_auth ∩ UserGrant` verdict for `(agent, contract,
2406
2039
  * pii_did)`: whether the acting agent (resolved from the session) holds the
2407
2040
  * standing grants that `contract`'s `functions` / `scopes` need for member
2408
2041
  * `pii_did`. The org half is vacuous for no-org (Individual-owned) targets,
@@ -2641,10 +2274,10 @@ declare class T3nClient {
2641
2274
  * (org-admin gated; idempotent on an already-absent membership). The host
2642
2275
  * membership gate makes the detach effective immediately.
2643
2276
  * 2. `org-remove-member-grants` — sweep the member from the org's
2644
- * per-contract `BoundGrant` lists, so the capability does not silently
2277
+ * per-contract `UserGrant` lists, so the capability does not silently
2645
2278
  * reactivate if the member later rejoins.
2646
2279
  *
2647
- * The member's `agent_auth` delegations are self-scoped (the agent-auth edge in `ROLE_ASSIGNMENTS_MAP` is a
2280
+ * The member's `agent_auth` delegations are self-scoped (`AGENT_AUTH_MAP` is a
2648
2281
  * per-user document an admin cannot reach), so this cannot sweep them; the host
2649
2282
  * membership gate denies them regardless, and the member's own session can run
2650
2283
  * {@link revokeAgentAuthForOrg} for full cleanup.
@@ -2675,7 +2308,7 @@ declare class T3nClient {
2675
2308
  * Revoke the caller's own agent delegations scoped to one org
2676
2309
  * (detach-cascade `agent_auth` half). Dispatches
2677
2310
  * `agent-auth-revoke-org` on `tee:user/contracts` (**SelfOnly**): every
2678
- * agent-edge grant targeting a `z:<orgTid>:*` contract is removed from the
2311
+ * `ScriptGrant` targeting a `z:<orgTid>:*` contract is removed from the
2679
2312
  * caller's own agent-auth document.
2680
2313
  *
2681
2314
  * @param orgTid - the org's z-space tenant id (`did:t3n:<hex>` or bare
@@ -2687,27 +2320,25 @@ declare class T3nClient {
2687
2320
  * grants delegated to agents. Dispatches `agent-auth-get` on
2688
2321
  * `tee:authorisations/contracts` (the policy's owning contract), which is
2689
2322
  * **SelfOnly**, so this always returns the caller's own
2690
- * agent-auth edge in `ROLE_ASSIGNMENTS_MAP`.
2323
+ * `AGENT_AUTH_MAP[self]` document.
2691
2324
  *
2692
- * @returns the full policy document as the flat snake_case wire shape: the
2693
- * `grants` list (each row's `grantee` is the authorised agent DID) plus the
2694
- * document-level `discover_dids` discovery grants
2325
+ * @returns the full policy document (normalised to the camelCase write
2326
+ * shape): the per-agent `agents` entries plus the document-level
2327
+ * `discoverDids` discovery grants
2695
2328
  * @throws if the session is not authenticated, or the contract refuses
2696
2329
  */
2697
- getAgentAuth(): Promise<AgentAuthDoc>;
2330
+ getAgentAuth(): Promise<AgentAuthPolicy>;
2698
2331
  /**
2699
2332
  * Authorise an agent for one contract on the caller's own behalf
2700
2333
  * (envelope-free authorisation). Read-merge-writes the
2701
- * caller's agent-auth edge in `ROLE_ASSIGNMENTS_MAP` via `agent-auth-update`
2702
- * (**SelfOnly**) with `(grantee, contract_id)` union semantics, so other
2703
- * contracts' grants for this or any agent survive untouched.
2334
+ * caller's `AGENT_AUTH_MAP[self]` document via `agent-auth-update`
2335
+ * (**SelfOnly**) with script-level union semantics, so other contracts'
2336
+ * grants for this or any agent survive untouched.
2704
2337
  *
2705
- * The grant is the flat wire {@link BoundGrant}: its `grantee` is the agent
2706
- * DID being authorised, and it carries `functions`, the delegated org-data
2707
- * `scopes`, direct-read `read_scopes`, egress `allowed_hosts`, an optional
2708
- * semver `version_req`, and an optional validity `window`. The ≤ cap *length*
2709
- * check is enforced contract-side at write time; the expiry gate is host-side
2710
- * at read time.
2338
+ * Carries the new `scopes` + validity fields: the delegated
2339
+ * org-data scopes and an optional `[validFromSecs, validUntilSecs]`
2340
+ * window. The ≤ cap *length* check is enforced contract-side at write
2341
+ * time; the expiry gate is host-side at read time.
2711
2342
  *
2712
2343
  * This is the write surface `getDelegationInstructions` produces the
2713
2344
  * parameters for. The caller MUST be the delegating user, authenticated as
@@ -2719,38 +2350,38 @@ declare class T3nClient {
2719
2350
  * standing discovery), and any `options.discoverDids` are unioned in
2720
2351
  * (order-preserving, deduplicated).
2721
2352
  *
2722
- * @param grant - the single grant to set — a {@link BoundGrant} whose
2723
- * `grantee` is the agent DID being authorised (contract_id, functions,
2724
- * scopes, window, egress hosts)
2353
+ * @param agentDid - the agent DID being authorised
2354
+ * @param grant - the single script grant to set (contract, functions,
2355
+ * scopes, validity, egress hosts)
2725
2356
  * @param options - optional `discoverDids` to union into the document's
2726
2357
  * discovery grants (org DIDs for org-mode `listContracts`, the caller's
2727
2358
  * own DID for self mode)
2728
- * @returns the grant rows preserved from the existing policy (audit aid)
2359
+ * @returns the script rows preserved from the existing policy (audit aid)
2729
2360
  * @throws if the session is not authenticated, or the contract refuses
2730
2361
  */
2731
- updateAgentAuth(grant: BoundGrant, options?: {
2362
+ updateAgentAuth(agentDid: string, grant: AgentAuthScriptGrant, options?: {
2732
2363
  discoverDids?: string[];
2733
2364
  }): Promise<{
2734
2365
  preservedRows: string[];
2735
2366
  }>;
2736
2367
  /**
2737
2368
  * Build the canonical `ExecuteActionRequest` shape the server
2738
- * expects (`contract_id`, `contract_version`, `function_name`, `input`,
2369
+ * expects (`script_name`, `script_version`, `function_name`, `input`,
2739
2370
  * optional `pii_did`) and dispatch it through {@link execute}.
2740
2371
  *
2741
2372
  * Two pieces of glue live here that every typed user-contract
2742
2373
  * wrapper would otherwise duplicate:
2743
2374
  *
2744
2375
  * 1. **Field naming.** The server deserialises strictly into
2745
- * `contract_id` / `contract_version` / `function_name` —
2376
+ * `script_name` / `script_version` / `function_name` —
2746
2377
  * sending `contract` / `version` / `function` produces
2747
2378
  * `Invalid action request: missing field …` 400s. Centralising
2748
2379
  * the names here means every wrapper agrees with the server.
2749
- * 2. **`"latest"` resolution.** `contract_version` is `SemVer` on
2380
+ * 2. **`"latest"` resolution.** `script_version` is `SemVer` on
2750
2381
  * the server, so a literal `"latest"` cannot be parsed. We
2751
2382
  * fetch the registered current version via
2752
2383
  * `GET /api/contracts/current?name=…` (cached per script name
2753
- * in `getContractVersion`) and forward the resolved
2384
+ * in `getScriptVersion`) and forward the resolved
2754
2385
  * `MAJOR.MINOR.PATCH` string.
2755
2386
  *
2756
2387
  * Wrappers that need PII delegation can extend this helper
@@ -3015,24 +2646,25 @@ declare class T3nClient {
3015
2646
  */
3016
2647
  submitUserInput(input: SubmitUserInputArgs): Promise<SubmitUserInputResult>;
3017
2648
  /**
3018
- * Replace this user's agent-authorisation policy (`tee:authorisations/contracts`
3019
- * → `agent-auth-update`). The supplied document IS the new state: an empty
3020
- * `grants` array revokes all agent access, and an empty `discover_dids`
2649
+ * Replace this user's agent-authorisation policy (`tee:user/contracts` →
2650
+ * `agent-auth-update`). The supplied document IS the new state: an empty
2651
+ * `agents` array revokes all agent access, and an omitted `discoverDids`
3021
2652
  * persists an empty discovery-grant list. This is the full-document
3022
2653
  * write — use {@link T3nClient.updateAgentAuth} for the single-grant
3023
2654
  * read-merge-write that preserves other contracts' grants and the
3024
2655
  * standing discovery grants.
3025
2656
  *
3026
- * The {@link AgentAuthDoc} IS the snake_case wire shape — grant rows are
3027
- * {@link BoundGrant} verbatim — so the document passes straight through with
3028
- * no casing transform. Absent per-grant qualifiers (`version_req` /
3029
- * `read_scopes` / `allowed_hosts` / `window`) are simply unset on the object
3030
- * and so omitted from the JSON.
2657
+ * Typed wrapper over the raw contract call: callers pass camelCase input;
2658
+ * the SDK emits the canonical snake_case wire via
2659
+ * {@link toAgentAuthUpdateWire} (carrying `scopes` / `read_scopes` /
2660
+ * validity alongside `functions` / `allowed_hosts`, plus the
2661
+ * document-level `discover_dids`), so it does not rely on the contract's
2662
+ * compatibility aliases.
3031
2663
  *
3032
2664
  * @throws {RpcError} if the contract rejects the policy (validation failure,
3033
2665
  * too many agents/grants).
3034
2666
  */
3035
- agentAuthUpdate(input: AgentAuthDoc): Promise<void>;
2667
+ agentAuthUpdate(input: AgentAuthUpdateInput): Promise<void>;
3036
2668
  /**
3037
2669
  * Convenience helper: run the explicit OTP roundtrip and submit
3038
2670
  * the slim user-upsert in one call.
@@ -3215,250 +2847,628 @@ declare class T3nClient {
3215
2847
  private throwIfRpcError;
3216
2848
  private sendMultipartRpcRequest;
3217
2849
  /**
3218
- * Capture the server-minted `Session-Id` from the last handshake
3219
- * response headers. Validates shape so a
3220
- * broken or MITM'd response fails loudly instead of leaving a
3221
- * garbage value in the client. Idempotent: only the first valid
3222
- * mint per session is honoured — subsequent handshake RPC legs
3223
- * (none exist today, but the state-machine loop can iterate) do
3224
- * not overwrite an already-set value.
2850
+ * Capture the server-minted `Session-Id` from the last handshake
2851
+ * response headers. Validates shape so a
2852
+ * broken or MITM'd response fails loudly instead of leaving a
2853
+ * garbage value in the client. Idempotent: only the first valid
2854
+ * mint per session is honoured — subsequent handshake RPC legs
2855
+ * (none exist today, but the state-machine loop can iterate) do
2856
+ * not overwrite an already-set value.
2857
+ */
2858
+ private captureMintedSessionId;
2859
+ /**
2860
+ * Get the finalized session blob (for `session.encrypt` calls).
2861
+ * Populated by `tryFinalize` once the handshake state machine
2862
+ * reaches its terminal phase.
2863
+ */
2864
+ private getSessionState;
2865
+ }
2866
+
2867
+ /**
2868
+ * Guest-to-Host Request Handlers
2869
+ *
2870
+ * These handle requests from WASM that need the host environment to perform side effects.
2871
+ * Examples: signing challenges, providing public keys, generating random bytes.
2872
+ */
2873
+
2874
+ /**
2875
+ * Account — MetaMask handler accepts either a plain address string or an
2876
+ * object with an `address` field (for compatibility with various wallet
2877
+ * libraries).
2878
+ */
2879
+ type EthAccount = string | {
2880
+ address: string;
2881
+ };
2882
+ /**
2883
+ * Create an EthSign handler using MetaMask (window.ethereum)
2884
+ * @param account - MetaMask account (string address or object with address property)
2885
+ * @param logger - Optional logger instance. Defaults to a logger using the global log level (LogLevel.ERROR).
2886
+ * Pass a custom logger to override logging behavior for this handler.
2887
+ * @param privateKey - Optional private key for signing (if provided, MetaMask is not used)
2888
+ */
2889
+ declare function metamask_sign(account: EthAccount, logger?: Logger, privateKey?: string | undefined): GuestToHostHandler;
2890
+ /**
2891
+ * Get the current MetaMask address
2892
+ * @returns Ethereum address (lowercase, 0x prefixed)
2893
+ */
2894
+ declare function metamask_get_address(): Promise<string>;
2895
+ /**
2896
+ * Get the address for a given private key
2897
+ * @param privateKey - Ethereum private key (0x prefixed hex string)
2898
+ * @returns Ethereum address (lowercase, 0x prefixed)
2899
+ */
2900
+ declare function eth_get_address(privateKey: string): string;
2901
+ /**
2902
+ * Create an MlKemPublicKey handler that lazily fetches the root public key
2903
+ * from `${baseUrl}/status` on first invocation, verifies it against the
2904
+ * DKG attestation trust anchor (SP-003), and caches the encoded response
2905
+ * for subsequent calls.
2906
+ *
2907
+ * @param baseUrl - **Required**. The node URL whose `/status` endpoint should
2908
+ * serve the ML-KEM public key. Must be the same URL the
2909
+ * T3nClient is constructed with — otherwise the handshake
2910
+ * encrypts to one node and sends ciphertext to another.
2911
+ *
2912
+ * Was optional in 0.3.x, where omitting it caused the lazy
2913
+ * fetch to silently fall back to `NODE_URLS[currentEnv]` and
2914
+ * hit the wrong node. Three downstream consumers (demo.ts,
2915
+ * t3-apps dev wallet hooks, t3n-mcp session manager) all
2916
+ * hit this trap before we tightened the type.
2917
+ * @param trustAnchor - **Required**. Client-pinned expected peer IDs +
2918
+ * RTMR3 allowlist the DKG bundle is verified against, or
2919
+ * `{ unsafe_trust_server: true }` to skip verification.
2920
+ * The key is only cached/returned once verification passes.
2921
+ */
2922
+ declare function createMlKemPublicKeyHandler(baseUrl: string, trustAnchor: TrustAnchorOrUnsafe): GuestToHostHandler;
2923
+ /**
2924
+ * Create Random handler backed by crypto.getRandomValues
2925
+ * Note: The Rust Vec<u8> type serializes as an array of bytes, not a base64 string
2926
+ */
2927
+ declare function createRandomHandler(): GuestToHostHandler;
2928
+ /**
2929
+ * Create the default handler set required by the T3n handshake.
2930
+ *
2931
+ * @param baseUrl - **Required**. Forwarded to `createMlKemPublicKeyHandler`
2932
+ * so the lazy /status fetch hits the right node.
2933
+ * @param trustAnchor - **Required**. Forwarded to the ML-KEM handler so the
2934
+ * fetched key is verified against the DKG attestation
2935
+ * (SP-003) before the handshake trusts it.
2936
+ */
2937
+ declare function createDefaultHandlers(baseUrl: string, trustAnchor: TrustAnchorOrUnsafe): GuestToHostHandlers;
2938
+
2939
+ /**
2940
+ * Stateless `api_key` agent auth.
2941
+ *
2942
+ * `invoke` posts once to `POST /api/invoke` — an HTTPS-only
2943
+ * endpoint (see the HTTPS-guard note below) that authenticates an org agent
2944
+ * by an opaque API key (`X-T3N-Api-Key: t3n_key_<...>`) and executes a
2945
+ * `z:` contract as that agent in the SAME request. Unlike
2946
+ * {@link T3nClient.execute}, there is **no** ML-KEM handshake, **no**
2947
+ * `Session-Id`, and **no** session state: the node derives the acting agent
2948
+ * DID from the relayed key per-call (`resolve_stateless_credential`
2949
+ * driving the session contract's `api_key` action), then runs the same
2950
+ * execute pipeline `action.execute` runs after `check_authentication`
2951
+ * (`ActionService::execute_as_did`), and returns the contract's decoded
2952
+ * result as a plain `Json(result)` body — NOT a JSON-RPC envelope.
2953
+ *
2954
+ * Because the response is the bare decoded value (no `{jsonrpc,result,id}`
2955
+ * wrapper to unwrap), decoding reuses {@link parseContractResponse} — the
2956
+ * exact same JSON.parse + optional-schema path {@link T3nClient.executeAndDecode}
2957
+ * uses for the session `execute` RPC — so callers get identical typed /
2958
+ * schema-validated decoding on either path.
2959
+ *
2960
+ * This module intentionally does NOT import {@link T3nClient}, the WASM
2961
+ * component loader, or any handshake/session machinery — `invoke` is
2962
+ * a single fetch, nothing else.
2963
+ *
2964
+ * ### HTTPS guard (CodeRabbit T2)
2965
+ * The API key is a long-lived bearer credential relayed in a plain header,
2966
+ * so `invoke` refuses to send it over an insecure transport: `baseUrl`
2967
+ * must be `https:`, unless the host is a local-dev loopback
2968
+ * (`localhost` / `127.0.0.1` / `[::1]`), in which case plain `http:` is
2969
+ * allowed. The check runs before any network activity — an insecure
2970
+ * `baseUrl` never gets as far as a `fetch` call.
2971
+ *
2972
+ * ### Error hygiene (CodeRabbit T3/T4/T5)
2973
+ * Every error `invoke` throws is a fixed, generic
2974
+ * {@link InvokeError} message — the response body text, the
2975
+ * underlying network error's message, and the api key are never
2976
+ * interpolated into it. This is defense in depth against a server (or a
2977
+ * malicious intermediary) that echoes the key or other secrets back in an
2978
+ * error body: whatever comes back over the wire on a non-2xx response is
2979
+ * discarded, not surfaced. The timeout timer also stays armed until the
2980
+ * response body has been fully read (or has itself timed out) — see
2981
+ * {@link invoke}'s implementation — so a connection that delivers
2982
+ * headers and then stalls on the body still respects `timeoutMs`.
2983
+ */
2984
+
2985
+ /**
2986
+ * Wire body for `POST /api/invoke` — mirrors the server's
2987
+ * server-side `ExecuteActionRequest`, the same shape
2988
+ * `T3nClient`'s `execute*` wrappers build for the session `action.execute`
2989
+ * RPC. Field names are load-bearing: the server deserialises strictly into
2990
+ * `script_name` / `script_version` / `function_name` (see
2991
+ * `T3nClient.executeSystemContract`'s doc comment) — `contract` / `version`
2992
+ * / `function` produce a 400.
2993
+ */
2994
+ interface InvokeRequest {
2995
+ script_name: string;
2996
+ script_version: string;
2997
+ function_name: string;
2998
+ /** Delegated-call target member; omitted for a self (non-delegated) call. */
2999
+ pii_did?: string;
3000
+ input?: unknown;
3001
+ }
3002
+ /** Options for {@link invoke}. */
3003
+ interface InvokeOptions {
3004
+ /**
3005
+ * RPC base URL of the T3n node, e.g. `https://node.example.com`. Must be
3006
+ * `https:` unless the host is a local-dev loopback (`localhost` /
3007
+ * `127.0.0.1` / `[::1]`) — see the module doc comment's HTTPS-guard note.
3008
+ */
3009
+ baseUrl: string;
3010
+ /**
3011
+ * The agent's opaque API key (`t3n_key_<...>`), relayed verbatim in the
3012
+ * `X-T3N-Api-Key` header. Never logged and never interpolated into any
3013
+ * error this module throws — see the module doc comment and
3014
+ * {@link InvokeError}.
3015
+ */
3016
+ apiKey: string;
3017
+ /** The wire request to execute, built to the {@link InvokeRequest} shape. */
3018
+ request: InvokeRequest;
3019
+ /** Fetch timeout in ms. Defaults to 30s, matching {@link HttpTransport}. */
3020
+ timeoutMs?: number;
3021
+ }
3022
+ /**
3023
+ * Thrown when `POST /api/invoke` fails at the transport or HTTP
3024
+ * layer (network failure, timeout, non-2xx status). Contract-level errors
3025
+ * the node returns as a 2xx JSON error value are NOT wrapped here — they
3026
+ * flow through {@link parseContractResponse}'s normal return, same as the
3027
+ * session `execute` path.
3028
+ *
3029
+ * The message is always one of a small set of fixed, generic strings — it
3030
+ * NEVER contains the raw api key, the response body text, or the
3031
+ * underlying network error's message (CodeRabbit T4/T5): a server (or a
3032
+ * misbehaving intermediary) that echoes the key or other secrets back in
3033
+ * an error body must not be able to leak them through this error's
3034
+ * message.
3035
+ */
3036
+ declare class InvokeError extends T3nError {
3037
+ readonly status?: number | undefined;
3038
+ constructor(message: string, status?: number | undefined);
3039
+ }
3040
+ /**
3041
+ * Execute a `z:` contract as an org agent, authenticating with an opaque
3042
+ * API key — one request, no handshake, no session.
3043
+ *
3044
+ * @param opts - baseUrl, apiKey, and the wire request to execute
3045
+ * @param schema - optional validator applied to the decoded result (e.g. a
3046
+ * zod schema); anything exposing `.parse(value)` is accepted, same as
3047
+ * {@link T3nClient.executeAndDecode}
3048
+ * @returns the contract's decoded result, typed as `T`
3049
+ * @throws {InvokeError} if `baseUrl` is insecure, on a network
3050
+ * failure/timeout, or on a non-2xx response
3051
+ * @throws {ContractResponseError} if the node returns a 2xx with a body
3052
+ * that is not valid JSON
3053
+ */
3054
+ declare function invoke<T = unknown>(opts: InvokeOptions, schema?: ContractResponseSchema<T>): Promise<T>;
3055
+
3056
+ /**
3057
+ * Token fixed-point units (USDT-style 6 decimals).
3058
+ *
3059
+ * As of `tee:*` metering v2, every token amount on the wire —
3060
+ * {@link BalanceRow}'s `available`/`reserved`, {@link UsageEntry.amount},
3061
+ * and `total_supply` — is denominated in **base units**, where
3062
+ * `1 T3N token = `{@link BASE_UNITS_PER_TOKEN}` base units`. The node
3063
+ * meters the *actual* fractional cost of each operation (pro-rata by
3064
+ * bytes / byte-seconds / fuel) down to `1e-6` token, so amounts are
3065
+ * raw integers in base units, NOT whole tokens.
3066
+ *
3067
+ * The wire fields are left as raw base units (no silent rescaling — that
3068
+ * would lose precision for large balances and surprise callers doing
3069
+ * arithmetic). Use {@link formatTokens} to render a human "tokens"
3070
+ * string and {@link toBaseUnits} to convert a token figure back.
3071
+ *
3072
+ * ⚠️ Breaking vs. the pre-decimals SDK: a balance that used to read `5`
3073
+ * (whole tokens) now reads `5_000_000` (base units). Multiply existing
3074
+ * display code through {@link formatTokens}.
3075
+ */
3076
+ /** Decimal places in a T3N token (fixed; mirrors the node constant). */
3077
+ declare const TOKEN_DECIMALS = 6;
3078
+ /** Base units per whole T3N token — `10 ** TOKEN_DECIMALS`. */
3079
+ declare const BASE_UNITS_PER_TOKEN = 1000000;
3080
+ /**
3081
+ * Render a base-unit amount as a human-readable token string, e.g.
3082
+ * `25_920_000 → "25.92"`, `1_000_000 → "1"`, `4768 → "0.004768"`.
3083
+ *
3084
+ * Trailing-zero fraction digits are trimmed; an integer amount renders
3085
+ * with no decimal point. Accepts `number` or `bigint`; for balances
3086
+ * above `Number.MAX_SAFE_INTEGER` prefer passing a `bigint`.
3087
+ */
3088
+ declare function formatTokens(baseUnits: number | bigint): string;
3089
+ /**
3090
+ * Convert a whole-or-fractional token figure to base units (rounded to
3091
+ * the nearest base unit). E.g. `25.92 → 25_920_000`, `1 → 1_000_000`.
3092
+ */
3093
+ declare function toBaseUnits(tokens: number): number;
3094
+
3095
+ /**
3096
+ * Org-data wire types mirroring the org-data contract wire shapes.
3097
+ *
3098
+ * Plain TypeScript interfaces (no zod) — the SDK does not use a
3099
+ * validation library for domain types; see the existing `types/` files.
3100
+ *
3101
+ * Each response type below is paired with a shallow runtime predicate
3102
+ * (`isMutationResponse`, `isOrgPolicyMeta`, etc.) so the org-data client
3103
+ * can `assertShape` the decoded payload before returning to callers.
3104
+ * Predicates check the top-level structure only; nested elements
3105
+ * (e.g. each `UserGrant` inside `OrgContractGrants.grants`) are not
3106
+ * deeply validated — see `utils/shape.ts` for the rationale.
3107
+ *
3108
+ * Reference: the org-data wire contract.
3109
+ */
3110
+ /**
3111
+ * Capability grant stored under `ORG_CONTRACT_GRANTS_MAP`.
3112
+ *
3113
+ * Mirrors the org-data `UserGrant` wire shape.
3114
+ */
3115
+ interface UserGrant {
3116
+ /** The user this grant applies to (`did:t3n:<40-hex>`). */
3117
+ user_did: string;
3118
+ /** WIT function names the user may invoke (e.g. `"set-records"`). */
3119
+ functions: string[];
3120
+ /** Data scope paths the user may access (e.g. `"example/records"`). */
3121
+ scopes: string[];
3122
+ }
3123
+ /**
3124
+ * Policy record for an organisation's data tier.
3125
+ *
3126
+ * Mirrors the org-data policy-meta wire shape.
3127
+ */
3128
+ interface OrgPolicyMeta {
3129
+ /** DIDs (`did:t3n:<40-hex>`) of users authorised to manage policy and read data. */
3130
+ admins: string[];
3131
+ /** Maximum number of admins allowed for this org. */
3132
+ max_admins: number;
3133
+ /** Unix timestamp (secs) when the policy was first created. */
3134
+ created_at_secs: number;
3135
+ /** Unix timestamp (secs) of the most recent policy update. */
3136
+ updated_at_secs: number;
3137
+ /**
3138
+ * Per-org ceiling on delegation-credential validity (seconds).
3139
+ *
3140
+ * Absent when no org-level cap is set — the contract omits the field
3141
+ * (never serialises null) and the cluster-wide
3142
+ * `delegation.max_credential_validity_secs` governs instead. When set,
3143
+ * the effective cap is `min(max_credential_validity_secs, cluster_ceiling)`.
3225
3144
  */
3226
- private captureMintedSessionId;
3145
+ max_credential_validity_secs?: number;
3146
+ }
3147
+ /** Shallow runtime guard for {@link OrgPolicyMeta}. */
3148
+ declare function isOrgPolicyMeta(value: unknown): value is OrgPolicyMeta;
3149
+ /**
3150
+ * Effective org policy view returned by `org-policy-view`.
3151
+ *
3152
+ * Readable by any authenticated session (non-sensitive metadata).
3153
+ * Returns the **effective** credential validity cap:
3154
+ * `min(org.max_credential_validity_secs, cluster_ceiling)`, equal to the
3155
+ * cluster ceiling when the org has not set a per-org cap. The contract
3156
+ * always returns a value (or errors) — the field is never null.
3157
+ */
3158
+ interface OrgPolicyView {
3227
3159
  /**
3228
- * Get the finalized session blob (for `session.encrypt` calls).
3229
- * Populated by `tryFinalize` once the handshake state machine
3230
- * reaches its terminal phase.
3160
+ * Effective delegation-credential validity cap in seconds:
3161
+ * `min(org value, cluster ceiling)`, equal to the cluster ceiling when the
3162
+ * org has not set a per-org cap. Always present — mirrors the contract's
3163
+ * `PolicyViewResponse.effective_validity_secs` (org-data `org-policy-view`).
3231
3164
  */
3232
- private getSessionState;
3165
+ effective_validity_secs: number;
3233
3166
  }
3234
-
3167
+ /** Shallow runtime guard for {@link OrgPolicyView}. */
3168
+ declare function isOrgPolicyView(value: unknown): value is OrgPolicyView;
3235
3169
  /**
3236
- * Guest-to-Host Request Handlers
3170
+ * Caller-scoped admin status returned by `org-am-i-admin`.
3237
3171
  *
3238
- * These handle requests from WASM that need the host environment to perform side effects.
3239
- * Examples: signing challenges, providing public keys, generating random bytes.
3172
+ * Reports only whether the **calling** session's DID is in the org's admin
3173
+ * list — never the roster itself (contrast {@link OrgPolicyMeta}, returned by
3174
+ * the admin-gated `org-policy-get`). Readable by any authenticated session.
3175
+ * Mirrors the org-data `AmIAdminResponse` wire shape.
3240
3176
  */
3241
-
3177
+ interface OrgAdminStatus {
3178
+ /** Whether the calling session is an admin of the queried org. */
3179
+ is_admin: boolean;
3180
+ }
3181
+ /** Shallow runtime guard for {@link OrgAdminStatus}. */
3182
+ declare function isOrgAdminStatus(value: unknown): value is OrgAdminStatus;
3242
3183
  /**
3243
- * Account — MetaMask handler accepts either a plain address string or an
3244
- * object with an `address` field (for compatibility with various wallet
3245
- * libraries).
3184
+ * Standard response returned by all policy write and data mutation operations.
3185
+ *
3186
+ * Mirrors the org-data `MutationResponse` wire shape.
3246
3187
  */
3247
- type EthAccount = string | {
3248
- address: string;
3249
- };
3188
+ interface MutationResponse {
3189
+ /**
3190
+ * `"created"`, `"updated"`, `"deleted"`, or — for the agent-card mutations —
3191
+ * `"published"` / `"unpublished"`.
3192
+ */
3193
+ status: string;
3194
+ /** Hex-encoded entry ID; present on data write/delete operations. */
3195
+ entry_id?: string;
3196
+ /** Whether the target key existed before deletion; present on single-entry deletes. */
3197
+ deleted?: boolean;
3198
+ /** Number of entries removed; present on `org-data-delete-scope`. */
3199
+ deleted_entries?: number;
3200
+ tx_hash: string | null;
3201
+ }
3250
3202
  /**
3251
- * Create an EthSign handler using MetaMask (window.ethereum)
3252
- * @param account - MetaMask account (string address or object with address property)
3253
- * @param logger - Optional logger instance. Defaults to a logger using the global log level (LogLevel.ERROR).
3254
- * Pass a custom logger to override logging behavior for this handler.
3255
- * @param privateKey - Optional private key for signing (if provided, MetaMask is not used)
3203
+ * Shallow runtime guard for {@link MutationResponse}.
3204
+ *
3205
+ * Only the always-present fields are checked — `status` is mandatory on
3206
+ * every mutation; `tx_hash` is non-optional but nullable. The optional
3207
+ * fields (`entry_id`, `deleted`, `deleted_entries`) are not validated
3208
+ * because their presence depends on which mutation ran.
3256
3209
  */
3257
- declare function metamask_sign(account: EthAccount, logger?: Logger, privateKey?: string | undefined): GuestToHostHandler;
3210
+ declare function isMutationResponse(value: unknown): value is MutationResponse;
3258
3211
  /**
3259
- * Get the current MetaMask address
3260
- * @returns Ethereum address (lowercase, 0x prefixed)
3212
+ * Response type alias for org-writers-get.
3213
+ *
3214
+ * The wire body is `{ writers: string[] }` where each entry is
3215
+ * `did:t3n:<40-hex>`.
3261
3216
  */
3262
- declare function metamask_get_address(): Promise<string>;
3217
+ interface OrgWriters {
3218
+ writers: string[];
3219
+ }
3220
+ /** Shallow runtime guard for {@link OrgWriters}. */
3221
+ declare function isOrgWriters(value: unknown): value is OrgWriters;
3263
3222
  /**
3264
- * Get the address for a given private key
3265
- * @param privateKey - Ethereum private key (0x prefixed hex string)
3266
- * @returns Ethereum address (lowercase, 0x prefixed)
3223
+ * Response type alias for org-grants-get.
3224
+ *
3225
+ * The wire body echoes the `contract_id` alongside the grant list.
3267
3226
  */
3268
- declare function eth_get_address(privateKey: string): string;
3227
+ interface OrgContractGrants {
3228
+ contract_id: string;
3229
+ grants: UserGrant[];
3230
+ }
3269
3231
  /**
3270
- * Create an MlKemPublicKey handler that lazily fetches the root public key
3271
- * from `${baseUrl}/status` on first invocation, verifies it against the
3272
- * DKG attestation trust anchor (SP-003), and caches the encoded response
3273
- * for subsequent calls.
3274
- *
3275
- * @param baseUrl - **Required**. The node URL whose `/status` endpoint should
3276
- * serve the ML-KEM public key. Must be the same URL the
3277
- * T3nClient is constructed with — otherwise the handshake
3278
- * encrypts to one node and sends ciphertext to another.
3232
+ * Shallow runtime guard for {@link OrgContractGrants}.
3279
3233
  *
3280
- * Was optional in 0.3.x, where omitting it caused the lazy
3281
- * fetch to silently fall back to `NODE_URLS[currentEnv]` and
3282
- * hit the wrong node. Three downstream consumers (demo.ts,
3283
- * t3-apps dev wallet hooks, t3n-mcp session manager) all
3284
- * hit this trap before we tightened the type.
3285
- * @param trustAnchor - **Required**. Client-pinned expected peer IDs +
3286
- * RTMR3 allowlist the DKG bundle is verified against, or
3287
- * `{ unsafe_trust_server: true }` to skip verification.
3288
- * The key is only cached/returned once verification passes.
3234
+ * Validates the immediate envelope (`contract_id: string`, `grants:
3235
+ * array`) without recursing into each `UserGrant`. The Rust contract
3236
+ * is the source of truth for grant element shape; widening the predicate
3237
+ * here would create maintenance churn against benign field additions.
3289
3238
  */
3290
- declare function createMlKemPublicKeyHandler(baseUrl: string, trustAnchor: TrustAnchorOrUnsafe): GuestToHostHandler;
3239
+ declare function isOrgContractGrants(value: unknown): value is OrgContractGrants;
3291
3240
  /**
3292
- * Create Random handler backed by crypto.getRandomValues
3293
- * Note: The Rust Vec<u8> type serializes as an array of bytes, not a base64 string
3241
+ * One grant inside a role: a {@link UserGrant} body (without the
3242
+ * grantee, which is bound at assignment time) plus the target contract.
3243
+ * Mirrors the org-data `RoleGrant` wire shape.
3294
3244
  */
3295
- declare function createRandomHandler(): GuestToHostHandler;
3245
+ interface RoleGrant {
3246
+ /** Target contract (canonical name, e.g. `"tee:z-payroll/contracts"`). */
3247
+ contract_id: string;
3248
+ /** WIT function names this grant confers. */
3249
+ functions: string[];
3250
+ /** Data scope paths this grant confers (canonicalised lowercase). */
3251
+ scopes: string[];
3252
+ }
3296
3253
  /**
3297
- * Create the default handler set required by the T3n handshake.
3298
- *
3299
- * @param baseUrl - **Required**. Forwarded to `createMlKemPublicKeyHandler`
3300
- * so the lazy /status fetch hits the right node.
3301
- * @param trustAnchor - **Required**. Forwarded to the ML-KEM handler so the
3302
- * fetched key is verified against the DKG attestation
3303
- * (SP-003) before the handshake trusts it.
3254
+ * A role: a named bundle of grants and/or composed sub-roles.
3255
+ * Mirrors the org-data `RoleDefinition` wire shape.
3304
3256
  */
3305
- declare function createDefaultHandlers(baseUrl: string, trustAnchor: TrustAnchorOrUnsafe): GuestToHostHandlers;
3306
-
3257
+ interface RoleDefinition {
3258
+ /** Org-unique role identifier (slug; function-name grammar). */
3259
+ role_id: string;
3260
+ /** Human-facing label. */
3261
+ label: string;
3262
+ /** Composite: other role ids in the same org whose grants this role confers. */
3263
+ includes: string[];
3264
+ /** Grants this role confers directly. */
3265
+ grants: RoleGrant[];
3266
+ }
3307
3267
  /**
3308
- * Stateless `api_key` agent auth.
3309
- *
3310
- * `invoke` posts once to `POST /api/invoke` — an HTTPS-only
3311
- * endpoint (see the HTTPS-guard note below) that authenticates an org agent
3312
- * by an opaque API key (`X-T3N-Api-Key: t3n_key_<...>`) and executes a
3313
- * `z:` contract as that agent in the SAME request. Unlike
3314
- * {@link T3nClient.execute}, there is **no** ML-KEM handshake, **no**
3315
- * `Session-Id`, and **no** session state: the node derives the acting agent
3316
- * DID from the relayed key per-call (`resolve_stateless_credential`
3317
- * driving the session contract's `api_key` action), then runs the same
3318
- * execute pipeline `action.execute` runs after `check_authentication`
3319
- * (`ActionService::execute_as_did`), and returns the contract's decoded
3320
- * result as a plain `Json(result)` body — NOT a JSON-RPC envelope.
3321
- *
3322
- * Because the response is the bare decoded value (no `{jsonrpc,result,id}`
3323
- * wrapper to unwrap), decoding reuses {@link parseContractResponse} — the
3324
- * exact same JSON.parse + optional-schema path {@link T3nClient.executeAndDecode}
3325
- * uses for the session `execute` RPC — so callers get identical typed /
3326
- * schema-validated decoding on either path.
3327
- *
3328
- * This module intentionally does NOT import {@link T3nClient}, the WASM
3329
- * component loader, or any handshake/session machinery — `invoke` is
3330
- * a single fetch, nothing else.
3331
- *
3332
- * ### HTTPS guard (CodeRabbit T2)
3333
- * The API key is a long-lived bearer credential relayed in a plain header,
3334
- * so `invoke` refuses to send it over an insecure transport: `baseUrl`
3335
- * must be `https:`, unless the host is a local-dev loopback
3336
- * (`localhost` / `127.0.0.1` / `[::1]`), in which case plain `http:` is
3337
- * allowed. The check runs before any network activity — an insecure
3338
- * `baseUrl` never gets as far as a `fetch` call.
3339
- *
3340
- * ### Error hygiene (CodeRabbit T3/T4/T5)
3341
- * Every error `invoke` throws is a fixed, generic
3342
- * {@link InvokeError} message — the response body text, the
3343
- * underlying network error's message, and the api key are never
3344
- * interpolated into it. This is defense in depth against a server (or a
3345
- * malicious intermediary) that echoes the key or other secrets back in an
3346
- * error body: whatever comes back over the wire on a non-2xx response is
3347
- * discarded, not surfaced. The timeout timer also stays armed until the
3348
- * response body has been fully read (or has itself timed out) — see
3349
- * {@link invoke}'s implementation — so a connection that delivers
3350
- * headers and then stalls on the body still respects `timeoutMs`.
3268
+ * The roles assigned to one grantee within one org.
3269
+ * Mirrors the org-data `RoleAssignments` wire shape.
3351
3270
  */
3352
-
3271
+ interface RoleAssignments {
3272
+ /** Assigned role ids. */
3273
+ roles: string[];
3274
+ }
3275
+ /** Response for `org-role-get`; `role` is `null` when the id is unknown. */
3276
+ interface RoleGetResponse {
3277
+ role: RoleDefinition | null;
3278
+ }
3279
+ /** Shallow runtime guard for {@link RoleGetResponse}. */
3280
+ declare function isRoleGetResponse(value: unknown): value is RoleGetResponse;
3281
+ /** Response for `org-role-assignments-get`. */
3282
+ interface RoleAssignmentsResponse {
3283
+ /** Echoed back so callers don't need to track which request this answers. */
3284
+ grantee_did: string;
3285
+ /** The grantee's assigned role ids (empty when none). */
3286
+ roles: string[];
3287
+ }
3288
+ /** Shallow runtime guard for {@link RoleAssignmentsResponse}. */
3289
+ declare function isRoleAssignmentsResponse(value: unknown): value is RoleAssignmentsResponse;
3290
+ /**
3291
+ * Input for `listAgents` — the org plus optional pagination. Omit both `cursor`
3292
+ * and `limit` for the first page at the default limit; pass a previous
3293
+ * response's `next_cursor` back as `cursor` to fetch the following page.
3294
+ */
3295
+ interface ListAgentsInput {
3296
+ orgDid: string;
3297
+ /** Opaque cursor from a previous response's `next_cursor`. */
3298
+ cursor?: string;
3299
+ /** Maximum agents to return in this page. */
3300
+ limit?: number;
3301
+ }
3353
3302
  /**
3354
- * Wire body for `POST /api/invoke` — mirrors the server's
3355
- * server-side `ExecuteActionRequest`, the same shape
3356
- * `T3nClient`'s `execute*` wrappers build for the session `action.execute`
3357
- * RPC. Field names are load-bearing: the server deserialises strictly into
3358
- * `contract_id` / `contract_version` / `function_name` (see
3359
- * `T3nClient.executeSystemContract`'s doc comment) — `contract` / `version`
3360
- * / `function` produce a 400.
3303
+ * One org-owned agent in a {@link ListAgentsResponse}: the agent's DID, its
3304
+ * display name, and the number of distinct contracts it can access via a direct
3305
+ * grant. Mirrors the org-data `AgentSummary` wire shape. The name comes from the
3306
+ * agent's private card (falling back to the DID), so the FE no longer needs to
3307
+ * fetch each `public:agent_cards` entry to render the roster.
3361
3308
  */
3362
- interface InvokeRequest {
3363
- contract_id: string;
3364
- contract_version: string;
3365
- function_name: string;
3366
- /** Delegated-call target member; omitted for a self (non-delegated) call. */
3367
- pii_did?: string;
3368
- input?: unknown;
3309
+ interface AgentSummary {
3310
+ /** The agent's DID (`did:t3n:<40-hex>`). */
3311
+ did: string;
3312
+ /** The agent's display name, from its private card (DID when unavailable). */
3313
+ name: string;
3314
+ /** Count of distinct contracts the agent holds a direct grant on. */
3315
+ contract_count: number;
3369
3316
  }
3370
- /** Options for {@link invoke}. */
3371
- interface InvokeOptions {
3372
- /**
3373
- * RPC base URL of the T3n node, e.g. `https://node.example.com`. Must be
3374
- * `https:` unless the host is a local-dev loopback (`localhost` /
3375
- * `127.0.0.1` / `[::1]`) — see the module doc comment's HTTPS-guard note.
3376
- */
3377
- baseUrl: string;
3378
- /**
3379
- * The agent's opaque API key (`t3n_key_<...>`), relayed verbatim in the
3380
- * `X-T3N-Api-Key` header. Never logged and never interpolated into any
3381
- * error this module throws — see the module doc comment and
3382
- * {@link InvokeError}.
3383
- */
3384
- apiKey: string;
3385
- /** The wire request to execute, built to the {@link InvokeRequest} shape. */
3386
- request: InvokeRequest;
3387
- /** Fetch timeout in ms. Defaults to 30s, matching {@link HttpTransport}. */
3388
- timeoutMs?: number;
3317
+ /** Response for `org-data-list-agents`. */
3318
+ interface ListAgentsResponse {
3319
+ /** One PAGE of the org's org-owned agents, sorted by DID. */
3320
+ agents: AgentSummary[];
3321
+ /** Opaque cursor for the next page; absent on the last page. */
3322
+ next_cursor?: string;
3389
3323
  }
3324
+ /** A human member's org role. The closed wire domain of {@link HumanMember}. */
3325
+ type MemberRole = "admin" | "member";
3390
3326
  /**
3391
- * Thrown when `POST /api/invoke` fails at the transport or HTTP
3392
- * layer (network failure, timeout, non-2xx status). Contract-level errors
3393
- * the node returns as a 2xx JSON error value are NOT wrapped here — they
3394
- * flow through {@link parseContractResponse}'s normal return, same as the
3395
- * session `execute` path.
3396
- *
3397
- * The message is always one of a small set of fixed, generic strings — it
3398
- * NEVER contains the raw api key, the response body text, or the
3399
- * underlying network error's message (CodeRabbit T4/T5): a server (or a
3400
- * misbehaving intermediary) that echoes the key or other secrets back in
3401
- * an error body must not be able to leak them through this error's
3402
- * message.
3327
+ * Input for `listHumanMembers` — the org plus optional pagination. Omit both
3328
+ * `cursor` and `limit` for the first page at the default limit; pass a previous
3329
+ * response's `next_cursor` back as `cursor` to fetch the following page.
3403
3330
  */
3404
- declare class InvokeError extends T3nError {
3405
- readonly status?: number | undefined;
3406
- constructor(message: string, status?: number | undefined);
3331
+ interface ListHumanMembersInput {
3332
+ orgDid: string;
3333
+ /** Opaque cursor from a previous response's `next_cursor`. */
3334
+ cursor?: string;
3335
+ /** Maximum members to return in this page. */
3336
+ limit?: number;
3407
3337
  }
3408
3338
  /**
3409
- * Execute a `z:` contract as an org agent, authenticating with an opaque
3410
- * API key — one request, no handshake, no session.
3411
- *
3412
- * @param opts - baseUrl, apiKey, and the wire request to execute
3413
- * @param schema - optional validator applied to the decoded result (e.g. a
3414
- * zod schema); anything exposing `.parse(value)` is accepted, same as
3415
- * {@link T3nClient.executeAndDecode}
3416
- * @returns the contract's decoded result, typed as `T`
3417
- * @throws {InvokeError} if `baseUrl` is insecure, on a network
3418
- * failure/timeout, or on a non-2xx response
3419
- * @throws {ContractResponseError} if the node returns a 2xx with a body
3420
- * that is not valid JSON
3339
+ * One direct human member: DID plus org role. No profile PII (name/email are
3340
+ * out of scope and owned by `tee:user`). Mirrors the org-data `HumanMember`
3341
+ * wire shape.
3421
3342
  */
3422
- declare function invoke<T = unknown>(opts: InvokeOptions, schema?: ContractResponseSchema<T>): Promise<T>;
3423
-
3343
+ interface HumanMember {
3344
+ /** The member's DID (`did:t3n:<40-hex>`). */
3345
+ did: string;
3346
+ /** The member's org role. */
3347
+ role: MemberRole;
3348
+ }
3349
+ /** Response for `org-data-list-human-members`. */
3350
+ interface ListHumanMembersResponse {
3351
+ /** One PAGE of the org's direct human members, sorted by DID. */
3352
+ members: HumanMember[];
3353
+ /** Opaque cursor for the next page; absent on the last page. */
3354
+ next_cursor?: string;
3355
+ }
3356
+ /** Shallow runtime guard for {@link ListHumanMembersResponse}. */
3357
+ declare function isListHumanMembersResponse(value: unknown): value is ListHumanMembersResponse;
3358
+ /** Shallow runtime guard for {@link ListAgentsResponse}. */
3359
+ declare function isListAgentsResponse(value: unknown): value is ListAgentsResponse;
3360
+ /** Response for `org-data-list`. */
3361
+ interface DataListResponse {
3362
+ /** Hex-encoded entry IDs for this page. */
3363
+ entry_ids: string[];
3364
+ /** Offset to pass for the next page. `null` when this is the last page. */
3365
+ next_offset: number | null;
3366
+ /** Total number of entries in the scope (across all pages). */
3367
+ total: number;
3368
+ }
3369
+ /** Shallow runtime guard for {@link DataListResponse}. */
3370
+ declare function isDataListResponse(value: unknown): value is DataListResponse;
3371
+ /** Secret shape discriminator (mirrors the contract `SecretKind`). */
3372
+ type SecretKind = "single_value" | "json";
3373
+ /** Metadata common to every {@link SecretView} entry. */
3374
+ interface SecretViewBase {
3375
+ /** Secret name (the `(org, name)` key tail). */
3376
+ name: string;
3377
+ /** Monotonic version, bumped on each value rotation and ACL edit. */
3378
+ version: number;
3379
+ /** Unix seconds of the most recent write. */
3380
+ updated_at_secs: number;
3381
+ }
3424
3382
  /**
3425
- * Token fixed-point units (USDT-style 6 decimals).
3426
- *
3427
- * As of `tee:*` metering v2, every token amount on the wire —
3428
- * {@link BalanceRow}'s `available`/`reserved`, {@link UsageEntry.amount},
3429
- * and `total_supply` — is denominated in **base units**, where
3430
- * `1 T3N token = `{@link BASE_UNITS_PER_TOKEN}` base units`. The node
3431
- * meters the *actual* fractional cost of each operation (pro-rata by
3432
- * bytes / byte-seconds / fuel) down to `1e-6` token, so amounts are
3433
- * raw integers in base units, NOT whole tokens.
3434
- *
3435
- * The wire fields are left as raw base units (no silent rescaling — that
3436
- * would lose precision for large balances and surprise callers doing
3437
- * arithmetic). Use {@link formatTokens} to render a human "tokens"
3438
- * string and {@link toBaseUnits} to convert a token figure back.
3439
- *
3440
- * ⚠️ Breaking vs. the pre-decimals SDK: a balance that used to read `5`
3441
- * (whole tokens) now reads `5_000_000` (base units). Multiply existing
3442
- * display code through {@link formatTokens}.
3383
+ * The redacted per-secret summary `org-secret-list` returns — a discriminated
3384
+ * union on `kind`. The value is NEVER present: a single-value exposes only its
3385
+ * last four characters and a json secret only its sorted top-level field names.
3443
3386
  */
3444
- /** Decimal places in a T3N token (fixed; mirrors the node constant). */
3445
- declare const TOKEN_DECIMALS = 6;
3446
- /** Base units per whole T3N token — `10 ** TOKEN_DECIMALS`. */
3447
- declare const BASE_UNITS_PER_TOKEN = 1000000;
3387
+ type SecretView = (SecretViewBase & {
3388
+ kind: "single_value";
3389
+ /** Last four characters of the value (whole value when ≤ 4 chars). */
3390
+ last4: string;
3391
+ }) | (SecretViewBase & {
3392
+ kind: "json";
3393
+ /** Sorted top-level object field names (keys only, no values). */
3394
+ field_names: string[];
3395
+ });
3396
+ /** Shallow runtime guard for {@link SecretView}. */
3397
+ declare function isSecretView(value: unknown): value is SecretView;
3448
3398
  /**
3449
- * Render a base-unit amount as a human-readable token string, e.g.
3450
- * `25_920_000 → "25.92"`, `1_000_000 → "1"`, `4768 → "0.004768"`.
3451
- *
3452
- * Trailing-zero fraction digits are trimmed; an integer amount renders
3453
- * with no decimal point. Accepts `number` or `bigint`; for balances
3454
- * above `Number.MAX_SAFE_INTEGER` prefer passing a `bigint`.
3399
+ * Full secret record returned by `org-secret-get` — the value IS included
3400
+ * (the deliberate read-back path the READ axis exists for), along with all
3401
+ * three ACLs.
3455
3402
  */
3456
- declare function formatTokens(baseUnits: number | bigint): string;
3403
+ interface SecretRecord {
3404
+ name: string;
3405
+ kind: SecretKind;
3406
+ /** The value as text: the scalar for a single-value, canonical JSON object for a json secret. */
3407
+ value: string;
3408
+ version: number;
3409
+ /** READ axis — DIDs allowed to read the value back. */
3410
+ reader_dids: string[];
3411
+ /** READ axis — role ids allowed to read the value back. */
3412
+ reader_roles: string[];
3413
+ /** MANAGE axis — DIDs allowed to rotate the value. */
3414
+ manager_dids: string[];
3415
+ /** MANAGE axis — role ids allowed to rotate the value. */
3416
+ manager_roles: string[];
3417
+ /** USE axis — canonical contract ids allowed to have the value injected. */
3418
+ contract_allowlist: string[];
3419
+ created_at_secs: number;
3420
+ updated_at_secs: number;
3421
+ /** DID of the caller who last wrote the record. */
3422
+ updated_by: string;
3423
+ }
3424
+ /** Shallow runtime guard for {@link SecretRecord}. */
3425
+ declare function isSecretRecord(value: unknown): value is SecretRecord;
3426
+ /** Response for `org-secret-list`: redacted per-kind views, no values. */
3427
+ interface SecretListResponse {
3428
+ secrets: SecretView[];
3429
+ }
3430
+ /** Shallow runtime guard for {@link SecretListResponse}. */
3431
+ declare function isSecretListResponse(value: unknown): value is SecretListResponse;
3432
+ /** Response for `org-data-get`. */
3433
+ interface DataGetResponse {
3434
+ entry_id: string;
3435
+ /** Hex-encoded raw payload bytes. */
3436
+ payload_hex: string;
3437
+ }
3438
+ /** Shallow runtime guard for {@link DataGetResponse}. */
3439
+ declare function isDataGetResponse(value: unknown): value is DataGetResponse;
3457
3440
  /**
3458
- * Convert a whole-or-fractional token figure to base units (rounded to
3459
- * the nearest base unit). E.g. `25.92 → 25_920_000`, `1 → 1_000_000`.
3441
+ * Return shape of `agentCardGet` — composed client-side from the generic
3442
+ * `org-data-get` read of the card's entry (there is no card-specific read
3443
+ * operation on the contract). To check whether a public copy exists, probe
3444
+ * the anonymous `GET /api/agent-card/{did}` endpoint.
3460
3445
  */
3461
- declare function toBaseUnits(tokens: number): number;
3446
+ interface AgentCardResponse {
3447
+ /** The agent whose card this is (`did:t3n:<40-hex>`). */
3448
+ agent_did: string;
3449
+ /** The stored card JSON body, verbatim. */
3450
+ card: string;
3451
+ }
3452
+ /** Shallow runtime guard for {@link AgentCardResponse}. */
3453
+ declare function isAgentCardResponse(value: unknown): value is AgentCardResponse;
3454
+ /**
3455
+ * Legacy direct-route org-data envelope shape retained for compatibility.
3456
+ *
3457
+ * This mirrors the removed `/api/user-contract/execute` body format from
3458
+ * the transitional transport. New callers should use `OrgDataClient`,
3459
+ * which now dispatches through authenticated `/api/rpc` +
3460
+ * `action.execute` instead.
3461
+ */
3462
+ interface OrgDataActionWire {
3463
+ nonce: string;
3464
+ user_did: string;
3465
+ authenticator_id: string;
3466
+ contract_id: string;
3467
+ function: string;
3468
+ args_hash: string;
3469
+ expires_at_secs: number;
3470
+ signature: string;
3471
+ }
3462
3472
 
3463
3473
  /**
3464
3474
  * OrgDataClient — typed wrapper over the existing authenticated
@@ -3531,17 +3541,10 @@ interface SetWritersInput {
3531
3541
  scope: string;
3532
3542
  writers: string[];
3533
3543
  }
3534
- /**
3535
- * A grant to set via {@link OrgDataClient.setGrants}. The per-grant
3536
- * `contract_id` is injected by the SDK from the request `contractId` (the
3537
- * contract sets it server-side regardless), so callers omit it — a read-back
3538
- * {@link BoundGrant}, which carries `contract_id`, is still assignable.
3539
- */
3540
- type SetGrantInput = Omit<BoundGrant, "contract_id">;
3541
3544
  interface SetGrantsInput {
3542
3545
  orgDid: string;
3543
3546
  contractId: string;
3544
- grants: SetGrantInput[];
3547
+ grants: UserGrant[];
3545
3548
  }
3546
3549
  interface DeleteGrantsInput {
3547
3550
  orgDid: string;
@@ -3803,7 +3806,7 @@ declare class OrgDataClient {
3803
3806
  /** Delete a secret entirely (org-admin only). */
3804
3807
  secretDelete(input: SecretNameInput): Promise<MutationResponse>;
3805
3808
  /**
3806
- * Full replacement of the org's grant list for a contract.
3809
+ * Full replacement of the user-grant list for a contract.
3807
3810
  *
3808
3811
  * Passing an empty list removes the entry.
3809
3812
  */
@@ -3882,7 +3885,7 @@ declare class OrgDataClient {
3882
3885
  purgeOrg(input: PurgeOrgInput): Promise<MutationResponse>;
3883
3886
  /**
3884
3887
  * Detach-cascade grant sweep: drop `memberDid` from every
3885
- * one of the org's per-contract `BoundGrant` lists. Authorised for an
3888
+ * one of the org's per-contract `UserGrant` lists. Authorised for an
3886
3889
  * org-admin of the subject, or the member removing their own grants.
3887
3890
  * `deleted_entries` reports how many contract grant lists were rewritten.
3888
3891
  */
@@ -4080,7 +4083,7 @@ declare function createOrgDataClientFromSession(t3n: T3nClient, baseUrl: string)
4080
4083
  *
4081
4084
  * Envelope-free authorisation removed the per-call delegation
4082
4085
  * credential and envelope entirely: authority is now the standing on-chain
4083
- * `agent_auth` ∩ `org_grant` intersection the host re-reads every call, and
4086
+ * `agent_auth` ∩ `UserGrant` intersection the host re-reads every call, and
4084
4087
  * every payroll call emits the plain Direct wire variant (`{ request }`).
4085
4088
  * What remains here is the request body shape, its canonical defaults, and
4086
4089
  * the base64url / DID helpers callers still need.
@@ -4299,7 +4302,7 @@ declare function stringToBytes(str: string): Uint8Array;
4299
4302
  */
4300
4303
  declare function bytesToString(bytes: Uint8Array): string;
4301
4304
 
4302
- declare function getContractVersion(rpcUrl: string, contractId: string): Promise<string>;
4305
+ declare function getScriptVersion(rpcUrl: string, scriptName: string): Promise<string>;
4303
4306
 
4304
4307
  /**
4305
4308
  * Secret redaction utilities for T3n SDK
@@ -4341,7 +4344,7 @@ declare function redactSecretsFromJson(jsonString: string): string;
4341
4344
  *
4342
4345
  * Predicates are intentionally shallow — they validate the immediate
4343
4346
  * top-level structure (object kind, presence/type of leading fields)
4344
- * but do not deeply validate nested elements (e.g. each `BoundGrant`
4347
+ * but do not deeply validate nested elements (e.g. each `UserGrant`
4345
4348
  * inside `OrgContractGrants.grants`). Deep validation would be brittle
4346
4349
  * against benign contract additions; shallow guards catch the failure
4347
4350
  * modes that actually surface as runtime crashes (null/string/missing
@@ -4622,7 +4625,7 @@ interface TenantBaseClient {
4622
4625
  }
4623
4626
  interface TenantClientConfig {
4624
4627
  environment?: TenantSdkEnvironment;
4625
- /** Node URL for `getContractVersion` during business contract execution. Falls back to `baseUrl`. */
4628
+ /** Node URL for `getScriptVersion` during business contract execution. Falls back to `baseUrl`. */
4626
4629
  endpoint?: string;
4627
4630
  /**
4628
4631
  * Authenticated base client the TenantClient dispatches RPCs through.
@@ -4639,7 +4642,7 @@ interface TenantClientConfig {
4639
4642
  t3n?: TenantBaseClient;
4640
4643
  baseUrl?: string;
4641
4644
  tenantDid?: string;
4642
- tenantContractId?: string;
4645
+ tenantScriptName?: string;
4643
4646
  }
4644
4647
  type TenantStatus = "pending" | "active" | "suspended";
4645
4648
  interface TenantMeResponse {
@@ -5089,5 +5092,5 @@ declare function tenantDidHex(tenantDid: string): string;
5089
5092
  declare function validateTail(tail: string): string;
5090
5093
  declare function canonicalTenantName(tenantDid: string, tail: string): string;
5091
5094
 
5092
- export { AGENT_CARDS_SCOPE, AuthMethod, AuthenticationError, BASE_UNITS_PER_TOKEN, ContractResponseError, DEFAULT_ENVIRONMENT, DEFAULT_INDIVIDUAL_THRESHOLD_CENTS, DEFAULT_KYC_POLL_CADENCE, HandshakeError, HttpTransport, InvokeError, KycStatusTimeoutError, LogLevel, MockTransport, NODE_URLS, OrgDataClient, OtpRateLimitedError, RpcError, SessionExpiredError, SessionOrgDataClient, SessionStateError, SessionStatus, SessionUsageReportClient, T3nClient, T3nError, TERMINAL_KYC_STATUSES, TOKEN_DECIMALS, TenantClient, TenantContractsNamespace, TenantMapsNamespace, TenantNamespace, TenantSdkValidationError, TenantTokenNamespace, UnsupportedTenantSdkOperationError, UserUpsertError, WasmError, WireEncodingError, Z_PAYROLL_AUDIT_READ_FUNCTIONS, Z_PAYROLL_RUN_FUNCTIONS, _b64uEncode, assertShape, b64uDecodeStrict, b64uEncodeBytes, buildSecretWriteArgs, bytesToString, canonicalTenantName, clearKeyCache, clearManifestVersionFloor, compactDidFromBytes, createDefaultHandlers, createEmailOtpAuthInput, createEthAuthInput, createLogger, createMlKemPublicKeyHandler, createOidcAuthInput, createOrgDataClientFromSession, createRandomHandler, createUsageReportClientFromSession, createWorkloadAuthInput, decodeWasmErrorMessage, deriveAgentCardEntryId, eth_get_address, extractWasmError, fetchDkgAttestation, fetchMlKemPublicKey, fetchTrustedManifest, formatTokens, generateRandomString, generateUUID, getContractVersion, getEnvironment, getEnvironmentName, getGlobalLogLevel, getLogger, getNodeUrl, invoke, isAgentCardResponse, isDataGetResponse, isDataListResponse, isListAgentsResponse, isListHumanMembersResponse, isMutationResponse, isObject, isOrgAdminStatus, isOrgContractGrants, isOrgPolicyMeta, isOrgPolicyView, isOrgUsageReport, isOrgWriters, isRoleAssignmentsResponse, isRoleGetResponse, isSecretListResponse, isSecretRecord, isSecretView, isUnsafeTrustServer, loadConfig, loadWasmComponent, manifestToTrustAnchor, maskKeyMaterial, mergeDiscoverDids, mergeGrants, metamask_get_address, metamask_sign, parseAgentAuthDoc, parseContractResponse, redactSecrets, redactSecretsFromJson, requestToWire, setEnvironment, setGlobalLogLevel, setNodeUrl, stringToBytes, tenantDidHex, toBaseUnits, validateConfig, validateTail, verifyDkgAttestation, verifyManifestSignature, verifyTdxQuote };
5093
- export type { ActivityCallerType, ActivityEntry, ActivityOutcome, ActivityReport, AdmitForOrgOptions, AgentAuthDoc, AgentCardRefInput, AgentCardResponse, AgentCardSetInput, AgentSummary, AssignRolesInput, AuthInput, BalanceRow, BoundGrant, ChargeReason, ClientAuth, ClientHandshake, ConfigValidationResult, ContractDescriptorFacets, ContractExecuteInput, ContractKind, ContractLifecycleStatus, ContractListDetailedOptions, ContractListDetailedPage, ContractPublishInput, ContractRegisterResult, ContractResponseSchema, ContractSetDescriptorInput, CreatePolicyInput, DataGetInput, DataGetResponse, DataListInput, DataListResponse, DelegationGrantKind, DelegationGrantRef, DeleteDataInput, DeleteGrantsInput, DeleteScopeInput, DetailedContract, Did, Direction, DkgAttestation, DkgVerifyResult, EmailOtpAuthInput, EmailOtpCredentials, Environment, EthAuthInput, ExecuteBusinessContractOptions, ExecuteOrgDataActionOptions, FetchTrustedManifestOptions, GetActivityLogOptions, GetUsageOptions, GrantCheckParams, GrantCheckResult, GranteeInput, GrantsGetInput, GrantsMergeResult, GuestToHostHandler, GuestToHostHandlers, HandshakeResult, HumanMember, InvokeOptions, InvokeRequest, JsonRpcRequest, JsonRpcResponse, KycPollCadence, KycPollOptions, KycStatus, KycStatusKind, ListAgentsInput, ListAgentsResponse, ListContractsParams, ListContractsResult, ListContractsScope, ListHumanMembersInput, ListHumanMembersResponse, ListedContract, Logger, MapCreateInput, MapLifecycleStatus, MapResponse, MapUpdateInput, MapVisibility, MemberRole, MutationResponse, OidcAuthInput, OidcCredentials, OrgAdminStatus, OrgContractGrants, OrgDataActionWire, OrgDataClientOptions, OrgPolicyMeta, OrgPolicyView, OrgUsageReport, OrgUsageReportInput, OrgWriters, OtpChannel, OtpMergeSuggestion, OtpRequestInput, OtpRequestResult, OtpVerifyInput, OtpVerifyResult, PayrollRunRequest, PeerQuoteResult, PolicyGetInput, PurgeOrgInput, QuoteVerifyResult, ReaderSet, RemoveMemberGrantsInput, RoleAssignments, RoleAssignmentsResponse, RoleDefinition, RoleGetResponse, RoleGrant, RoleIdInput, SdkConfig, SecretKind, SecretListInput, SecretListResponse, SecretNameInput, SecretRecord, SecretSetValueInput, SecretView, SecretWriteInput, SessionCrypto, SessionId, SetGrantsInput, SetRoleInput, SetWritersInput, SignedTrustManifest, StringEncoding, SubmitUserInputArgs, SubmitUserInputResult, T3nClientConfig, TenantAdmitProjection, TenantAdmitStatus, TenantBaseClient, TenantClientConfig, TenantContractExecuteInput, TenantContractPublishInput, TenantContractSetDescriptorInput, TenantExecutionSession, TenantMapCreateInput, TenantMapUpdatePatch, TenantMeResponse, TenantSdkEnvironment, TenantSelfAdmitResult, TenantStatus, TenantTargetOptions, TokenTxKind, Transport, TrustAnchor, TrustAnchorOrUnsafe, TrustManifestPayload, UnassignRolesInput, UnsafeTrustServer, UpdateMetaInput, UsageEntry, UsagePage, UsageReportSignature, UserInputProfile, UserUpsertErrorKind, Validity, WasmComponent, WasmNextResult, WireBlock, WorkloadAuthInput, WriteDataInput, WriterSet, WritersGetInput };
5095
+ export { AGENT_CARDS_SCOPE, AuthMethod, AuthenticationError, BASE_UNITS_PER_TOKEN, ContractResponseError, DEFAULT_ENVIRONMENT, DEFAULT_INDIVIDUAL_THRESHOLD_CENTS, DEFAULT_KYC_POLL_CADENCE, HandshakeError, HttpTransport, InvokeError, KycStatusTimeoutError, LogLevel, MockTransport, NODE_URLS, OrgDataClient, OtpRateLimitedError, RpcError, SessionExpiredError, SessionOrgDataClient, SessionStateError, SessionStatus, SessionUsageReportClient, T3nClient, T3nError, TERMINAL_KYC_STATUSES, TOKEN_DECIMALS, TenantClient, TenantContractsNamespace, TenantMapsNamespace, TenantNamespace, TenantSdkValidationError, TenantTokenNamespace, UnsupportedTenantSdkOperationError, UserUpsertError, WasmError, WireEncodingError, Z_PAYROLL_AUDIT_READ_FUNCTIONS, Z_PAYROLL_RUN_FUNCTIONS, _b64uEncode, assertShape, b64uDecodeStrict, b64uEncodeBytes, buildSecretWriteArgs, bytesToString, canonicalTenantName, clearKeyCache, clearManifestVersionFloor, compactDidFromBytes, createDefaultHandlers, createEmailOtpAuthInput, createEthAuthInput, createLogger, createMlKemPublicKeyHandler, createOidcAuthInput, createOrgDataClientFromSession, createRandomHandler, createUsageReportClientFromSession, createWorkloadAuthInput, decodeWasmErrorMessage, deriveAgentCardEntryId, eth_get_address, extractWasmError, fetchDkgAttestation, fetchMlKemPublicKey, fetchTrustedManifest, formatTokens, generateRandomString, generateUUID, getEnvironment, getEnvironmentName, getGlobalLogLevel, getLogger, getNodeUrl, getScriptVersion, invoke, isAgentCardResponse, isDataGetResponse, isDataListResponse, isListAgentsResponse, isListHumanMembersResponse, isMutationResponse, isObject, isOrgAdminStatus, isOrgContractGrants, isOrgPolicyMeta, isOrgPolicyView, isOrgUsageReport, isOrgWriters, isRoleAssignmentsResponse, isRoleGetResponse, isSecretListResponse, isSecretRecord, isSecretView, isUnsafeTrustServer, loadConfig, loadWasmComponent, manifestToTrustAnchor, maskKeyMaterial, mergeAgentAuthEntries, mergeDiscoverDids, metamask_get_address, metamask_sign, parseAgentAuthGet, parseAgentAuthPolicy, parseContractResponse, redactSecrets, redactSecretsFromJson, requestToWire, setEnvironment, setGlobalLogLevel, setNodeUrl, stringToBytes, tenantDidHex, toAgentAuthUpdateWire, toBaseUnits, validateConfig, validateTail, verifyDkgAttestation, verifyManifestSignature, verifyTdxQuote };
5096
+ export type { ActivityCallerType, ActivityEntry, ActivityOutcome, ActivityReport, AdmitForOrgOptions, AgentAuthEntry, AgentAuthMergeResult, AgentAuthPolicy, AgentAuthScriptGrant, AgentAuthUpdateInput, AgentCardRefInput, AgentCardResponse, AgentCardSetInput, AgentSummary, AssignRolesInput, AuthInput, BalanceRow, ChargeReason, ClientAuth, ClientHandshake, ConfigValidationResult, ContractDescriptorFacets, ContractExecuteInput, ContractKind, ContractLifecycleStatus, ContractListDetailedOptions, ContractListDetailedPage, ContractPublishInput, ContractRegisterResult, ContractResponseSchema, ContractSetDescriptorInput, CreatePolicyInput, DataGetInput, DataGetResponse, DataListInput, DataListResponse, DelegationGrantKind, DelegationGrantRef, DeleteDataInput, DeleteGrantsInput, DeleteScopeInput, DetailedContract, Did, Direction, DkgAttestation, DkgVerifyResult, EmailOtpAuthInput, EmailOtpCredentials, Environment, EthAuthInput, ExecuteBusinessContractOptions, ExecuteOrgDataActionOptions, FetchTrustedManifestOptions, GetActivityLogOptions, GetUsageOptions, GrantCheckParams, GrantCheckResult, GranteeInput, GrantsGetInput, GuestToHostHandler, GuestToHostHandlers, HandshakeResult, HumanMember, InvokeOptions, InvokeRequest, JsonRpcRequest, JsonRpcResponse, KycPollCadence, KycPollOptions, KycStatus, KycStatusKind, ListAgentsInput, ListAgentsResponse, ListContractsParams, ListContractsResult, ListContractsScope, ListHumanMembersInput, ListHumanMembersResponse, ListedContract, Logger, MapCreateInput, MapLifecycleStatus, MapResponse, MapUpdateInput, MapVisibility, MemberRole, MutationResponse, OidcAuthInput, OidcCredentials, OrgAdminStatus, OrgContractGrants, OrgDataActionWire, OrgDataClientOptions, OrgPolicyMeta, OrgPolicyView, OrgUsageReport, OrgUsageReportInput, OrgWriters, OtpChannel, OtpMergeSuggestion, OtpRequestInput, OtpRequestResult, OtpVerifyInput, OtpVerifyResult, PayrollRunRequest, PeerQuoteResult, PolicyGetInput, PurgeOrgInput, QuoteVerifyResult, ReaderSet, RemoveMemberGrantsInput, RoleAssignments, RoleAssignmentsResponse, RoleDefinition, RoleGetResponse, RoleGrant, RoleIdInput, SdkConfig, SecretKind, SecretListInput, SecretListResponse, SecretNameInput, SecretRecord, SecretSetValueInput, SecretView, SecretWriteInput, SessionCrypto, SessionId, SetGrantsInput, SetRoleInput, SetWritersInput, SignedTrustManifest, StringEncoding, SubmitUserInputArgs, SubmitUserInputResult, T3nClientConfig, TenantAdmitProjection, TenantAdmitStatus, TenantBaseClient, TenantClientConfig, TenantContractExecuteInput, TenantContractPublishInput, TenantContractSetDescriptorInput, TenantExecutionSession, TenantMapCreateInput, TenantMapUpdatePatch, TenantMeResponse, TenantSdkEnvironment, TenantSelfAdmitResult, TenantStatus, TenantTargetOptions, TokenTxKind, Transport, TrustAnchor, TrustAnchorOrUnsafe, TrustManifestPayload, UnassignRolesInput, UnsafeTrustServer, UpdateMetaInput, UsageEntry, UsagePage, UsageReportSignature, UserGrant, UserInputProfile, UserUpsertErrorKind, WasmComponent, WasmNextResult, WireBlock, WorkloadAuthInput, WriteDataInput, WriterSet, WritersGetInput };