@anuma/sdk 6.22.0 → 6.24.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.
@@ -706,6 +706,172 @@ declare function callNotionMCPTool<T>(accessToken: string, toolName: string, arg
706
706
  */
707
707
  declare function createGitHubTools(getAccessToken: () => string | null, requestGitHubAccess: () => Promise<string>): ToolConfig[];
708
708
 
709
+ /**
710
+ * Client for the agentres.dev registration flow.
711
+ *
712
+ * Signer-agnostic on purpose: it takes a `signMessage` closure, a base58
713
+ * address and a `fetch`, and imports nothing app-specific. The browser app
714
+ * bridges Privy's embedded Solana wallet to {@link SolanaSignMessageFn} the
715
+ * same way `usePrivySigningAdapters` already bridges the EVM one for
716
+ * encryption, and this module never learns that Privy exists.
717
+ *
718
+ * Registration is four calls plus a status read, and the user is step three:
719
+ *
720
+ * 1. {@link AgentresClient.ensureAccount} — creates the wallet-bound account.
721
+ * 2. {@link AgentresClient.requestCode} — agentres asks Resy to email a code.
722
+ * 3. The user reads the 6-digit code out of their own inbox.
723
+ * 4. {@link AgentresClient.verifyCode} — agentres verifies it and stores the
724
+ * Resy credential.
725
+ * 5. {@link AgentresClient.getLinkStatus} — confirms `resyLinked`.
726
+ *
727
+ * The same email goes to all of them, and its field name is `em_address` on
728
+ * `/api/link-resy` but `email` on `/api/account`. They are the provider's
729
+ * spellings, not a typo.
730
+ *
731
+ * Whichever key signs IS the account, permanently — agentres derives identity
732
+ * from the signature and has no unlink endpoint. So this client must be given
733
+ * the end user's own wallet, never a shared or treasury one.
734
+ *
735
+ * @module lib/connectors/agentres/client
736
+ */
737
+ /**
738
+ * Signs arbitrary bytes with the user's Solana key.
739
+ *
740
+ * Bytes in, bytes out — the SDK base58-encodes the result. Keep it byte-typed
741
+ * end to end: a `Uint8Array` that reaches a string API stringifies to a
742
+ * comma-separated digit list, which signs and encodes cleanly and verifies as
743
+ * garbage with no error anywhere (ai-memoryless-client#7217).
744
+ */
745
+ type SolanaSignMessageFn = (message: Uint8Array) => Promise<Uint8Array>;
746
+ /** The `fetch` surface this client uses. Injected so tests make no network call. */
747
+ type FetchLike = (url: string, init?: RequestInit) => Promise<Response>;
748
+ interface AgentresClientOptions {
749
+ /** The user's own Solana address, base58. The identity the proof asserts. */
750
+ address: string;
751
+ signMessage: SolanaSignMessageFn;
752
+ /** @default "https://agentres.dev" */
753
+ baseUrl?: string;
754
+ /** @default globalThis.fetch */
755
+ fetch?: FetchLike;
756
+ }
757
+ /** One call to make through {@link AgentresClient.withSiwx}. */
758
+ interface AgentresRequest {
759
+ method: "GET" | "POST";
760
+ /** Path on the agentres host, e.g. `/api/me`. */
761
+ path: string;
762
+ /** JSON body, for POSTs. */
763
+ body?: unknown;
764
+ }
765
+ /** `POST /api/account` — the wallet-bound account, resolved or created. */
766
+ interface AgentresAccount {
767
+ accountId: string;
768
+ email: string | null;
769
+ /** `wallet` for this flow; `api_key` is the other auth path agentres offers. */
770
+ credentialKind: string;
771
+ walletLinked: boolean;
772
+ }
773
+ /** `POST /api/link-resy` — which half of the OTP exchange just completed. */
774
+ interface AgentresLinkStep {
775
+ step: "code_sent" | "linked";
776
+ message?: string;
777
+ /** Present once linked. */
778
+ resyUserId?: number;
779
+ }
780
+ /** `GET /api/me` — what the tile renders from. */
781
+ interface AgentresLinkStatus {
782
+ accountId: string;
783
+ email: string | null;
784
+ resyLinked: boolean;
785
+ /** The address agentres resolved from the proof. Base58, despite the OpenAPI's 0x pattern. */
786
+ walletAddress: string | null;
787
+ resyLinkedAt: string | null;
788
+ }
789
+ interface AgentresClient {
790
+ /**
791
+ * Make one call, satisfying its 402 with a fresh SIWX proof.
792
+ *
793
+ * Always two requests: the first is unauthenticated and expected to answer
794
+ * 402, the second carries the proof. Nonces are single-use and expire minutes
795
+ * after they are issued, so nothing here is cached — a reused challenge works
796
+ * in a fast dev loop and fails in real use.
797
+ */
798
+ withSiwx<T>(request: AgentresRequest): Promise<T>;
799
+ ensureAccount(email: string): Promise<AgentresAccount>;
800
+ requestCode(email: string): Promise<AgentresLinkStep>;
801
+ verifyCode(email: string, code: string): Promise<AgentresLinkStep>;
802
+ getLinkStatus(): Promise<AgentresLinkStatus>;
803
+ }
804
+ /**
805
+ * Build a client bound to one wallet.
806
+ *
807
+ * The client holds no state between calls, deliberately. The pending code lives
808
+ * at agentres, keyed by email, and step three of the flow sends the user out to
809
+ * their inbox — on a phone that can unmount the page, so the instance that
810
+ * requested the code is often not the instance that verifies it. A client that
811
+ * remembered would refuse a code that is still perfectly valid upstream.
812
+ */
813
+ declare function createAgentresClient(options: AgentresClientOptions): AgentresClient;
814
+
815
+ /**
816
+ * Typed errors for the agentres connector.
817
+ *
818
+ * agentres states every refusal in one envelope, on every route:
819
+ *
820
+ * ```json
821
+ * { "error": { "code": "NO_LINKED_ACCOUNT", "message": "…", "retryable": false,
822
+ * "next_step": "Call POST /api/link-resy with the account email." } }
823
+ * ```
824
+ *
825
+ * `next_step` is often the only actionable part — it is the provider's own
826
+ * sentence about what to do next — so it is carried through to the caller
827
+ * rather than folded into the message. The registration UI shows the raw code
828
+ * and message, which is deliberate: a refusal here is usually the user's Resy
829
+ * account state, not a bug, and paraphrasing it hides what to fix.
830
+ *
831
+ * The SIWX errors are separate because they are ours, not the provider's: they
832
+ * mean the challenge never became a usable proof, so no request was authorized.
833
+ *
834
+ * @module lib/connectors/agentres/errors
835
+ */
836
+ /**
837
+ * Provider codes the registration flow can return.
838
+ *
839
+ * `AgentresError.code` stays a plain `string` — agentres documents two dozen
840
+ * more for the booking routes, and new ones appear without a version bump —
841
+ * but these four are the ones a registration surface has to handle by name.
842
+ */
843
+ type AgentresErrorCode = "NO_LINKED_ACCOUNT" | "RESY_VERIFICATION_FAILED" | "RESY_NO_PAYMENT_METHOD" | "UNAUTHORIZED";
844
+ /** A refusal agentres stated, decoded from its error envelope. */
845
+ declare class AgentresError extends Error {
846
+ /** HTTP status the refusal arrived with. */
847
+ readonly status: number;
848
+ /** Provider's stable machine-readable code, e.g. `NO_LINKED_ACCOUNT`. */
849
+ readonly code: string;
850
+ /** Whether the provider says the same call could work later. */
851
+ readonly retryable: boolean;
852
+ /** What the provider says to do about it, when it says anything. */
853
+ readonly nextStep?: string;
854
+ constructor(status: number, code: string, message: string, retryable: boolean, nextStep?: string);
855
+ }
856
+ /**
857
+ * The 402 carried no `sign-in-with-x` extension.
858
+ *
859
+ * That marks a paid endpoint, which SIWX cannot satisfy. Signing anyway would
860
+ * produce a well-formed proof the server answers with a bare 401, so the cause
861
+ * has to be named here or it surfaces as an authentication mystery later.
862
+ */
863
+ declare class SiwxUnsupportedError extends Error {
864
+ constructor(message: string);
865
+ }
866
+ /** The challenge could not be read, or is missing something the proof needs. */
867
+ declare class SiwxChallengeError extends Error {
868
+ /** The underlying decode failure, when there was one. */
869
+ readonly cause?: unknown;
870
+ constructor(message: string, options?: {
871
+ cause?: unknown;
872
+ });
873
+ }
874
+
709
875
  /**
710
876
  * Token-getter factory shared by every connector tool factory.
711
877
  *
@@ -2849,4 +3015,4 @@ declare const DEFAULT_MAX_DOCUMENT_CONVERSATIONS = 1000;
2849
3015
  */
2850
3016
  declare function createDocumentTools({ getConversationId, storage, logError, displayDocument, maxConversations, }: CreateDocumentToolsOptions): ToolConfig[];
2851
3017
 
2852
- export { ADD_SLIDE_SCHEMA, APP_BUILDER_PROMPT, APP_COMPLETE_CONNECT_ACK_TYPE, APP_COMPLETE_CONNECT_TYPE, APP_COMPLETE_DEFAULT_TIMEOUT_MS, APP_COMPLETE_IFRAME_SHIM_SCRIPT, APP_COMPLETE_REQUEST_TYPE, APP_COMPLETE_RESPONSE_TYPE, APP_COMPLETE_STUB_SCRIPT, APP_FILE_TOOL_NAMES, APP_PREVIEW_BASELINE_CSS, AUDIT_DESIGN_SCHEMA, type AnchorMatch, type AnumaChild, AnumaJsxError, type AnumaNode, type AppCompleteBridge, type AppCompleteBridgeOptions, type AppFileRecord, type AppFileStorage, type AttrValue, type AuditIssue, type AuditIssueType, type AuditResult, type AuditSeverity, type AuditTokens, type BuildSlideSystemPromptOptions, CONNECTOR_ERROR_MARKER, CREATE_DOCUMENT_SCHEMA, CREATE_FILE_SCHEMA, CRITIQUE_DESIGN_SCHEMA, type CalendarEvent, type ChartDataPoint, type ChoiceOption, type ConnectorErrorCode, type ConnectorMintError, type ConnectorMintResult, type ConnectorTokenGetterOpts, type ConnectorTokenSource, type CreateAppGenerationToolsOptions, type CreateDocumentToolsOptions, type CreateEventArgs, type CreateFileArgs, type CreateSlideToolsOptions, type CreateUIToolsOptions, type CreateWeatherToolOptions, DEFAULT_DESIGN_CRITIQUE_RUBRIC, DEFAULT_DOCUMENT_ID, DEFAULT_MAX_CONVERSATIONS, DEFAULT_MAX_DOCUMENT_CONVERSATIONS, DELETE_FILE_SCHEMA, DOCUMENT_BUILDER_PROMPT, DOCUMENT_TOOL_NAMES, type DisplayChartResult, type DisplayConnectorResult, type DisplayPhoneCallOfferResult, type DisplayToolConfig, type DisplayToolMigrations, type DisplayWeatherResult, type DocAttrValue, type DocChild, DocDslError, type DocNode, type DriveFile, type DropboxRequestAccess, type DropboxTokenGetter, type ExportAppOptions, FONT_LIBRARY, FONT_PRESETS, type FileChangeEvent, type FileSnippet, type FontCategory, type FontPreset, type FontSpec, type ForecastDay, type FormField, type FormFieldOption, type FormFieldType, type GetFileContentArgs, type GmailGetMessageArgs, type GmailMessageDetail, type GmailMessageSummary, type GmailRequestAccess, type GmailSearchArgs, type GmailSendMessageArgs, type GmailTokenGetter, type InteractiveToolConfig, type KnownTag, LAYOUT_MODES, LIST_FILES_SCHEMA, type LayoutMode, type LegacyDeckJson, type ListEventsArgs, type ListRecentFilesArgs, MapFileStorage, type NotionCreatePagesArgs, type NotionFetchArgs, type NotionMovePagesArgs, type NotionSearchArgs, type NotionUpdatePageArgs, PATCH_DOCUMENT_SCHEMA, PATCH_FILE_SCHEMA, PATCH_SLIDES_SCHEMA, PLAN_DECK_SCHEMA, type PatchFailure, type PatchFailureReason, type PdfTag, READ_DOCUMENT_SCHEMA, READ_FILE_SCHEMA, READ_SLIDES_SCHEMA, RUNTIME_ERROR_OVERLAY_SCRIPT, SLIDES_FILE_PATH, SLIDE_CANVAS_HEIGHT, SLIDE_CANVAS_WIDTH, type SearchFilesArgs, type SlackGetChannelHistoryArgs, type SlackGetThreadRepliesArgs, type SlackListChannelsArgs, type SlackListDmsArgs, type SlackListUsersArgs, type SlackPostMessageArgs, type SlackProxyCaller, type SlackSearchMessagesArgs, type SlideToolSet, THEME_ATTRS, type ThemeAttr, type ToolConfig, type ToolExecutionErrorType, type ToolExecutionResult, type UIInteractionContext, type UpdateEventArgs, type UpdateFileArgs, VERIFY_APP_SCHEMA, type VerifyAppResult, type XGetMeArgs, type XGetMyPostsArgs, type XProxyCaller, applyPatches, auditDesign, buildAppFileManifest, buildAppSystemPrompt, buildConnectorErrorResult, buildDocumentSystemPrompt, buildFontsUrl, buildSlideSystemPrompt, callNotionMCPTool, connectorMintErrorToToolResult, convertLegacyDeckJson, createAppCompleteBridge, createAppGenerationTools, createChartTool, createChatTools, createChoiceTool, createConnectorOfferTool, createConnectorTokenGetter, createDisplayTool, createDocumentTools, createDriveTools, createDropboxTools, createFormTool, createGitHubTools, createGmailTools, createGoogleCalendarCreateEventTool, createGoogleCalendarTool, createGoogleCalendarUpdateEventTool, createGoogleDriveCreateFileTool, createGoogleDriveGetContentTool, createGoogleDriveListRecentTool, createGoogleDriveSearchTool, createGoogleDriveUpdateFileTool, createInteractiveTool, createNotionCreateCommentTool, createNotionCreateDatabaseTool, createNotionCreatePagesTool, createNotionDuplicatePageTool, createNotionFetchTool, createNotionGetCommentsTool, createNotionGetTeamsTool, createNotionGetUsersTool, createNotionMovePagesTool, createNotionSearchTool, createNotionTools, createNotionUpdateDataSourceTool, createNotionUpdatePageTool, createPhoneCallOfferTool, createSlackTools, createSlideTools, createWeatherTool, createXTools, documentPath, exportAppToHtml, findById, findParentOfId, getFontByName, getId, getMCPEndpoints, getNumberAttr, getStringAttr, insertAfterId, insertChild, installAppCompleteIframeShim, isAnumaTag, isHtmlTag, isKnownFont, isLegacyDeckJson, isPdfTag, migrateDisplayResult, normalizePath, parseDocumentDsl, parseJsx, pdfStyleKeys, pdfTags, removeById, replaceById, serializeJsx, truncateContent, updateAttrs, walk };
3018
+ export { ADD_SLIDE_SCHEMA, APP_BUILDER_PROMPT, APP_COMPLETE_CONNECT_ACK_TYPE, APP_COMPLETE_CONNECT_TYPE, APP_COMPLETE_DEFAULT_TIMEOUT_MS, APP_COMPLETE_IFRAME_SHIM_SCRIPT, APP_COMPLETE_REQUEST_TYPE, APP_COMPLETE_RESPONSE_TYPE, APP_COMPLETE_STUB_SCRIPT, APP_FILE_TOOL_NAMES, APP_PREVIEW_BASELINE_CSS, AUDIT_DESIGN_SCHEMA, type AgentresAccount, type AgentresClient, type AgentresClientOptions, AgentresError, type AgentresErrorCode, type AgentresLinkStatus, type AgentresLinkStep, type AnchorMatch, type AnumaChild, AnumaJsxError, type AnumaNode, type AppCompleteBridge, type AppCompleteBridgeOptions, type AppFileRecord, type AppFileStorage, type AttrValue, type AuditIssue, type AuditIssueType, type AuditResult, type AuditSeverity, type AuditTokens, type BuildSlideSystemPromptOptions, CONNECTOR_ERROR_MARKER, CREATE_DOCUMENT_SCHEMA, CREATE_FILE_SCHEMA, CRITIQUE_DESIGN_SCHEMA, type CalendarEvent, type ChartDataPoint, type ChoiceOption, type ConnectorErrorCode, type ConnectorMintError, type ConnectorMintResult, type ConnectorTokenGetterOpts, type ConnectorTokenSource, type CreateAppGenerationToolsOptions, type CreateDocumentToolsOptions, type CreateEventArgs, type CreateFileArgs, type CreateSlideToolsOptions, type CreateUIToolsOptions, type CreateWeatherToolOptions, DEFAULT_DESIGN_CRITIQUE_RUBRIC, DEFAULT_DOCUMENT_ID, DEFAULT_MAX_CONVERSATIONS, DEFAULT_MAX_DOCUMENT_CONVERSATIONS, DELETE_FILE_SCHEMA, DOCUMENT_BUILDER_PROMPT, DOCUMENT_TOOL_NAMES, type DisplayChartResult, type DisplayConnectorResult, type DisplayPhoneCallOfferResult, type DisplayToolConfig, type DisplayToolMigrations, type DisplayWeatherResult, type DocAttrValue, type DocChild, DocDslError, type DocNode, type DriveFile, type DropboxRequestAccess, type DropboxTokenGetter, type ExportAppOptions, FONT_LIBRARY, FONT_PRESETS, type FileChangeEvent, type FileSnippet, type FontCategory, type FontPreset, type FontSpec, type ForecastDay, type FormField, type FormFieldOption, type FormFieldType, type GetFileContentArgs, type GmailGetMessageArgs, type GmailMessageDetail, type GmailMessageSummary, type GmailRequestAccess, type GmailSearchArgs, type GmailSendMessageArgs, type GmailTokenGetter, type InteractiveToolConfig, type KnownTag, LAYOUT_MODES, LIST_FILES_SCHEMA, type LayoutMode, type LegacyDeckJson, type ListEventsArgs, type ListRecentFilesArgs, MapFileStorage, type NotionCreatePagesArgs, type NotionFetchArgs, type NotionMovePagesArgs, type NotionSearchArgs, type NotionUpdatePageArgs, PATCH_DOCUMENT_SCHEMA, PATCH_FILE_SCHEMA, PATCH_SLIDES_SCHEMA, PLAN_DECK_SCHEMA, type PatchFailure, type PatchFailureReason, type PdfTag, READ_DOCUMENT_SCHEMA, READ_FILE_SCHEMA, READ_SLIDES_SCHEMA, RUNTIME_ERROR_OVERLAY_SCRIPT, SLIDES_FILE_PATH, SLIDE_CANVAS_HEIGHT, SLIDE_CANVAS_WIDTH, type SearchFilesArgs, SiwxChallengeError, SiwxUnsupportedError, type SlackGetChannelHistoryArgs, type SlackGetThreadRepliesArgs, type SlackListChannelsArgs, type SlackListDmsArgs, type SlackListUsersArgs, type SlackPostMessageArgs, type SlackProxyCaller, type SlackSearchMessagesArgs, type SlideToolSet, type SolanaSignMessageFn, THEME_ATTRS, type ThemeAttr, type ToolConfig, type ToolExecutionErrorType, type ToolExecutionResult, type UIInteractionContext, type UpdateEventArgs, type UpdateFileArgs, VERIFY_APP_SCHEMA, type VerifyAppResult, type XGetMeArgs, type XGetMyPostsArgs, type XProxyCaller, applyPatches, auditDesign, buildAppFileManifest, buildAppSystemPrompt, buildConnectorErrorResult, buildDocumentSystemPrompt, buildFontsUrl, buildSlideSystemPrompt, callNotionMCPTool, connectorMintErrorToToolResult, convertLegacyDeckJson, createAgentresClient, createAppCompleteBridge, createAppGenerationTools, createChartTool, createChatTools, createChoiceTool, createConnectorOfferTool, createConnectorTokenGetter, createDisplayTool, createDocumentTools, createDriveTools, createDropboxTools, createFormTool, createGitHubTools, createGmailTools, createGoogleCalendarCreateEventTool, createGoogleCalendarTool, createGoogleCalendarUpdateEventTool, createGoogleDriveCreateFileTool, createGoogleDriveGetContentTool, createGoogleDriveListRecentTool, createGoogleDriveSearchTool, createGoogleDriveUpdateFileTool, createInteractiveTool, createNotionCreateCommentTool, createNotionCreateDatabaseTool, createNotionCreatePagesTool, createNotionDuplicatePageTool, createNotionFetchTool, createNotionGetCommentsTool, createNotionGetTeamsTool, createNotionGetUsersTool, createNotionMovePagesTool, createNotionSearchTool, createNotionTools, createNotionUpdateDataSourceTool, createNotionUpdatePageTool, createPhoneCallOfferTool, createSlackTools, createSlideTools, createWeatherTool, createXTools, documentPath, exportAppToHtml, findById, findParentOfId, getFontByName, getId, getMCPEndpoints, getNumberAttr, getStringAttr, insertAfterId, insertChild, installAppCompleteIframeShim, isAnumaTag, isHtmlTag, isKnownFont, isLegacyDeckJson, isPdfTag, migrateDisplayResult, normalizePath, parseDocumentDsl, parseJsx, pdfStyleKeys, pdfTags, removeById, replaceById, serializeJsx, truncateContent, updateAttrs, walk };
@@ -586,7 +586,7 @@ function createPhoneCallOfferTool(options) {
586
586
  function createConnectorOfferTool(options) {
587
587
  return createDisplayTool(options, {
588
588
  name: "display_connector",
589
- description: "Display an inline card that prompts the user to connect an app or service (for example Notion, Gmail, Google Drive, Google Calendar, GitHub, Dropbox). Call this when the user asks to connect, link, enable, or authorize one of these apps, or when answering their request requires access the user has not yet granted. The card renders the connect prompt visually; do NOT repeat the connection instructions in your text response.",
589
+ description: "Display an inline card that prompts the user to connect an app or service (for example Notion, Gmail, Google Drive, Google Calendar, GitHub, Dropbox, or Agentic Reservations for restaurant bookings, id 'agentres'). Call this when the user asks to connect, link, enable, or authorize one of these apps, or when answering their request requires access the user has not yet granted. The card renders the connect prompt visually; do NOT repeat the connection instructions in your text response.",
590
590
  parameters: {
591
591
  type: "object",
592
592
  properties: {
@@ -2401,6 +2401,344 @@ function createGitHubTools(getAccessToken, requestGitHubAccess) {
2401
2401
  ];
2402
2402
  }
2403
2403
 
2404
+ // src/lib/connectors/agentres/errors.ts
2405
+ var AgentresError = class extends Error {
2406
+ constructor(status, code, message, retryable, nextStep) {
2407
+ super(message);
2408
+ this.name = "AgentresError";
2409
+ this.status = status;
2410
+ this.code = code;
2411
+ this.retryable = retryable;
2412
+ this.nextStep = nextStep;
2413
+ }
2414
+ };
2415
+ var SiwxUnsupportedError = class extends Error {
2416
+ constructor(message) {
2417
+ super(message);
2418
+ this.name = "SiwxUnsupportedError";
2419
+ }
2420
+ };
2421
+ var SiwxChallengeError = class extends Error {
2422
+ constructor(message, options) {
2423
+ super(message);
2424
+ this.name = "SiwxChallengeError";
2425
+ this.cause = options?.cause;
2426
+ }
2427
+ };
2428
+ function parseAgentresError(status, body) {
2429
+ const stated = statedError(body);
2430
+ if (!stated) {
2431
+ return new AgentresError(
2432
+ status,
2433
+ `HTTP_${status}`,
2434
+ body.trim() || `HTTP ${status}`,
2435
+ status >= 500
2436
+ );
2437
+ }
2438
+ const code = typeof stated.code === "string" ? stated.code : `HTTP_${status}`;
2439
+ const message = typeof stated.message === "string" ? stated.message : `HTTP ${status}`;
2440
+ const retryable = typeof stated.retryable === "boolean" ? stated.retryable : status >= 500;
2441
+ const nextStep = typeof stated.next_step === "string" ? stated.next_step : void 0;
2442
+ return new AgentresError(status, code, message, retryable, nextStep);
2443
+ }
2444
+ function statedError(body) {
2445
+ let parsed;
2446
+ try {
2447
+ parsed = JSON.parse(body);
2448
+ } catch {
2449
+ return null;
2450
+ }
2451
+ const envelope = parsed;
2452
+ const stated = typeof envelope?.error === "object" && envelope.error !== null ? envelope.error : null;
2453
+ if (!stated) {
2454
+ return null;
2455
+ }
2456
+ const fields = stated;
2457
+ if (typeof fields.code !== "string" && typeof fields.message !== "string") {
2458
+ return null;
2459
+ }
2460
+ return fields;
2461
+ }
2462
+
2463
+ // src/lib/processors/encoding.ts
2464
+ var B64_ENCODE_CHUNK = 32768 * 3;
2465
+ function uint8ArrayToBase64(data) {
2466
+ if (typeof Buffer !== "undefined") {
2467
+ return Buffer.from(data).toString("base64");
2468
+ }
2469
+ let base64 = "";
2470
+ for (let i = 0; i < data.length; i += B64_ENCODE_CHUNK) {
2471
+ const slice = data.subarray(i, i + B64_ENCODE_CHUNK);
2472
+ let binary = "";
2473
+ for (let j = 0; j < slice.length; j++) {
2474
+ binary += String.fromCharCode(slice[j]);
2475
+ }
2476
+ base64 += btoa(binary);
2477
+ }
2478
+ return base64;
2479
+ }
2480
+ function base64ToUint8Array(base64) {
2481
+ if (typeof Buffer !== "undefined") {
2482
+ const buf = Buffer.from(base64, "base64");
2483
+ return new Uint8Array(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength));
2484
+ }
2485
+ const binary = atob(base64);
2486
+ const bytes = new Uint8Array(binary.length);
2487
+ for (let i = 0; i < binary.length; i++) {
2488
+ bytes[i] = binary.charCodeAt(i);
2489
+ }
2490
+ return bytes;
2491
+ }
2492
+
2493
+ // src/lib/connectors/agentres/siwx.ts
2494
+ var PAYMENT_REQUIRED_HEADER = "PAYMENT-REQUIRED";
2495
+ var SIWX_HEADER = "SIGN-IN-WITH-X";
2496
+ var SIWX_EXTENSION = "sign-in-with-x";
2497
+ var SOLANA_NAMESPACE = "solana:";
2498
+ function parseChallenge(paymentRequiredHeader, expectedOrigin) {
2499
+ const decoded = decodeHeader(paymentRequiredHeader);
2500
+ const extensions = asRecord(decoded.extensions);
2501
+ const extension = extensions ? asRecord(extensions[SIWX_EXTENSION]) : null;
2502
+ if (!extension) {
2503
+ throw new SiwxUnsupportedError(
2504
+ "the 402 carries no sign-in-with-x extension, so this endpoint is paid rather than identity-only"
2505
+ );
2506
+ }
2507
+ const info = asRecord(extension.info);
2508
+ if (!info) {
2509
+ throw new SiwxChallengeError("the sign-in-with-x extension has no info block");
2510
+ }
2511
+ const chain = solanaChain(extension.supportedChains);
2512
+ const challenge = {
2513
+ domain: requireString(info, "domain"),
2514
+ uri: requireString(info, "uri"),
2515
+ version: requireString(info, "version"),
2516
+ statement: requireString(info, "statement"),
2517
+ nonce: requireString(info, "nonce"),
2518
+ issuedAt: requireString(info, "issuedAt"),
2519
+ resources: requireResources(info),
2520
+ chainId: chain.chainId,
2521
+ signingType: chain.signingType
2522
+ };
2523
+ assertScopedTo(challenge, expectedOrigin);
2524
+ return challenge;
2525
+ }
2526
+ function assertScopedTo(challenge, expectedOrigin) {
2527
+ const expected = parseUrl(expectedOrigin, `the agentres base URL "${expectedOrigin}"`);
2528
+ if (challenge.domain !== expected.host) {
2529
+ throw new SiwxChallengeError(
2530
+ `the challenge is scoped to "${challenge.domain}" but this client talks to "${expected.host}" \u2014 refusing to sign it`
2531
+ );
2532
+ }
2533
+ const uri = parseUrl(challenge.uri, `the sign-in-with-x uri "${challenge.uri}"`);
2534
+ if (uri.origin !== expected.origin) {
2535
+ throw new SiwxChallengeError(
2536
+ `the challenge addresses "${uri.origin}" but this client talks to "${expected.origin}" \u2014 refusing to sign it`
2537
+ );
2538
+ }
2539
+ }
2540
+ function parseUrl(value, description) {
2541
+ try {
2542
+ return new URL(value);
2543
+ } catch (cause) {
2544
+ throw new SiwxChallengeError(`${description} is not a URL`, { cause });
2545
+ }
2546
+ }
2547
+ function buildMessage(challenge, address) {
2548
+ if (!challenge.chainId.startsWith(SOLANA_NAMESPACE)) {
2549
+ throw new SiwxChallengeError(
2550
+ `expected a solana: chain id for the message, got "${challenge.chainId}"`
2551
+ );
2552
+ }
2553
+ const reference = challenge.chainId.slice(SOLANA_NAMESPACE.length);
2554
+ const resources = challenge.resources.map((resource) => `- ${resource}`).join("\n");
2555
+ return `${challenge.domain} wants you to sign in with your Solana account:
2556
+ ${address}
2557
+
2558
+ ${challenge.statement}
2559
+
2560
+ URI: ${challenge.uri}
2561
+ Version: ${challenge.version}
2562
+ Chain ID: ${reference}
2563
+ Nonce: ${challenge.nonce}
2564
+ Issued At: ${challenge.issuedAt}
2565
+ Resources:
2566
+ ${resources}`;
2567
+ }
2568
+ function buildPayload(challenge, address, signature) {
2569
+ const payload = {
2570
+ domain: challenge.domain,
2571
+ address,
2572
+ statement: challenge.statement,
2573
+ uri: challenge.uri,
2574
+ version: challenge.version,
2575
+ // Full CAIP-2 here, unlike the bare reference the message carries.
2576
+ chainId: challenge.chainId,
2577
+ type: challenge.signingType,
2578
+ nonce: challenge.nonce,
2579
+ issuedAt: challenge.issuedAt,
2580
+ resources: challenge.resources,
2581
+ signature: base58Encode(signature)
2582
+ };
2583
+ return uint8ArrayToBase64(new TextEncoder().encode(JSON.stringify(payload)));
2584
+ }
2585
+ var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
2586
+ function base58Encode(bytes) {
2587
+ let zeros = 0;
2588
+ while (zeros < bytes.length && bytes[zeros] === 0) {
2589
+ zeros++;
2590
+ }
2591
+ const digits = [];
2592
+ for (let i = zeros; i < bytes.length; i++) {
2593
+ let carry = bytes[i];
2594
+ for (let j = 0; j < digits.length; j++) {
2595
+ carry += digits[j] * 256;
2596
+ digits[j] = carry % 58;
2597
+ carry = Math.floor(carry / 58);
2598
+ }
2599
+ while (carry > 0) {
2600
+ digits.push(carry % 58);
2601
+ carry = Math.floor(carry / 58);
2602
+ }
2603
+ }
2604
+ let encoded = "1".repeat(zeros);
2605
+ for (let i = digits.length - 1; i >= 0; i--) {
2606
+ encoded += BASE58_ALPHABET[digits[i]];
2607
+ }
2608
+ return encoded;
2609
+ }
2610
+ function decodeHeader(paymentRequiredHeader) {
2611
+ let parsed;
2612
+ try {
2613
+ parsed = JSON.parse(new TextDecoder().decode(base64ToUint8Array(paymentRequiredHeader)));
2614
+ } catch (cause) {
2615
+ throw new SiwxChallengeError("the PAYMENT-REQUIRED header is not base64-encoded JSON", {
2616
+ cause
2617
+ });
2618
+ }
2619
+ const decoded = asRecord(parsed);
2620
+ if (!decoded) {
2621
+ throw new SiwxChallengeError("the PAYMENT-REQUIRED header did not decode to an object");
2622
+ }
2623
+ return decoded;
2624
+ }
2625
+ function solanaChain(supportedChains) {
2626
+ if (!Array.isArray(supportedChains)) {
2627
+ throw new SiwxChallengeError("the sign-in-with-x extension lists no supportedChains");
2628
+ }
2629
+ for (const entry of supportedChains) {
2630
+ const chain = asRecord(entry);
2631
+ const chainId = chain?.chainId;
2632
+ if (typeof chainId !== "string" || !chainId.startsWith(SOLANA_NAMESPACE)) {
2633
+ continue;
2634
+ }
2635
+ const signingType = chain?.type;
2636
+ if (typeof signingType !== "string" || signingType === "") {
2637
+ throw new SiwxChallengeError(`the ${chainId} entry declares no signing type`);
2638
+ }
2639
+ return { chainId, signingType };
2640
+ }
2641
+ throw new SiwxChallengeError("the sign-in-with-x extension offers no solana: chain");
2642
+ }
2643
+ function asRecord(value) {
2644
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
2645
+ }
2646
+ function requireString(info, key) {
2647
+ const value = info[key];
2648
+ if (typeof value !== "string" || value === "") {
2649
+ throw new SiwxChallengeError(`the sign-in-with-x info block has no ${key}`);
2650
+ }
2651
+ return value;
2652
+ }
2653
+ function requireResources(info) {
2654
+ const resources = info.resources;
2655
+ if (!Array.isArray(resources) || resources.length === 0) {
2656
+ throw new SiwxChallengeError("the sign-in-with-x info block has no resources");
2657
+ }
2658
+ if (!resources.every((resource) => typeof resource === "string" && resource !== "")) {
2659
+ throw new SiwxChallengeError("the sign-in-with-x resources are not all strings");
2660
+ }
2661
+ return resources;
2662
+ }
2663
+
2664
+ // src/lib/connectors/agentres/client.ts
2665
+ var DEFAULT_BASE_URL = "https://agentres.dev";
2666
+ function createAgentresClient(options) {
2667
+ const baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
2668
+ const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
2669
+ const { address, signMessage } = options;
2670
+ async function withSiwx(request) {
2671
+ const url = `${baseUrl}${request.path}`;
2672
+ const init = requestInit(request);
2673
+ const challenged = await fetchImpl(url, init);
2674
+ if (challenged.status !== 402) {
2675
+ return readBody(challenged);
2676
+ }
2677
+ await challenged.body?.cancel().catch(() => {
2678
+ });
2679
+ const header = challenged.headers.get(PAYMENT_REQUIRED_HEADER);
2680
+ if (!header) {
2681
+ throw new SiwxChallengeError(
2682
+ `the 402 from ${request.path} carried no ${PAYMENT_REQUIRED_HEADER} header`
2683
+ );
2684
+ }
2685
+ const challenge = parseChallenge(header, baseUrl);
2686
+ const signature = await signMessage(new TextEncoder().encode(buildMessage(challenge, address)));
2687
+ const authorized = await fetchImpl(url, {
2688
+ ...init,
2689
+ headers: { ...init.headers, [SIWX_HEADER]: buildPayload(challenge, address, signature) }
2690
+ });
2691
+ return readBody(authorized);
2692
+ }
2693
+ async function linkResy(body) {
2694
+ const response = await withSiwx({ method: "POST", path: "/api/link-resy", body });
2695
+ return { step: response.step, message: response.message, resyUserId: response.resy_user_id };
2696
+ }
2697
+ return {
2698
+ withSiwx,
2699
+ async ensureAccount(email) {
2700
+ const body = await withSiwx({ method: "POST", path: "/api/account", body: { email } });
2701
+ return {
2702
+ accountId: body.account_id,
2703
+ email: body.email,
2704
+ credentialKind: body.credential_kind,
2705
+ walletLinked: body.wallet_linked
2706
+ };
2707
+ },
2708
+ requestCode(email) {
2709
+ return linkResy({ em_address: email });
2710
+ },
2711
+ verifyCode(email, code) {
2712
+ return linkResy({ em_address: email, code });
2713
+ },
2714
+ async getLinkStatus() {
2715
+ const body = await withSiwx({ method: "GET", path: "/api/me" });
2716
+ return {
2717
+ accountId: body.account_id,
2718
+ email: body.email,
2719
+ resyLinked: body.resy_linked,
2720
+ walletAddress: body.wallet_address,
2721
+ resyLinkedAt: body.resy_linked_at ?? null
2722
+ };
2723
+ }
2724
+ };
2725
+ }
2726
+ function requestInit(request) {
2727
+ const headers = { Accept: "application/json" };
2728
+ if (request.body === void 0) {
2729
+ return { method: request.method, headers };
2730
+ }
2731
+ headers["Content-Type"] = "application/json";
2732
+ return { method: request.method, headers, body: JSON.stringify(request.body) };
2733
+ }
2734
+ async function readBody(response) {
2735
+ const body = await response.text();
2736
+ if (!response.ok) {
2737
+ throw parseAgentresError(response.status, body);
2738
+ }
2739
+ return JSON.parse(body);
2740
+ }
2741
+
2404
2742
  // src/lib/connectors/client.ts
2405
2743
  var DEFAULT_REFRESH_BEFORE_MS = 3e4;
2406
2744
  function createConnectorTokenGetter(client, provider, opts = {}) {
@@ -13526,6 +13864,7 @@ export {
13526
13864
  APP_FILE_TOOL_NAMES,
13527
13865
  APP_PREVIEW_BASELINE_CSS,
13528
13866
  AUDIT_DESIGN_SCHEMA,
13867
+ AgentresError,
13529
13868
  AnumaJsxError,
13530
13869
  CONNECTOR_ERROR_MARKER,
13531
13870
  CREATE_DOCUMENT_SCHEMA,
@@ -13555,6 +13894,8 @@ export {
13555
13894
  SLIDES_FILE_PATH,
13556
13895
  SLIDE_CANVAS_HEIGHT,
13557
13896
  SLIDE_CANVAS_WIDTH,
13897
+ SiwxChallengeError,
13898
+ SiwxUnsupportedError,
13558
13899
  THEME_ATTRS,
13559
13900
  VERIFY_APP_SCHEMA,
13560
13901
  applyPatches,
@@ -13568,6 +13909,7 @@ export {
13568
13909
  callNotionMCPTool,
13569
13910
  connectorMintErrorToToolResult,
13570
13911
  convertLegacyDeckJson,
13912
+ createAgentresClient,
13571
13913
  createAppCompleteBridge,
13572
13914
  createAppGenerationTools,
13573
13915
  createChartTool,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "6.22.0",
3
+ "version": "6.24.0",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",