@terminal3/t3n-sdk 3.6.1 → 3.8.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
@@ -281,7 +281,8 @@ declare enum SessionStatus {
281
281
  */
282
282
  declare enum AuthMethod {
283
283
  Ethereum = "eth",
284
- OIDC = "oidc"
284
+ OIDC = "oidc",
285
+ EmailOtp = "email_otp"
285
286
  }
286
287
  /**
287
288
  * OIDC credentials interface.
@@ -295,6 +296,20 @@ interface OidcCredentials {
295
296
  provider: string;
296
297
  getIdToken: (nonce: string) => Promise<string>;
297
298
  }
299
+ /**
300
+ * Email-OTP credentials interface.
301
+ *
302
+ * The user submits their email; the node sends a one-time code to it.
303
+ * The `getOtpCode` callback is invoked between the two round-trips and
304
+ * must return the code the user received in their inbox (e.g. read from
305
+ * a UI prompt). The resolved DID is keyed on the email, so a user who
306
+ * previously signed in with the same email via Google (OIDC) resolves
307
+ * to the SAME DID — one identity, no double accounts.
308
+ */
309
+ interface EmailOtpCredentials {
310
+ email: string;
311
+ getOtpCode: () => Promise<string>;
312
+ }
298
313
  /**
299
314
  * Base authentication input with method discriminator
300
315
  */
@@ -322,15 +337,23 @@ interface OidcAuthInput extends BaseAuthInput {
322
337
  method: AuthMethod.OIDC;
323
338
  credentials: OidcCredentials;
324
339
  }
340
+ /**
341
+ * Email-OTP authentication input
342
+ */
343
+ interface EmailOtpAuthInput extends BaseAuthInput {
344
+ method: AuthMethod.EmailOtp;
345
+ credentials: EmailOtpCredentials;
346
+ }
325
347
  /**
326
348
  * Union type for all supported authentication inputs
327
349
  */
328
- type AuthInput = EthAuthInput | OidcAuthInput;
350
+ type AuthInput = EthAuthInput | OidcAuthInput | EmailOtpAuthInput;
329
351
  /**
330
352
  * Helper functions to create auth inputs
331
353
  */
332
354
  declare function createEthAuthInput(address: string, options?: EthAuthOptions): EthAuthInput;
333
355
  declare function createOidcAuthInput(credentials: OidcCredentials): OidcAuthInput;
356
+ declare function createEmailOtpAuthInput(credentials: EmailOtpCredentials): EmailOtpAuthInput;
334
357
 
335
358
  /**
336
359
  * Error classes for T3n SDK
@@ -409,6 +432,38 @@ declare class RpcError extends T3nError {
409
432
  /** Per-request correlation id (JSON-RPC `error.data.request_id`). */
410
433
  requestId?: string | undefined);
411
434
  }
435
+ /**
436
+ * Error thrown when an OTP send is throttled by the node.
437
+ *
438
+ * The email-OTP login flow's `InitEmailOtp` step refuses a send when a
439
+ * still-valid code was issued within the resend cooldown
440
+ * (`reason: "cooldown_active"`) or the rolling per-recipient send cap is
441
+ * exhausted (`reason: "send_cap_exceeded"`). Previously a cooldown-
442
+ * suppressed resend returned a silent success, leaving a user who never
443
+ * received the first code at a dead end; this typed error lets the app
444
+ * render a "you just requested a code — retry in {retryAfterSecs}s"
445
+ * affordance instead.
446
+ *
447
+ * Recognised from the node's stable
448
+ * `OtpRateLimited (reason=…, retry_after_secs=…)` wire token (pinned by a
449
+ * server-side test). Subclass of {@link RpcError} so callers that catch
450
+ * the parent still see `httpStatus`/`requestId`; callers that want the
451
+ * typed surface `instanceof OtpRateLimitedError` to read `reason` and
452
+ * `retryAfterSecs`.
453
+ *
454
+ * Retryable after `retryAfterSecs` (caller-side back-off).
455
+ */
456
+ declare class OtpRateLimitedError extends RpcError {
457
+ /** Stable reason code: `"cooldown_active"` or `"send_cap_exceeded"`. */
458
+ readonly reason: string;
459
+ /** Seconds to wait before retrying the send (parsed from `retry_after_secs=`). */
460
+ readonly retryAfterSecs: number;
461
+ constructor(message: string,
462
+ /** Stable reason code: `"cooldown_active"` or `"send_cap_exceeded"`. */
463
+ reason: string,
464
+ /** Seconds to wait before retrying the send (parsed from `retry_after_secs=`). */
465
+ retryAfterSecs: number, rpcMethod?: string, requestId?: string);
466
+ }
412
467
  /**
413
468
  * Error thrown when WASM operations fail
414
469
  */
@@ -1577,6 +1632,22 @@ declare class T3nClient {
1577
1632
  * returns `Finish { did }`.
1578
1633
  */
1579
1634
  private authenticateOidc;
1635
+ /**
1636
+ * Email-OTP two-step authentication.
1637
+ *
1638
+ * Symmetric with {@link authenticateOidc}: bypasses the WASM client
1639
+ * state machine and makes two encrypted RPC calls directly:
1640
+ * 1. `InitEmailOtp { email }` → node sends a one-time code → returns
1641
+ * an `OtpSent` ack.
1642
+ * 2. App calls `getOtpCode()` to obtain the code the user received.
1643
+ * 3. `SubmitOtpCode { code }` → node verifies the code, resolves the
1644
+ * DID on the shared `email:<addr>` key → returns `Finish { did }`.
1645
+ *
1646
+ * Because the DID is keyed on the (server-lowercased) email, a user
1647
+ * who previously signed in with the same address via Google (OIDC)
1648
+ * authenticates to the SAME DID — one identity, no double account.
1649
+ */
1650
+ private authenticateEmailOtp;
1580
1651
  /**
1581
1652
  * Execute an action on the T3n node.
1582
1653
  *
@@ -1814,6 +1885,33 @@ declare class T3nClient {
1814
1885
  * `result.status` for retryable OTP failures.
1815
1886
  */
1816
1887
  otpVerify(input: OtpVerifyInput): Promise<OtpVerifyResult>;
1888
+ /**
1889
+ * Merge the currently-authenticated DID (the *source*) into
1890
+ * `targetDid` (the *survivor*), consolidating two accounts that
1891
+ * belong to the same person. Backed by
1892
+ * `tee:user/contracts::merge-profiles`.
1893
+ *
1894
+ * This is the consolidation path for the wallet ↔ email clash: a user
1895
+ * who claimed with a wallet (one DID) and later proved an email that
1896
+ * already belongs to an OIDC/email DID can fold them into one. The
1897
+ * source's wallets, verified-credential state, and org attribution
1898
+ * are reparented onto the target; the target wins on profile-field
1899
+ * conflicts.
1900
+ *
1901
+ * **Security**: the contract only permits the merge when *both* DIDs
1902
+ * share a verified email or phone — i.e. the caller has OTP-proven
1903
+ * ownership of the same contact on each side. An unproven email can
1904
+ * never absorb a stranger's profile. Typical flow: authenticate
1905
+ * (wallet) → {@link otpVerify} the email → read the returned
1906
+ * `mergeSuggestion.existingDid` → call `mergeProfiles(existingDid)`.
1907
+ *
1908
+ * @param targetDid the surviving DID (absorbs the current session's
1909
+ * DID). Usually the `existingDid` from a {@link otpVerify}
1910
+ * `mergeSuggestion`.
1911
+ * @throws {RpcError} if the contract refuses (e.g. the DIDs share no
1912
+ * verified contact) or on transport / decode failure.
1913
+ */
1914
+ mergeProfiles(targetDid: string): Promise<Record<string, unknown>>;
1817
1915
  /**
1818
1916
  * Submit Level-1 user-input fields to the slim
1819
1917
  * `tee:user/contracts::user-upsert`. The contract merges the
@@ -3231,5 +3329,5 @@ declare function tenantDidHex(tenantDid: string): string;
3231
3329
  declare function validateTail(tail: string): string;
3232
3330
  declare function canonicalTenantName(tenantDid: string, tail: string): string;
3233
3331
 
3234
- export { AGENT_PUBKEY_LEN, AuthMethod, AuthenticationError, BASE_UNITS_PER_TOKEN, ContractResponseError, DEFAULT_INDIVIDUAL_THRESHOLD_CENTS, DEFAULT_KYC_POLL_CADENCE, DELEGATION_CREDENTIAL_DOMAIN, DELEGATION_INVOCATION_DOMAIN, DelegationCustodialClient, ETH_SIG_LEN, HandshakeError, HttpTransport, KycStatusTimeoutError, LogLevel, MAX_FUNCTIONS_PER_CREDENTIAL, MockTransport, NODE_URLS, NONCE_LEN, OrgDataClient, PAYROLL_FUNCTIONS_V1, REQUEST_HASH_LEN, RpcError, SessionExpiredError, SessionOrgDataClient, SessionStateError, SessionStatus, T3nClient, T3nError, TERMINAL_KYC_STATUSES, TOKEN_DECIMALS, TenantClient, TenantContractsNamespace, TenantMapsNamespace, TenantNamespace, TenantSdkValidationError, TenantTokenNamespace, UnsupportedTenantSdkOperationError, UserUpsertError, VC_ID_LEN, WasmError, _b64uEncode, assertShape, b64uDecodeStrict, b64uEncodeBytes, buildDelegationCredential, buildInvocationPreimage, buildPayrollDirectInvocation, buildPayrollInvocation, bytesToString, canonicalTenantName, canonicaliseCredential, canonicaliseRequest, clearKeyCache, compactDidFromBytes, createDefaultHandlers, createEthAuthInput, createLogger, createMlKemPublicKeyHandler, createOidcAuthInput, createOrgDataClientFromSession, createRandomHandler, decodeWasmErrorMessage, eip191Digest, ethRecoverEip191, eth_get_address, extractWasmError, fetchDkgAttestation, fetchMlKemPublicKey, formatTokens, generateRandomString, generateUUID, getEnvironment, getEnvironmentName, getGlobalLogLevel, getLogger, getNodeUrl, getScriptVersion, isDataGetResponse, isDataListResponse, isMutationResponse, isObject, isOrgContractGrants, isOrgPolicyMeta, isOrgWriters, loadConfig, loadWasmComponent, metamask_get_address, metamask_sign, parseContractResponse, redactSecrets, redactSecretsFromJson, requestHash, revokeDelegation, setEnvironment, setGlobalLogLevel, setNodeUrl, signAgentInvocation, signCredential, stringToBytes, tenantDidHex, toBaseUnits, validateConfig, validateCredentialBody, validateTail, verifyDkgAttestation, verifyTdxQuote };
3235
- export type { AgeBand, AuthInput, BalanceRow, BuildDelegationCredentialOpts, BuildPayrollDirectInvocationOpts, BuildPayrollInvocationOpts, ChargeReason, ClientAuth, ClientHandshake, ConfigValidationResult, ContractExecuteInput, ContractPublishInput, ContractResponseSchema, CreatePolicyInput, DataGetInput, DataGetResponse, DataListInput, DataListResponse, DelegationCredential, DelegationCustodialClientOpts, DelegationEnvelope, DeleteDataInput, DeleteGrantsInput, DeleteScopeInput, Did, Direction, DkgAttestation, DkgVerifyResult, EmployeeRecord, EmploymentStatus, Environment, EthAuthInput, ExecuteBusinessContractOptions, ExecuteOrgDataActionOptions, ExpenseClaim, GetUsageOptions, GrantsGetInput, GuestToHostHandler, GuestToHostHandlers, HandshakeResult, JsonRpcRequest, JsonRpcResponse, KycPollCadence, KycPollOptions, KycStatus, KycStatusKind, Logger, MapCreateInput, MapResponse, MapUpdateInput, MapVisibility, MutationResponse, OidcAuthInput, OidcCredentials, OrgContractGrants, OrgDataActionWire, OrgDataClientOptions, OrgPolicyMeta, OrgWriters, OtpChannel, OtpMergeSuggestion, OtpRequestInput, OtpRequestResult, OtpVerifyInput, OtpVerifyResult, PayrollInvocation, PayrollInvocationDelegated, PayrollInvocationDirect, PayrollRunRequest, PeerQuoteResult, PolicyGetInput, QuoteVerifyResult, ReaderSet, ResidencyCategory, RevokeDelegationOpts, RevokeDelegationResult, SdkConfig, SessionCrypto, SessionId, SetGrantsInput, SetWritersInput, SignCustodialResult, SignDelegationResponse, SubmitUserInputArgs, SubmitUserInputResult, T3nClientConfig, TenantAdmitProjection, TenantAdmitStatus, TenantBaseClient, TenantClientConfig, TenantContractExecuteInput, TenantContractPublishInput, TenantExecutionSession, TenantMapCreateInput, TenantMapUpdatePatch, TenantMeResponse, TenantSdkEnvironment, TenantSelfAdmitResult, TenantStatus, TokenTxKind, Transport, UpdateMetaInput, UsageEntry, UsagePage, UserGrant, UserInputProfile, UserUpsertErrorKind, WasmComponent, WasmNextResult, WriteDataInput, WriterSet, WritersGetInput };
3332
+ export { AGENT_PUBKEY_LEN, AuthMethod, AuthenticationError, BASE_UNITS_PER_TOKEN, ContractResponseError, DEFAULT_INDIVIDUAL_THRESHOLD_CENTS, DEFAULT_KYC_POLL_CADENCE, DELEGATION_CREDENTIAL_DOMAIN, DELEGATION_INVOCATION_DOMAIN, DelegationCustodialClient, ETH_SIG_LEN, HandshakeError, HttpTransport, KycStatusTimeoutError, LogLevel, MAX_FUNCTIONS_PER_CREDENTIAL, MockTransport, NODE_URLS, NONCE_LEN, OrgDataClient, OtpRateLimitedError, PAYROLL_FUNCTIONS_V1, REQUEST_HASH_LEN, RpcError, SessionExpiredError, SessionOrgDataClient, SessionStateError, SessionStatus, T3nClient, T3nError, TERMINAL_KYC_STATUSES, TOKEN_DECIMALS, TenantClient, TenantContractsNamespace, TenantMapsNamespace, TenantNamespace, TenantSdkValidationError, TenantTokenNamespace, UnsupportedTenantSdkOperationError, UserUpsertError, VC_ID_LEN, WasmError, _b64uEncode, assertShape, b64uDecodeStrict, b64uEncodeBytes, buildDelegationCredential, buildInvocationPreimage, buildPayrollDirectInvocation, buildPayrollInvocation, bytesToString, canonicalTenantName, canonicaliseCredential, canonicaliseRequest, clearKeyCache, compactDidFromBytes, createDefaultHandlers, createEmailOtpAuthInput, createEthAuthInput, createLogger, createMlKemPublicKeyHandler, createOidcAuthInput, createOrgDataClientFromSession, createRandomHandler, decodeWasmErrorMessage, eip191Digest, ethRecoverEip191, eth_get_address, extractWasmError, fetchDkgAttestation, fetchMlKemPublicKey, formatTokens, generateRandomString, generateUUID, getEnvironment, getEnvironmentName, getGlobalLogLevel, getLogger, getNodeUrl, getScriptVersion, isDataGetResponse, isDataListResponse, isMutationResponse, isObject, isOrgContractGrants, isOrgPolicyMeta, isOrgWriters, loadConfig, loadWasmComponent, metamask_get_address, metamask_sign, parseContractResponse, redactSecrets, redactSecretsFromJson, requestHash, revokeDelegation, setEnvironment, setGlobalLogLevel, setNodeUrl, signAgentInvocation, signCredential, stringToBytes, tenantDidHex, toBaseUnits, validateConfig, validateCredentialBody, validateTail, verifyDkgAttestation, verifyTdxQuote };
3333
+ export type { AgeBand, AuthInput, BalanceRow, BuildDelegationCredentialOpts, BuildPayrollDirectInvocationOpts, BuildPayrollInvocationOpts, ChargeReason, ClientAuth, ClientHandshake, ConfigValidationResult, ContractExecuteInput, ContractPublishInput, ContractResponseSchema, CreatePolicyInput, DataGetInput, DataGetResponse, DataListInput, DataListResponse, DelegationCredential, DelegationCustodialClientOpts, DelegationEnvelope, DeleteDataInput, DeleteGrantsInput, DeleteScopeInput, Did, Direction, DkgAttestation, DkgVerifyResult, EmailOtpAuthInput, EmailOtpCredentials, EmployeeRecord, EmploymentStatus, Environment, EthAuthInput, ExecuteBusinessContractOptions, ExecuteOrgDataActionOptions, ExpenseClaim, GetUsageOptions, GrantsGetInput, GuestToHostHandler, GuestToHostHandlers, HandshakeResult, JsonRpcRequest, JsonRpcResponse, KycPollCadence, KycPollOptions, KycStatus, KycStatusKind, Logger, MapCreateInput, MapResponse, MapUpdateInput, MapVisibility, MutationResponse, OidcAuthInput, OidcCredentials, OrgContractGrants, OrgDataActionWire, OrgDataClientOptions, OrgPolicyMeta, OrgWriters, OtpChannel, OtpMergeSuggestion, OtpRequestInput, OtpRequestResult, OtpVerifyInput, OtpVerifyResult, PayrollInvocation, PayrollInvocationDelegated, PayrollInvocationDirect, PayrollRunRequest, PeerQuoteResult, PolicyGetInput, QuoteVerifyResult, ReaderSet, ResidencyCategory, RevokeDelegationOpts, RevokeDelegationResult, SdkConfig, SessionCrypto, SessionId, SetGrantsInput, SetWritersInput, SignCustodialResult, SignDelegationResponse, SubmitUserInputArgs, SubmitUserInputResult, T3nClientConfig, TenantAdmitProjection, TenantAdmitStatus, TenantBaseClient, TenantClientConfig, TenantContractExecuteInput, TenantContractPublishInput, TenantExecutionSession, TenantMapCreateInput, TenantMapUpdatePatch, TenantMeResponse, TenantSdkEnvironment, TenantSelfAdmitResult, TenantStatus, TokenTxKind, Transport, UpdateMetaInput, UsageEntry, UsagePage, UserGrant, UserInputProfile, UserUpsertErrorKind, WasmComponent, WasmNextResult, WriteDataInput, WriterSet, WritersGetInput };