@byoky/sdk 0.1.0 → 0.2.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.cjs CHANGED
@@ -69,9 +69,8 @@ function createProxyFetch(providerId, sessionKey) {
69
69
  cleanup();
70
70
  reject(new Error("Proxy request timed out"));
71
71
  }, 12e4);
72
- function handleMessage(event) {
73
- if (event.source !== window) return;
74
- const data = event.data;
72
+ function handleEvent(event) {
73
+ const data = event.detail ?? event.data;
75
74
  if (data?.requestId !== requestId) return;
76
75
  switch (data.type) {
77
76
  case "BYOKY_PROXY_RESPONSE_META":
@@ -118,9 +117,9 @@ function createProxyFetch(providerId, sessionKey) {
118
117
  }
119
118
  function cleanup() {
120
119
  clearTimeout(timeout);
121
- window.removeEventListener("message", handleMessage);
120
+ document.removeEventListener("byoky-message", handleEvent);
122
121
  }
123
- window.addEventListener("message", handleMessage);
122
+ document.addEventListener("byoky-message", handleEvent);
124
123
  window.postMessage(
125
124
  {
126
125
  type: "BYOKY_PROXY_REQUEST",
@@ -192,10 +191,9 @@ var Byoky = class {
192
191
  new import_core2.ByokyError(import_core2.ByokyErrorCode.UNKNOWN, "Connection request timed out")
193
192
  );
194
193
  }, this.timeout);
195
- function handleMessage(event) {
196
- if (event.source !== window) return;
197
- if (!(0, import_core2.isByokyMessage)(event.data)) return;
198
- const msg = event.data;
194
+ function handleEvent(event) {
195
+ const msg = event.detail;
196
+ if (typeof msg?.type !== "string" || !msg.type.startsWith("BYOKY_")) return;
199
197
  if (msg.requestId !== requestId) return;
200
198
  cleanup();
201
199
  if (msg.type === "BYOKY_CONNECT_RESPONSE") {
@@ -207,9 +205,9 @@ var Byoky = class {
207
205
  }
208
206
  function cleanup() {
209
207
  clearTimeout(timeoutId);
210
- window.removeEventListener("message", handleMessage);
208
+ document.removeEventListener("byoky-message", handleEvent);
211
209
  }
212
- window.addEventListener("message", handleMessage);
210
+ document.addEventListener("byoky-message", handleEvent);
213
211
  window.postMessage(
214
212
  {
215
213
  type: "BYOKY_CONNECT_REQUEST",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/byoky.ts","../src/detect.ts","../src/proxy-fetch.ts"],"sourcesContent":["export { Byoky } from './byoky.js';\nexport type { ByokySession, ByokyOptions } from './byoky.js';\nexport { isExtensionInstalled, getStoreUrl } from './detect.js';\nexport { createProxyFetch } from './proxy-fetch.js';\nexport {\n type ConnectRequest,\n type ConnectResponse,\n type ProviderRequirement,\n ByokyError,\n ByokyErrorCode,\n} from '@byoky/core';\n","import type { ConnectRequest, ConnectResponse } from '@byoky/core';\nimport { ByokyError, ByokyErrorCode, isByokyMessage } from '@byoky/core';\nimport { isExtensionInstalled, getStoreUrl } from './detect.js';\nimport { createProxyFetch } from './proxy-fetch.js';\n\nexport interface ByokySession extends ConnectResponse {\n createFetch(providerId: string): typeof fetch;\n disconnect(): void;\n}\n\nexport interface ByokyOptions {\n timeout?: number;\n}\n\nexport class Byoky {\n private timeout: number;\n\n constructor(options: ByokyOptions = {}) {\n this.timeout = options.timeout ?? 60_000;\n }\n\n async connect(request: ConnectRequest = {}): Promise<ByokySession> {\n if (!isExtensionInstalled()) {\n const storeUrl = getStoreUrl();\n if (storeUrl) {\n window.open(storeUrl, '_blank');\n }\n throw ByokyError.walletNotInstalled();\n }\n\n const response = await this.sendConnectRequest(request);\n\n return {\n ...response,\n createFetch: (providerId: string) =>\n createProxyFetch(providerId, response.sessionKey),\n disconnect: () => this.disconnect(response.sessionKey),\n };\n }\n\n private sendConnectRequest(\n request: ConnectRequest,\n ): Promise<ConnectResponse> {\n return new Promise<ConnectResponse>((resolve, reject) => {\n const requestId = crypto.randomUUID();\n\n const timeoutId = setTimeout(() => {\n cleanup();\n reject(\n new ByokyError(ByokyErrorCode.UNKNOWN, 'Connection request timed out'),\n );\n }, this.timeout);\n\n function handleMessage(event: MessageEvent) {\n if (event.source !== window) return;\n if (!isByokyMessage(event.data)) return;\n\n const msg = event.data;\n if (msg.requestId !== requestId) return;\n\n cleanup();\n\n if (msg.type === 'BYOKY_CONNECT_RESPONSE') {\n resolve(msg.payload as ConnectResponse);\n } else if (msg.type === 'BYOKY_ERROR') {\n const { code, message } = msg.payload as {\n code: string;\n message: string;\n };\n reject(new ByokyError(code as ByokyErrorCode, message));\n }\n }\n\n function cleanup() {\n clearTimeout(timeoutId);\n window.removeEventListener('message', handleMessage);\n }\n\n window.addEventListener('message', handleMessage);\n\n window.postMessage(\n {\n type: 'BYOKY_CONNECT_REQUEST',\n id: requestId,\n requestId,\n payload: request,\n },\n '*',\n );\n });\n }\n\n private disconnect(sessionKey: string): void {\n window.postMessage(\n { type: 'BYOKY_DISCONNECT', payload: { sessionKey } },\n '*',\n );\n }\n}\n","import { BYOKY_PROVIDER_KEY } from '@byoky/core';\n\nexport function isExtensionInstalled(): boolean {\n return typeof window !== 'undefined' && BYOKY_PROVIDER_KEY in window;\n}\n\nexport function getStoreUrl(): string | null {\n if (typeof navigator === 'undefined') return null;\n\n const ua = navigator.userAgent.toLowerCase();\n\n if (ua.includes('chrome') && !ua.includes('edg')) {\n return 'https://chrome.google.com/webstore/detail/byoky/TODO_EXTENSION_ID';\n }\n if (ua.includes('firefox')) {\n return 'https://addons.mozilla.org/en-US/firefox/addon/byoky/';\n }\n if (ua.includes('safari') && !ua.includes('chrome')) {\n return 'https://apps.apple.com/app/byoky/TODO_APP_ID';\n }\n return null;\n}\n","export function createProxyFetch(\n providerId: string,\n sessionKey: string,\n): typeof fetch {\n return async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const url =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n\n const method = init?.method ?? 'GET';\n const headers = init?.headers\n ? Object.fromEntries(new Headers(init.headers).entries())\n : {};\n const body = init?.body ? await readBody(init.body) : undefined;\n\n const requestId = crypto.randomUUID();\n\n return new Promise<Response>((resolve, reject) => {\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n let resolved = false;\n\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error('Proxy request timed out'));\n }, 120_000);\n\n function handleMessage(event: MessageEvent) {\n if (event.source !== window) return;\n const data = event.data;\n if (data?.requestId !== requestId) return;\n\n switch (data.type) {\n case 'BYOKY_PROXY_RESPONSE_META':\n if (!resolved) {\n resolved = true;\n clearTimeout(timeout);\n resolve(\n new Response(readable, {\n status: data.status,\n statusText: data.statusText,\n headers: new Headers(data.headers),\n }),\n );\n }\n break;\n\n case 'BYOKY_PROXY_RESPONSE_CHUNK':\n writer.write(encoder.encode(data.chunk)).catch(() => {});\n break;\n\n case 'BYOKY_PROXY_RESPONSE_DONE':\n writer.close().catch(() => {});\n cleanup();\n break;\n\n case 'BYOKY_PROXY_RESPONSE_ERROR': {\n const errResponse = new Response(\n JSON.stringify({ error: data.error }),\n {\n status: data.status || 500,\n headers: { 'content-type': 'application/json' },\n },\n );\n if (!resolved) {\n resolved = true;\n clearTimeout(timeout);\n resolve(errResponse);\n }\n writer.close().catch(() => {});\n cleanup();\n break;\n }\n }\n }\n\n function cleanup() {\n clearTimeout(timeout);\n window.removeEventListener('message', handleMessage);\n }\n\n window.addEventListener('message', handleMessage);\n\n window.postMessage(\n {\n type: 'BYOKY_PROXY_REQUEST',\n requestId,\n sessionKey,\n providerId,\n url,\n method,\n headers,\n body,\n },\n '*',\n );\n });\n };\n}\n\nasync function readBody(body: BodyInit): Promise<string | undefined> {\n if (typeof body === 'string') return body;\n if (body instanceof ArrayBuffer) return new TextDecoder().decode(body);\n if (body instanceof Blob) return body.text();\n if (body instanceof URLSearchParams) return body.toString();\n if (body instanceof ReadableStream) {\n const reader = body.getReader();\n const chunks: Uint8Array[] = [];\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n const total = chunks.reduce((acc, c) => acc + c.length, 0);\n const combined = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n return new TextDecoder().decode(combined);\n }\n return undefined;\n}\n"],"mappings":"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","names":["import_core","import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/byoky.ts","../src/detect.ts","../src/proxy-fetch.ts"],"sourcesContent":["export { Byoky } from './byoky.js';\nexport type { ByokySession, ByokyOptions } from './byoky.js';\nexport { isExtensionInstalled, getStoreUrl } from './detect.js';\nexport { createProxyFetch } from './proxy-fetch.js';\nexport {\n type ConnectRequest,\n type ConnectResponse,\n type ProviderRequirement,\n ByokyError,\n ByokyErrorCode,\n} from '@byoky/core';\n","import type { ConnectRequest, ConnectResponse } from '@byoky/core';\nimport { ByokyError, ByokyErrorCode, isByokyMessage } from '@byoky/core';\nimport { isExtensionInstalled, getStoreUrl } from './detect.js';\nimport { createProxyFetch } from './proxy-fetch.js';\n\nexport interface ByokySession extends ConnectResponse {\n createFetch(providerId: string): typeof fetch;\n disconnect(): void;\n}\n\nexport interface ByokyOptions {\n timeout?: number;\n}\n\nexport class Byoky {\n private timeout: number;\n\n constructor(options: ByokyOptions = {}) {\n this.timeout = options.timeout ?? 60_000;\n }\n\n async connect(request: ConnectRequest = {}): Promise<ByokySession> {\n if (!isExtensionInstalled()) {\n const storeUrl = getStoreUrl();\n if (storeUrl) {\n window.open(storeUrl, '_blank');\n }\n throw ByokyError.walletNotInstalled();\n }\n\n const response = await this.sendConnectRequest(request);\n\n return {\n ...response,\n createFetch: (providerId: string) =>\n createProxyFetch(providerId, response.sessionKey),\n disconnect: () => this.disconnect(response.sessionKey),\n };\n }\n\n private sendConnectRequest(\n request: ConnectRequest,\n ): Promise<ConnectResponse> {\n return new Promise<ConnectResponse>((resolve, reject) => {\n const requestId = crypto.randomUUID();\n\n const timeoutId = setTimeout(() => {\n cleanup();\n reject(\n new ByokyError(ByokyErrorCode.UNKNOWN, 'Connection request timed out'),\n );\n }, this.timeout);\n\n function handleEvent(event: Event) {\n const msg = (event as CustomEvent).detail;\n if (typeof msg?.type !== 'string' || !msg.type.startsWith('BYOKY_')) return;\n if (msg.requestId !== requestId) return;\n\n cleanup();\n\n if (msg.type === 'BYOKY_CONNECT_RESPONSE') {\n resolve(msg.payload as ConnectResponse);\n } else if (msg.type === 'BYOKY_ERROR') {\n const { code, message } = msg.payload as {\n code: string;\n message: string;\n };\n reject(new ByokyError(code as ByokyErrorCode, message));\n }\n }\n\n function cleanup() {\n clearTimeout(timeoutId);\n document.removeEventListener('byoky-message', handleEvent);\n }\n\n document.addEventListener('byoky-message', handleEvent);\n\n window.postMessage(\n {\n type: 'BYOKY_CONNECT_REQUEST',\n id: requestId,\n requestId,\n payload: request,\n },\n '*',\n );\n });\n }\n\n private disconnect(sessionKey: string): void {\n window.postMessage(\n { type: 'BYOKY_DISCONNECT', payload: { sessionKey } },\n '*',\n );\n }\n}\n","import { BYOKY_PROVIDER_KEY } from '@byoky/core';\n\nexport function isExtensionInstalled(): boolean {\n return typeof window !== 'undefined' && BYOKY_PROVIDER_KEY in window;\n}\n\nexport function getStoreUrl(): string | null {\n if (typeof navigator === 'undefined') return null;\n\n const ua = navigator.userAgent.toLowerCase();\n\n if (ua.includes('chrome') && !ua.includes('edg')) {\n return 'https://chrome.google.com/webstore/detail/byoky/TODO_EXTENSION_ID';\n }\n if (ua.includes('firefox')) {\n return 'https://addons.mozilla.org/en-US/firefox/addon/byoky/';\n }\n if (ua.includes('safari') && !ua.includes('chrome')) {\n return 'https://apps.apple.com/app/byoky/TODO_APP_ID';\n }\n return null;\n}\n","export function createProxyFetch(\n providerId: string,\n sessionKey: string,\n): typeof fetch {\n return async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const url =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n\n const method = init?.method ?? 'GET';\n const headers = init?.headers\n ? Object.fromEntries(new Headers(init.headers).entries())\n : {};\n const body = init?.body ? await readBody(init.body) : undefined;\n\n const requestId = crypto.randomUUID();\n\n return new Promise<Response>((resolve, reject) => {\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n let resolved = false;\n\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error('Proxy request timed out'));\n }, 120_000);\n\n function handleEvent(event: Event) {\n const data = (event as CustomEvent).detail ?? (event as MessageEvent).data;\n if (data?.requestId !== requestId) return;\n\n switch (data.type) {\n case 'BYOKY_PROXY_RESPONSE_META':\n if (!resolved) {\n resolved = true;\n clearTimeout(timeout);\n resolve(\n new Response(readable, {\n status: data.status,\n statusText: data.statusText,\n headers: new Headers(data.headers),\n }),\n );\n }\n break;\n\n case 'BYOKY_PROXY_RESPONSE_CHUNK':\n writer.write(encoder.encode(data.chunk)).catch(() => {});\n break;\n\n case 'BYOKY_PROXY_RESPONSE_DONE':\n writer.close().catch(() => {});\n cleanup();\n break;\n\n case 'BYOKY_PROXY_RESPONSE_ERROR': {\n const errResponse = new Response(\n JSON.stringify({ error: data.error }),\n {\n status: data.status || 500,\n headers: { 'content-type': 'application/json' },\n },\n );\n if (!resolved) {\n resolved = true;\n clearTimeout(timeout);\n resolve(errResponse);\n }\n writer.close().catch(() => {});\n cleanup();\n break;\n }\n }\n }\n\n function cleanup() {\n clearTimeout(timeout);\n document.removeEventListener('byoky-message', handleEvent);\n }\n\n document.addEventListener('byoky-message', handleEvent);\n\n window.postMessage(\n {\n type: 'BYOKY_PROXY_REQUEST',\n requestId,\n sessionKey,\n providerId,\n url,\n method,\n headers,\n body,\n },\n '*',\n );\n });\n };\n}\n\nasync function readBody(body: BodyInit): Promise<string | undefined> {\n if (typeof body === 'string') return body;\n if (body instanceof ArrayBuffer) return new TextDecoder().decode(body);\n if (body instanceof Blob) return body.text();\n if (body instanceof URLSearchParams) return body.toString();\n if (body instanceof ReadableStream) {\n const reader = body.getReader();\n const chunks: Uint8Array[] = [];\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n const total = chunks.reduce((acc, c) => acc + c.length, 0);\n const combined = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n return new TextDecoder().decode(combined);\n }\n return undefined;\n}\n"],"mappings":"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","names":["import_core","import_core"]}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/byoky.ts
2
- import { ByokyError, ByokyErrorCode, isByokyMessage } from "@byoky/core";
2
+ import { ByokyError, ByokyErrorCode } from "@byoky/core";
3
3
 
4
4
  // src/detect.ts
5
5
  import { BYOKY_PROVIDER_KEY } from "@byoky/core";
@@ -38,9 +38,8 @@ function createProxyFetch(providerId, sessionKey) {
38
38
  cleanup();
39
39
  reject(new Error("Proxy request timed out"));
40
40
  }, 12e4);
41
- function handleMessage(event) {
42
- if (event.source !== window) return;
43
- const data = event.data;
41
+ function handleEvent(event) {
42
+ const data = event.detail ?? event.data;
44
43
  if (data?.requestId !== requestId) return;
45
44
  switch (data.type) {
46
45
  case "BYOKY_PROXY_RESPONSE_META":
@@ -87,9 +86,9 @@ function createProxyFetch(providerId, sessionKey) {
87
86
  }
88
87
  function cleanup() {
89
88
  clearTimeout(timeout);
90
- window.removeEventListener("message", handleMessage);
89
+ document.removeEventListener("byoky-message", handleEvent);
91
90
  }
92
- window.addEventListener("message", handleMessage);
91
+ document.addEventListener("byoky-message", handleEvent);
93
92
  window.postMessage(
94
93
  {
95
94
  type: "BYOKY_PROXY_REQUEST",
@@ -161,10 +160,9 @@ var Byoky = class {
161
160
  new ByokyError(ByokyErrorCode.UNKNOWN, "Connection request timed out")
162
161
  );
163
162
  }, this.timeout);
164
- function handleMessage(event) {
165
- if (event.source !== window) return;
166
- if (!isByokyMessage(event.data)) return;
167
- const msg = event.data;
163
+ function handleEvent(event) {
164
+ const msg = event.detail;
165
+ if (typeof msg?.type !== "string" || !msg.type.startsWith("BYOKY_")) return;
168
166
  if (msg.requestId !== requestId) return;
169
167
  cleanup();
170
168
  if (msg.type === "BYOKY_CONNECT_RESPONSE") {
@@ -176,9 +174,9 @@ var Byoky = class {
176
174
  }
177
175
  function cleanup() {
178
176
  clearTimeout(timeoutId);
179
- window.removeEventListener("message", handleMessage);
177
+ document.removeEventListener("byoky-message", handleEvent);
180
178
  }
181
- window.addEventListener("message", handleMessage);
179
+ document.addEventListener("byoky-message", handleEvent);
182
180
  window.postMessage(
183
181
  {
184
182
  type: "BYOKY_CONNECT_REQUEST",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/byoky.ts","../src/detect.ts","../src/proxy-fetch.ts","../src/index.ts"],"sourcesContent":["import type { ConnectRequest, ConnectResponse } from '@byoky/core';\nimport { ByokyError, ByokyErrorCode, isByokyMessage } from '@byoky/core';\nimport { isExtensionInstalled, getStoreUrl } from './detect.js';\nimport { createProxyFetch } from './proxy-fetch.js';\n\nexport interface ByokySession extends ConnectResponse {\n createFetch(providerId: string): typeof fetch;\n disconnect(): void;\n}\n\nexport interface ByokyOptions {\n timeout?: number;\n}\n\nexport class Byoky {\n private timeout: number;\n\n constructor(options: ByokyOptions = {}) {\n this.timeout = options.timeout ?? 60_000;\n }\n\n async connect(request: ConnectRequest = {}): Promise<ByokySession> {\n if (!isExtensionInstalled()) {\n const storeUrl = getStoreUrl();\n if (storeUrl) {\n window.open(storeUrl, '_blank');\n }\n throw ByokyError.walletNotInstalled();\n }\n\n const response = await this.sendConnectRequest(request);\n\n return {\n ...response,\n createFetch: (providerId: string) =>\n createProxyFetch(providerId, response.sessionKey),\n disconnect: () => this.disconnect(response.sessionKey),\n };\n }\n\n private sendConnectRequest(\n request: ConnectRequest,\n ): Promise<ConnectResponse> {\n return new Promise<ConnectResponse>((resolve, reject) => {\n const requestId = crypto.randomUUID();\n\n const timeoutId = setTimeout(() => {\n cleanup();\n reject(\n new ByokyError(ByokyErrorCode.UNKNOWN, 'Connection request timed out'),\n );\n }, this.timeout);\n\n function handleMessage(event: MessageEvent) {\n if (event.source !== window) return;\n if (!isByokyMessage(event.data)) return;\n\n const msg = event.data;\n if (msg.requestId !== requestId) return;\n\n cleanup();\n\n if (msg.type === 'BYOKY_CONNECT_RESPONSE') {\n resolve(msg.payload as ConnectResponse);\n } else if (msg.type === 'BYOKY_ERROR') {\n const { code, message } = msg.payload as {\n code: string;\n message: string;\n };\n reject(new ByokyError(code as ByokyErrorCode, message));\n }\n }\n\n function cleanup() {\n clearTimeout(timeoutId);\n window.removeEventListener('message', handleMessage);\n }\n\n window.addEventListener('message', handleMessage);\n\n window.postMessage(\n {\n type: 'BYOKY_CONNECT_REQUEST',\n id: requestId,\n requestId,\n payload: request,\n },\n '*',\n );\n });\n }\n\n private disconnect(sessionKey: string): void {\n window.postMessage(\n { type: 'BYOKY_DISCONNECT', payload: { sessionKey } },\n '*',\n );\n }\n}\n","import { BYOKY_PROVIDER_KEY } from '@byoky/core';\n\nexport function isExtensionInstalled(): boolean {\n return typeof window !== 'undefined' && BYOKY_PROVIDER_KEY in window;\n}\n\nexport function getStoreUrl(): string | null {\n if (typeof navigator === 'undefined') return null;\n\n const ua = navigator.userAgent.toLowerCase();\n\n if (ua.includes('chrome') && !ua.includes('edg')) {\n return 'https://chrome.google.com/webstore/detail/byoky/TODO_EXTENSION_ID';\n }\n if (ua.includes('firefox')) {\n return 'https://addons.mozilla.org/en-US/firefox/addon/byoky/';\n }\n if (ua.includes('safari') && !ua.includes('chrome')) {\n return 'https://apps.apple.com/app/byoky/TODO_APP_ID';\n }\n return null;\n}\n","export function createProxyFetch(\n providerId: string,\n sessionKey: string,\n): typeof fetch {\n return async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const url =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n\n const method = init?.method ?? 'GET';\n const headers = init?.headers\n ? Object.fromEntries(new Headers(init.headers).entries())\n : {};\n const body = init?.body ? await readBody(init.body) : undefined;\n\n const requestId = crypto.randomUUID();\n\n return new Promise<Response>((resolve, reject) => {\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n let resolved = false;\n\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error('Proxy request timed out'));\n }, 120_000);\n\n function handleMessage(event: MessageEvent) {\n if (event.source !== window) return;\n const data = event.data;\n if (data?.requestId !== requestId) return;\n\n switch (data.type) {\n case 'BYOKY_PROXY_RESPONSE_META':\n if (!resolved) {\n resolved = true;\n clearTimeout(timeout);\n resolve(\n new Response(readable, {\n status: data.status,\n statusText: data.statusText,\n headers: new Headers(data.headers),\n }),\n );\n }\n break;\n\n case 'BYOKY_PROXY_RESPONSE_CHUNK':\n writer.write(encoder.encode(data.chunk)).catch(() => {});\n break;\n\n case 'BYOKY_PROXY_RESPONSE_DONE':\n writer.close().catch(() => {});\n cleanup();\n break;\n\n case 'BYOKY_PROXY_RESPONSE_ERROR': {\n const errResponse = new Response(\n JSON.stringify({ error: data.error }),\n {\n status: data.status || 500,\n headers: { 'content-type': 'application/json' },\n },\n );\n if (!resolved) {\n resolved = true;\n clearTimeout(timeout);\n resolve(errResponse);\n }\n writer.close().catch(() => {});\n cleanup();\n break;\n }\n }\n }\n\n function cleanup() {\n clearTimeout(timeout);\n window.removeEventListener('message', handleMessage);\n }\n\n window.addEventListener('message', handleMessage);\n\n window.postMessage(\n {\n type: 'BYOKY_PROXY_REQUEST',\n requestId,\n sessionKey,\n providerId,\n url,\n method,\n headers,\n body,\n },\n '*',\n );\n });\n };\n}\n\nasync function readBody(body: BodyInit): Promise<string | undefined> {\n if (typeof body === 'string') return body;\n if (body instanceof ArrayBuffer) return new TextDecoder().decode(body);\n if (body instanceof Blob) return body.text();\n if (body instanceof URLSearchParams) return body.toString();\n if (body instanceof ReadableStream) {\n const reader = body.getReader();\n const chunks: Uint8Array[] = [];\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n const total = chunks.reduce((acc, c) => acc + c.length, 0);\n const combined = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n return new TextDecoder().decode(combined);\n }\n return undefined;\n}\n","export { Byoky } from './byoky.js';\nexport type { ByokySession, ByokyOptions } from './byoky.js';\nexport { isExtensionInstalled, getStoreUrl } from './detect.js';\nexport { createProxyFetch } from './proxy-fetch.js';\nexport {\n type ConnectRequest,\n type ConnectResponse,\n type ProviderRequirement,\n ByokyError,\n ByokyErrorCode,\n} from '@byoky/core';\n"],"mappings":"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","names":["ByokyError","ByokyErrorCode"]}
1
+ {"version":3,"sources":["../src/byoky.ts","../src/detect.ts","../src/proxy-fetch.ts","../src/index.ts"],"sourcesContent":["import type { ConnectRequest, ConnectResponse } from '@byoky/core';\nimport { ByokyError, ByokyErrorCode, isByokyMessage } from '@byoky/core';\nimport { isExtensionInstalled, getStoreUrl } from './detect.js';\nimport { createProxyFetch } from './proxy-fetch.js';\n\nexport interface ByokySession extends ConnectResponse {\n createFetch(providerId: string): typeof fetch;\n disconnect(): void;\n}\n\nexport interface ByokyOptions {\n timeout?: number;\n}\n\nexport class Byoky {\n private timeout: number;\n\n constructor(options: ByokyOptions = {}) {\n this.timeout = options.timeout ?? 60_000;\n }\n\n async connect(request: ConnectRequest = {}): Promise<ByokySession> {\n if (!isExtensionInstalled()) {\n const storeUrl = getStoreUrl();\n if (storeUrl) {\n window.open(storeUrl, '_blank');\n }\n throw ByokyError.walletNotInstalled();\n }\n\n const response = await this.sendConnectRequest(request);\n\n return {\n ...response,\n createFetch: (providerId: string) =>\n createProxyFetch(providerId, response.sessionKey),\n disconnect: () => this.disconnect(response.sessionKey),\n };\n }\n\n private sendConnectRequest(\n request: ConnectRequest,\n ): Promise<ConnectResponse> {\n return new Promise<ConnectResponse>((resolve, reject) => {\n const requestId = crypto.randomUUID();\n\n const timeoutId = setTimeout(() => {\n cleanup();\n reject(\n new ByokyError(ByokyErrorCode.UNKNOWN, 'Connection request timed out'),\n );\n }, this.timeout);\n\n function handleEvent(event: Event) {\n const msg = (event as CustomEvent).detail;\n if (typeof msg?.type !== 'string' || !msg.type.startsWith('BYOKY_')) return;\n if (msg.requestId !== requestId) return;\n\n cleanup();\n\n if (msg.type === 'BYOKY_CONNECT_RESPONSE') {\n resolve(msg.payload as ConnectResponse);\n } else if (msg.type === 'BYOKY_ERROR') {\n const { code, message } = msg.payload as {\n code: string;\n message: string;\n };\n reject(new ByokyError(code as ByokyErrorCode, message));\n }\n }\n\n function cleanup() {\n clearTimeout(timeoutId);\n document.removeEventListener('byoky-message', handleEvent);\n }\n\n document.addEventListener('byoky-message', handleEvent);\n\n window.postMessage(\n {\n type: 'BYOKY_CONNECT_REQUEST',\n id: requestId,\n requestId,\n payload: request,\n },\n '*',\n );\n });\n }\n\n private disconnect(sessionKey: string): void {\n window.postMessage(\n { type: 'BYOKY_DISCONNECT', payload: { sessionKey } },\n '*',\n );\n }\n}\n","import { BYOKY_PROVIDER_KEY } from '@byoky/core';\n\nexport function isExtensionInstalled(): boolean {\n return typeof window !== 'undefined' && BYOKY_PROVIDER_KEY in window;\n}\n\nexport function getStoreUrl(): string | null {\n if (typeof navigator === 'undefined') return null;\n\n const ua = navigator.userAgent.toLowerCase();\n\n if (ua.includes('chrome') && !ua.includes('edg')) {\n return 'https://chrome.google.com/webstore/detail/byoky/TODO_EXTENSION_ID';\n }\n if (ua.includes('firefox')) {\n return 'https://addons.mozilla.org/en-US/firefox/addon/byoky/';\n }\n if (ua.includes('safari') && !ua.includes('chrome')) {\n return 'https://apps.apple.com/app/byoky/TODO_APP_ID';\n }\n return null;\n}\n","export function createProxyFetch(\n providerId: string,\n sessionKey: string,\n): typeof fetch {\n return async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const url =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n\n const method = init?.method ?? 'GET';\n const headers = init?.headers\n ? Object.fromEntries(new Headers(init.headers).entries())\n : {};\n const body = init?.body ? await readBody(init.body) : undefined;\n\n const requestId = crypto.randomUUID();\n\n return new Promise<Response>((resolve, reject) => {\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n let resolved = false;\n\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error('Proxy request timed out'));\n }, 120_000);\n\n function handleEvent(event: Event) {\n const data = (event as CustomEvent).detail ?? (event as MessageEvent).data;\n if (data?.requestId !== requestId) return;\n\n switch (data.type) {\n case 'BYOKY_PROXY_RESPONSE_META':\n if (!resolved) {\n resolved = true;\n clearTimeout(timeout);\n resolve(\n new Response(readable, {\n status: data.status,\n statusText: data.statusText,\n headers: new Headers(data.headers),\n }),\n );\n }\n break;\n\n case 'BYOKY_PROXY_RESPONSE_CHUNK':\n writer.write(encoder.encode(data.chunk)).catch(() => {});\n break;\n\n case 'BYOKY_PROXY_RESPONSE_DONE':\n writer.close().catch(() => {});\n cleanup();\n break;\n\n case 'BYOKY_PROXY_RESPONSE_ERROR': {\n const errResponse = new Response(\n JSON.stringify({ error: data.error }),\n {\n status: data.status || 500,\n headers: { 'content-type': 'application/json' },\n },\n );\n if (!resolved) {\n resolved = true;\n clearTimeout(timeout);\n resolve(errResponse);\n }\n writer.close().catch(() => {});\n cleanup();\n break;\n }\n }\n }\n\n function cleanup() {\n clearTimeout(timeout);\n document.removeEventListener('byoky-message', handleEvent);\n }\n\n document.addEventListener('byoky-message', handleEvent);\n\n window.postMessage(\n {\n type: 'BYOKY_PROXY_REQUEST',\n requestId,\n sessionKey,\n providerId,\n url,\n method,\n headers,\n body,\n },\n '*',\n );\n });\n };\n}\n\nasync function readBody(body: BodyInit): Promise<string | undefined> {\n if (typeof body === 'string') return body;\n if (body instanceof ArrayBuffer) return new TextDecoder().decode(body);\n if (body instanceof Blob) return body.text();\n if (body instanceof URLSearchParams) return body.toString();\n if (body instanceof ReadableStream) {\n const reader = body.getReader();\n const chunks: Uint8Array[] = [];\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n const total = chunks.reduce((acc, c) => acc + c.length, 0);\n const combined = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n return new TextDecoder().decode(combined);\n }\n return undefined;\n}\n","export { Byoky } from './byoky.js';\nexport type { ByokySession, ByokyOptions } from './byoky.js';\nexport { isExtensionInstalled, getStoreUrl } from './detect.js';\nexport { createProxyFetch } from './proxy-fetch.js';\nexport {\n type ConnectRequest,\n type ConnectResponse,\n type ProviderRequirement,\n ByokyError,\n ByokyErrorCode,\n} from '@byoky/core';\n"],"mappings":"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","names":["ByokyError","ByokyErrorCode"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byoky/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",