@bananalink-test/agent 1.0.1
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.cjs +481 -0
- package/dist/index.d.cts +175 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +175 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +439 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/errors/BananalinkError.ts","../src/errors/AgentApiError.ts","../src/api/createAgentPairingRequest.ts","../src/errors/InvalidConfigError.ts","../src/errors/InvalidJwtError.ts","../src/jwt/createBananalinkJwks.ts","../src/jwt/verifyJwt.ts","../src/utils/isValidUrl.ts","../src/errors/ConnectionRejectedError.ts","../src/errors/ConnectionTimeoutError.ts","../src/errors/InvalidConnectionStateError.ts","../src/errors/PendingSessionAbortedError.ts","../src/api/createAgentMessage.ts","../src/errors/RequestRejectedError.ts","../src/errors/RequestTimeoutError.ts","../src/errors/SessionClosedError.ts","../src/core/BananalinkSession.ts","../src/core/BananalinkConnection.ts","../src/core/BananalinkAgent.ts","../src/errors/InvalidUrlError.ts","../src/utils/displayBananalinkQR.ts"],"sourcesContent":["export class BananalinkError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = 'BananalinkError';\n }\n}\n","import { BananalinkError } from './BananalinkError.js';\n\nexport class AgentApiError extends BananalinkError {\n constructor(\n message: string,\n public readonly statusCode: number,\n ) {\n super(message);\n this.name = 'AgentApiError';\n }\n}\n","import type { Agent, CreateAgentPairingResponse } from '@bananalink-test/sdk-core';\nimport { AgentApiError } from '../errors/AgentApiError.js';\n\nfunction isCreateAgentPairingResponse(body: unknown): body is CreateAgentPairingResponse {\n return typeof body === 'object' && body !== null && 'pairingCode' in body;\n}\n\nexport async function createAgentPairingRequest(apiUrl: string, params: Agent): Promise<CreateAgentPairingResponse> {\n const response = await fetch(`${apiUrl}/agents/pairings`, {\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n body: JSON.stringify(params),\n });\n if (response.ok) {\n const body = await response.json().catch(() => {\n throw new AgentApiError('Invalid JSON response from bananalink API', response.status);\n });\n if (!isCreateAgentPairingResponse(body)) {\n throw new AgentApiError('Unexpected response shape from bananalink API', response.status);\n }\n return body;\n }\n throw new AgentApiError('Failed to create agent pairing request', response.status);\n}\n","import { BananalinkError } from './BananalinkError.js';\n\nexport class InvalidConfigError extends BananalinkError {\n constructor(message: string) {\n super(message);\n this.name = 'InvalidConfigError';\n }\n}\n","import { BananalinkError } from './BananalinkError.js';\n\nexport class InvalidJwtError extends BananalinkError {\n constructor() {\n super('Invalid Bananalink agent jwt');\n }\n}\n","import { createRemoteJWKSet, type JWTVerifyGetKey } from 'jose';\n\nexport function createBananalinkJwks(apiUrl: string): JWTVerifyGetKey {\n const url = new URL(`${apiUrl}/.well-known/jwks.json`);\n return createRemoteJWKSet(url);\n}\n","import { type JWTVerifyGetKey, jwtVerify } from 'jose';\nimport type { JwtPayload } from '../types/JwtPayload.js';\n\nexport async function verifyJwt(jwt: string, jwks: JWTVerifyGetKey): Promise<JwtPayload | null> {\n try {\n const { payload } = await jwtVerify(jwt, jwks, {\n algorithms: ['ES256'],\n issuer: 'bananalink',\n requiredClaims: ['sub', 'aud'],\n });\n return {\n agentId: Array.isArray(payload.aud) ? payload.aud[0] : (payload.aud as string),\n jwt,\n };\n } catch {\n return null;\n }\n}\n","export function isValidUrl(url: string, protocols: string[]): boolean {\n try {\n const parsed = new URL(url);\n return protocols.includes(parsed.protocol.replace(':', ''));\n } catch {\n return false;\n }\n}\n","import { BananalinkError } from './BananalinkError.js';\n\nexport class ConnectionRejectedError extends BananalinkError {\n constructor() {\n super('Agent connection attempt was rejected by the hub');\n this.name = 'ConnectionRejectedError';\n }\n}\n","import { BananalinkError } from './BananalinkError.js';\n\nexport class ConnectionTimeoutError extends BananalinkError {\n constructor() {\n super('Agent connection attempt timed out');\n this.name = 'ConnectionTimeoutError';\n }\n}\n","import { BananalinkError } from './BananalinkError.js';\n\nexport class InvalidConnectionStateError extends BananalinkError {\n constructor(message: string) {\n super(message);\n this.name = 'InvalidConnectionStateError';\n }\n}\n","import { BananalinkError } from './BananalinkError.js';\n\nexport class PendingSessionAbortedError extends BananalinkError {\n constructor() {\n super('Pending session was intentionally aborted');\n this.name = 'PendingSessionAbortedError';\n }\n}\n","import { AgentApiError } from '../errors/AgentApiError.js';\n\nfunction isCreateAgentMessageResponse(body: unknown): body is { messageId: string } {\n return typeof body === 'object' && body !== null && 'messageId' in body && typeof body.messageId === 'string';\n}\n\nexport async function createAgentMessage(\n apiUrl: string,\n accessToken: string,\n params: {\n method: string;\n payload: unknown;\n },\n): Promise<{ messageId: string }> {\n const response = await fetch(`${apiUrl}/agents/messages`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(params),\n });\n if (response.ok) {\n const body = await response.json().catch(() => {\n throw new AgentApiError('Invalid JSON response from bananalink API', response.status);\n });\n if (!isCreateAgentMessageResponse(body)) {\n throw new AgentApiError('Unexpected response shape from bananalink API', response.status);\n }\n return body;\n }\n throw new AgentApiError('Failed to create agent message', response.status);\n}\n","import { BananalinkError } from './BananalinkError.js';\n\nexport class RequestRejectedError extends BananalinkError {\n constructor(public readonly messageId: string) {\n super(`Request rejected by hub (messageId: ${messageId})`);\n this.name = 'RequestRejectedError';\n }\n}\n","import type { Request } from '../types/Request.js';\nimport { BananalinkError } from './BananalinkError.js';\n\nexport class RequestTimeoutError extends BananalinkError {\n constructor(public readonly method: Request) {\n super(`Timeout reached for request ${method}`);\n }\n}\n","import { BananalinkError } from './BananalinkError.js';\n\nexport class SessionClosedError extends BananalinkError {\n constructor() {\n super('Session is closed');\n }\n}\n","import {\n isMessageResponseMessage,\n type MessageResponseMessage,\n type TransportHandle,\n withBackoff,\n} from '@bananalink-test/sdk-core';\nimport { createAgentMessage } from '../api/createAgentMessage.js';\nimport { BananalinkError } from '../errors/BananalinkError.js';\nimport { RequestRejectedError } from '../errors/RequestRejectedError.js';\nimport { RequestTimeoutError } from '../errors/RequestTimeoutError.js';\nimport { SessionClosedError } from '../errors/SessionClosedError.js';\nimport type { PendingMessageRequest } from '../types/PendingMessageRequest.js';\nimport type { Request } from '../types/Request.js';\nimport type { RequestParams } from '../types/RequestParams.js';\nimport type { RequestResult } from '../types/RequestResult.js';\nimport type { RequestResultHandler } from '../types/RequestResultHandler.js';\nimport type { SessionClaims } from '../types/SessionClaims.js';\n\nexport class BananalinkSession {\n private static readonly REQUEST_TIMEOUT_MS = 10 * 60 * 1000;\n private static readonly CREATE_DAPP_MESSAGE_MAX_ATTEMPTS = 3;\n private static readonly CREATE_DAPP_MESSAGE_BASE_DELAY_MS = 1000;\n private readonly pendingRequests = new Map<string, PendingMessageRequest>();\n private readonly stopListening: () => void;\n private readonly stopListeningOnClose: () => void;\n private closed: boolean;\n\n private static readonly RESULT_HANDLERS: { [T in Request]: RequestResultHandler<T> } = {\n eth_sendTransaction: (result) => {\n if (typeof result === 'object' && result !== null && 'txHash' in result && typeof result.txHash === 'string') {\n return result.txHash;\n }\n throw new BananalinkError(`Unexpected eth_sendTransaction result: ${result}`);\n },\n };\n\n constructor(\n public readonly sessionClaims: SessionClaims,\n private readonly ws: TransportHandle,\n private readonly apiUrl: string,\n ) {\n this.stopListening = this.ws.onMessage((payload) => {\n if (isMessageResponseMessage(payload)) {\n this.handleMessageResponse(payload);\n }\n });\n this.stopListeningOnClose = this.ws.onClose(() => {\n this.cleanup();\n this.closed = true;\n });\n this.closed = false;\n }\n\n public async request<T extends Request>({\n method,\n params,\n timeoutMs = BananalinkSession.REQUEST_TIMEOUT_MS,\n }: {\n method: T;\n params?: RequestParams<T>;\n timeoutMs?: number;\n }): Promise<RequestResult<T>> {\n if (this.closed) {\n throw new SessionClosedError();\n }\n\n const { messageId } = await withBackoff(\n async () =>\n await createAgentMessage(this.apiUrl, this.sessionClaims.accessToken, {\n method,\n payload: params,\n }),\n BananalinkSession.CREATE_DAPP_MESSAGE_MAX_ATTEMPTS,\n BananalinkSession.CREATE_DAPP_MESSAGE_BASE_DELAY_MS,\n );\n\n if (this.closed) {\n throw new SessionClosedError();\n }\n\n return new Promise<RequestResult<T>>((resolve, reject) => {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n if (timeoutMs > 0) {\n timeout = setTimeout(() => {\n this.pendingRequests.delete(messageId);\n reject(new RequestTimeoutError(method));\n }, timeoutMs);\n }\n\n this.pendingRequests.set(messageId, {\n timeout,\n handle: (messageResponse: MessageResponseMessage) => {\n if (messageResponse.status === 'rejected') {\n reject(new RequestRejectedError(messageId));\n return;\n }\n const resultHandler = BananalinkSession.RESULT_HANDLERS[method];\n try {\n resolve(resultHandler(messageResponse.payloadResponse));\n } catch (error: unknown) {\n reject(new BananalinkError(`Failed resolving request response, ${error}`));\n }\n },\n reject,\n });\n });\n }\n\n public close(): void {\n this.cleanup();\n if (!this.ws.closed) {\n this.ws.close();\n }\n this.closed = true;\n }\n\n private handleMessageResponse(messageResponseMessage: MessageResponseMessage): void {\n const pending = this.pendingRequests.get(messageResponseMessage.msgId);\n if (!pending) return;\n\n this.pendingRequests.delete(messageResponseMessage.msgId);\n clearTimeout(pending.timeout);\n pending.handle(messageResponseMessage);\n }\n\n private cleanup(): void {\n this.rejectAllPendingRequests();\n this.stopListening();\n this.stopListeningOnClose();\n }\n\n private rejectAllPendingRequests(): void {\n for (const [, pending] of this.pendingRequests) {\n clearTimeout(pending.timeout);\n // TODO: propagate error or throw generic one\n pending.reject(new Error('Pending requests rejected'));\n }\n this.pendingRequests.clear();\n }\n}\n","import {\n type AuthorizedMessage,\n BindTransportError,\n bindTransport,\n connectWebSocket,\n createReconnectingTransport,\n isAuthorizedMessage,\n isRejectedMessage,\n type TransportHandle,\n waitForTransportEvent,\n} from '@bananalink-test/sdk-core';\nimport { BananalinkError } from '../errors/BananalinkError.js';\nimport { ConnectionRejectedError } from '../errors/ConnectionRejectedError.js';\nimport { ConnectionTimeoutError } from '../errors/ConnectionTimeoutError.js';\nimport { InvalidConnectionStateError } from '../errors/InvalidConnectionStateError.js';\nimport { InvalidJwtError } from '../errors/InvalidJwtError.js';\nimport { PendingSessionAbortedError } from '../errors/PendingSessionAbortedError.js';\nimport type { JwtPayload } from '../types/JwtPayload.js';\nimport type { SessionClaims } from '../types/SessionClaims.js';\nimport { BananalinkSession } from './BananalinkSession.js';\n\ntype BananalinkAgentJwt = { jwtPayload: JwtPayload; accessToken: string } | undefined;\n\nexport class BananalinkConnection {\n private static readonly AUTH_TIMEOUT_MILLIS = 10 * 60 * 1000;\n private static readonly BIND_RESPONSE_TIMEOUT_MILLIS = 20 * 1000;\n private readonly apiUrl: string;\n private readonly wsUrl: string;\n private readonly jwt: BananalinkAgentJwt;\n private readonly agentPairingCode: string | null;\n private pendingSessionPromise: Promise<BananalinkSession> | null = null;\n private pendingSessionAbortController: AbortController | null = null;\n\n constructor(opts: {\n apiUrl: string;\n wsUrl: string;\n jwt: BananalinkAgentJwt;\n agentPairingCode: string | null;\n }) {\n this.apiUrl = opts.apiUrl;\n this.wsUrl = opts.wsUrl;\n this.jwt = opts.jwt;\n this.agentPairingCode = opts.agentPairingCode;\n if (!this.agentPairingCode && !this.jwt) {\n throw new InvalidConnectionStateError('Cannot get session without authorizing agent or providing a valid JWT');\n }\n }\n\n public get connectionUrl(): string {\n if (!this.agentPairingCode) {\n throw new InvalidConnectionStateError('Cannot get connection URL without a pairing code');\n }\n return `bananalink://?code=${encodeURIComponent(this.agentPairingCode)}`;\n }\n\n public abortPendingSession(): void {\n this.pendingSessionAbortController?.abort();\n }\n\n public async getSession(): Promise<BananalinkSession> {\n if (this.pendingSessionPromise) {\n return this.pendingSessionPromise;\n }\n this.pendingSessionAbortController = new AbortController();\n this.pendingSessionPromise = (\n this.jwt\n ? this.resumeSession(this.jwt, this.pendingSessionAbortController.signal)\n : this.waitForAuthorization(this.pendingSessionAbortController.signal)\n ).finally(() => {\n this.pendingSessionPromise = null;\n this.pendingSessionAbortController = null;\n });\n return this.pendingSessionPromise;\n }\n\n private async openSession(\n getSessionClaims: (transportHandle: TransportHandle) => Promise<SessionClaims>,\n abortSignal: AbortSignal,\n ) {\n const transportHandle = await this.getTransportHandle(this.agentPairingCode);\n const onAbort = (): void => transportHandle.close();\n abortSignal.addEventListener('abort', onAbort, { once: true });\n if (abortSignal.aborted) {\n transportHandle.close();\n throw new PendingSessionAbortedError();\n }\n try {\n const sessionClaims = await getSessionClaims(transportHandle);\n await this.bind(transportHandle, sessionClaims.accessToken, abortSignal);\n const transport = createReconnectingTransport(transportHandle, {\n reconnectTransport: async () => this.getTransportHandle(null),\n onReconnect: async (th) => this.bind(th, sessionClaims.accessToken),\n maxReconnectAttempts: 5,\n baseDelayReconnectMs: 1000,\n });\n return new BananalinkSession(sessionClaims, transport, this.apiUrl);\n } catch (error) {\n transportHandle.close();\n throw error;\n } finally {\n abortSignal.removeEventListener('abort', onAbort);\n }\n }\n\n private async resumeSession(\n jwt: NonNullable<BananalinkAgentJwt>,\n abortSignal: AbortSignal,\n ): Promise<BananalinkSession> {\n return await this.openSession(async () => ({ ...jwt.jwtPayload, accessToken: jwt.accessToken }), abortSignal);\n }\n\n private async waitForAuthorization(abortSignal: AbortSignal): Promise<BananalinkSession> {\n return await this.openSession(\n async (transportHandle: TransportHandle) =>\n await waitForTransportEvent<AuthorizedMessage>(transportHandle, {\n onMessage: (payload, resolve, reject) => {\n if (isAuthorizedMessage(payload)) resolve(payload);\n if (isRejectedMessage(payload)) reject(new ConnectionRejectedError());\n },\n timeoutMs: BananalinkConnection.AUTH_TIMEOUT_MILLIS,\n createTimeoutError: () => new ConnectionTimeoutError(),\n createClosedError: () => new BananalinkError('Connection closed unexpectedly'),\n abortSignal,\n createAbortError: () => new PendingSessionAbortedError(),\n }),\n abortSignal,\n );\n }\n\n private async getTransportHandle(agentPairingCode?: string | null): Promise<TransportHandle> {\n const url = `${this.wsUrl}${agentPairingCode != null ? `?code=${encodeURIComponent(agentPairingCode)}` : ''}`;\n try {\n return await connectWebSocket({\n url,\n pingIntervalMs: 30_000,\n pongTimeoutMs: 5_000,\n maxReconnectAttempts: 0,\n });\n } catch (error) {\n throw new BananalinkError('Unable to establish agent websocket connection', { cause: error });\n }\n }\n\n private async bind(ws: TransportHandle, accessToken: string, abortSignal?: AbortSignal): Promise<void> {\n try {\n await bindTransport(ws, accessToken, {\n timeoutMs: BananalinkConnection.BIND_RESPONSE_TIMEOUT_MILLIS,\n createTimeoutError: () => new ConnectionTimeoutError(),\n createClosedError: () => new BananalinkError('Connection closed unexpectedly'),\n abortSignal,\n createAbortError: () => new PendingSessionAbortedError(),\n });\n } catch (error) {\n if (error instanceof BindTransportError) {\n throw new InvalidJwtError();\n }\n throw error;\n }\n }\n}\n","import type { Agent, CreateAgentPairingResponse } from '@bananalink-test/sdk-core';\nimport { createAgentPairingRequest } from '../api/createAgentPairingRequest.js';\nimport { InvalidConfigError } from '../errors/InvalidConfigError.js';\nimport { InvalidJwtError } from '../errors/InvalidJwtError.js';\nimport { createBananalinkJwks } from '../jwt/createBananalinkJwks.js';\nimport { verifyJwt } from '../jwt/verifyJwt.js';\nimport type { ConnectOpts } from '../types/ConnectOpts.js';\nimport type { JwtPayload } from '../types/JwtPayload.js';\nimport { isValidUrl } from '../utils/isValidUrl.js';\nimport { BananalinkConnection } from './BananalinkConnection.js';\n\nexport class BananalinkAgent {\n private readonly apiUrl: string;\n private readonly wsUrl: string;\n private readonly jwks: ReturnType<typeof createBananalinkJwks>;\n private readonly agent: Agent;\n private static readonly DEFAULT_BANANALINK_API_URL = 'https://api.dev.banana.link';\n private static readonly DEFAULT_BANANALINK_WS_URL = 'wss://ws.dev.banana.link';\n\n constructor(config: {\n apiUrl?: string;\n wsUrl?: string;\n agent: Agent;\n }) {\n this.apiUrl = config.apiUrl ?? BananalinkAgent.DEFAULT_BANANALINK_API_URL;\n this.wsUrl = config.wsUrl ?? BananalinkAgent.DEFAULT_BANANALINK_WS_URL;\n if (!isValidUrl(this.apiUrl, ['http', 'https'])) {\n throw new InvalidConfigError(`Invalid apiUrl: \"${this.apiUrl}\". Must use http or https.`);\n }\n if (!isValidUrl(this.wsUrl, ['ws', 'wss'])) {\n throw new InvalidConfigError(`Invalid wsUrl: \"${this.wsUrl}\". Must use ws or wss.`);\n }\n this.agent = config.agent;\n this.jwks = createBananalinkJwks(this.apiUrl);\n }\n\n public async connect(opts?: ConnectOpts): Promise<BananalinkConnection> {\n const accessToken = opts?.accessToken;\n if (!accessToken) {\n const { pairingCode } = await this.pairAgent();\n return new BananalinkConnection({\n jwt: undefined,\n agentPairingCode: pairingCode,\n apiUrl: this.apiUrl,\n wsUrl: this.wsUrl,\n });\n }\n\n const jwtPayload = await this.getJwtPayload(accessToken);\n if (!jwtPayload) {\n throw new InvalidJwtError();\n }\n\n return new BananalinkConnection({\n jwt: { jwtPayload, accessToken },\n agentPairingCode: null,\n apiUrl: this.apiUrl,\n wsUrl: this.wsUrl,\n });\n }\n\n private async getJwtPayload(accessToken: string): Promise<JwtPayload | null> {\n return await verifyJwt(accessToken, this.jwks);\n }\n\n private async pairAgent(): Promise<CreateAgentPairingResponse> {\n return await createAgentPairingRequest(this.apiUrl, this.agent);\n }\n}\n","import { BananalinkError } from './BananalinkError.js';\n\nexport class InvalidUrlError extends BananalinkError {\n constructor(public readonly url: string) {\n super(`${url} is not a valid url`);\n }\n}\n","import QRCode from 'qrcode';\nimport { InvalidUrlError } from '../errors/InvalidUrlError.js';\nimport { isValidUrl } from './isValidUrl.js';\n\nexport async function displayBananalinkQR(url: string): Promise<string> {\n if (!isValidUrl(url, ['bananalink'])) {\n throw new InvalidUrlError(url);\n }\n return QRCode.toDataURL(url);\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bananalink-test/agent",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": {
|
|
10
|
+
"types": "./dist/index.d.mts",
|
|
11
|
+
"default": "./dist/index.mjs"
|
|
12
|
+
},
|
|
13
|
+
"require": {
|
|
14
|
+
"types": "./dist/index.d.cts",
|
|
15
|
+
"default": "./dist/index.cjs"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"main": "./dist/index.cjs",
|
|
20
|
+
"module": "./dist/index.mjs",
|
|
21
|
+
"types": "./dist/index.d.mts",
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@biomejs/biome": "2.3.15",
|
|
30
|
+
"@types/qrcode": "^1.5.6",
|
|
31
|
+
"tsdown": "^0.20.3",
|
|
32
|
+
"typescript": "^5.9.3",
|
|
33
|
+
"vitest": "^4.0.18"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"jose": "^6.1.3",
|
|
37
|
+
"qrcode": "^1.5.4",
|
|
38
|
+
"@bananalink-test/sdk-core": "0.8.1"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsdown",
|
|
42
|
+
"type-check": "tsc --noEmit",
|
|
43
|
+
"lint": "biome check .",
|
|
44
|
+
"dev": "tsdown --watch",
|
|
45
|
+
"test": "vitest run"
|
|
46
|
+
}
|
|
47
|
+
}
|