@medialane/sdk 0.105.0 → 0.107.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 +239 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -2
- package/dist/index.d.ts +62 -2
- package/dist/index.js +236 -28
- package/dist/index.js.map +1 -1
- package/dist/starknet/index.cjs +20 -0
- package/dist/starknet/index.cjs.map +1 -1
- package/dist/starknet/index.d.cts +8 -1
- package/dist/starknet/index.d.ts +8 -1
- package/dist/starknet/index.js +19 -1
- package/dist/starknet/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -497,12 +497,60 @@ declare const ALLOWED_IMAGE_CONTENT_TYPES: Set<string>;
|
|
|
497
497
|
declare const MAX_IMAGE_REDIRECTS = 5;
|
|
498
498
|
declare const MAX_IMAGE_PROXY_BYTES: number;
|
|
499
499
|
declare function isPrivateHost(hostname: string): boolean;
|
|
500
|
-
|
|
500
|
+
/**
|
|
501
|
+
* Validates a URL before it is fetched server-side. `requireHttps` is on by
|
|
502
|
+
* default; callers that legitimately accept plain http (a metadata URI already
|
|
503
|
+
* committed on chain, say) opt out explicitly rather than the guard being
|
|
504
|
+
* lenient for everyone.
|
|
505
|
+
*/
|
|
506
|
+
declare function validateUrl(raw: string, options?: {
|
|
507
|
+
requireHttps?: boolean;
|
|
508
|
+
}): {
|
|
501
509
|
url: URL;
|
|
502
510
|
} | {
|
|
503
511
|
error: string;
|
|
504
512
|
status: number;
|
|
505
513
|
};
|
|
514
|
+
/** Convenience for callers that only need a yes/no, mirroring the backend's prior helper. */
|
|
515
|
+
declare function isPrivateOrInsecureUrl(raw: string, requireHttps?: boolean): boolean;
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Proxies a remote image, which means fetching a URL an untrusted caller chose
|
|
519
|
+
* — the classic SSRF shape. Guarded in four places, each of which has to hold:
|
|
520
|
+
*
|
|
521
|
+
* 1. the URL is https, credential-free and not a private host
|
|
522
|
+
* 2. the hostname's *resolved* addresses are re-checked, since a public name
|
|
523
|
+
* can resolve to a private address
|
|
524
|
+
* 3. redirects are followed manually, re-validating each hop, because a
|
|
525
|
+
* permitted host can redirect into the private range
|
|
526
|
+
* 4. the response must be an allowed image type and is read under a byte cap
|
|
527
|
+
*
|
|
528
|
+
* This existed as a byte-identical copy in each app, so a fix to one would not
|
|
529
|
+
* have reached the other. DNS resolution is injected rather than imported: it
|
|
530
|
+
* is runtime-specific, and this package stays isomorphic.
|
|
531
|
+
*
|
|
532
|
+
* Note the remaining exposure: between resolving a hostname and fetching it,
|
|
533
|
+
* the name could resolve differently (DNS rebinding). Closing that needs the
|
|
534
|
+
* fetch pinned to the address already checked, which the platform fetch does
|
|
535
|
+
* not expose. The content-type allowlist and byte cap bound what an attacker
|
|
536
|
+
* gets if they win that race.
|
|
537
|
+
*/
|
|
538
|
+
interface ImageProxyConfig {
|
|
539
|
+
checkRateLimit: (ip: string) => boolean;
|
|
540
|
+
/** Returns every address a hostname resolves to. Injected; see above. */
|
|
541
|
+
resolveHostname: (hostname: string) => Promise<string[]>;
|
|
542
|
+
fetchImpl?: typeof fetch;
|
|
543
|
+
userAgent?: string;
|
|
544
|
+
}
|
|
545
|
+
interface CappedBody {
|
|
546
|
+
ok: boolean;
|
|
547
|
+
body?: Uint8Array;
|
|
548
|
+
error?: string;
|
|
549
|
+
status?: number;
|
|
550
|
+
}
|
|
551
|
+
/** Reads a response body, refusing anything past `maxBytes` rather than buffering it. */
|
|
552
|
+
declare function readBodyWithCap(res: Response, maxBytes: number): Promise<CappedBody>;
|
|
553
|
+
declare function createImageProxyHandler(config: ImageProxyConfig): (req: Request) => Promise<Response>;
|
|
506
554
|
|
|
507
555
|
interface BackendMetadataConfig {
|
|
508
556
|
backendUrl: string;
|
|
@@ -525,8 +573,20 @@ declare function uploadDirectoryToBackend(config: BackendMetadataConfig, files:
|
|
|
525
573
|
declare function getBackendSignedUrl(config: BackendMetadataConfig, kind?: "image" | "document" | "media"): Promise<string>;
|
|
526
574
|
|
|
527
575
|
declare function createRateLimiter(windowMs: number, max: number): (key: string) => boolean;
|
|
576
|
+
declare const TRUSTED_APP_IP_HEADER = "x-medialane-client-ip";
|
|
528
577
|
declare function requestIp(req: Request): string;
|
|
529
578
|
|
|
579
|
+
/**
|
|
580
|
+
* Same-origin guard for server routes. A missing `Origin` header is allowed,
|
|
581
|
+
* because same-origin navigations and server-to-server calls do not send one;
|
|
582
|
+
* a present `Origin` must match `Host`.
|
|
583
|
+
*
|
|
584
|
+
* Read that carefully before relying on it: this blocks cross-site *browser*
|
|
585
|
+
* abuse, and nothing else. A non-browser client simply omits `Origin` and
|
|
586
|
+
* passes. It is not a substitute for authentication, and on a route that
|
|
587
|
+
* spends money or credits it must be paired with a rate limit and, where the
|
|
588
|
+
* route touches a paid resource, real auth.
|
|
589
|
+
*/
|
|
530
590
|
declare function isSameOrigin(req: Request): boolean;
|
|
531
591
|
|
|
532
592
|
declare const IDENTITY_TTL_SECONDS = 86400;
|
|
@@ -596,4 +656,4 @@ declare const IPFS_SAFE_CONTENT_TYPE_PREFIXES: readonly ["image/jpeg", "image/pn
|
|
|
596
656
|
declare function resolveSafeImageContentType(contentType: string): string;
|
|
597
657
|
declare const MAX_IPFS_GATEWAY_RESPONSE_BYTES: number;
|
|
598
658
|
|
|
599
|
-
export { ACCOUNT_SESSION_TTL_SECONDS, ALLOWED_IMAGE_CONTENT_TYPES, type AssetAttribute, type AssetMetadata, type BackendMetadataConfig, type BackendProxyConfig, type BackendUploadResult, type BuildAssetMetadataInput, type CanonicalHash, Chain, DEFAULT_CURRENCY, type FailoverFetchOptions, type FeeEnv, IDENTITY_TTL_SECONDS, IPFS_SAFE_CONTENT_TYPE_PREFIXES, MAX_IMAGE_PROXY_BYTES, MAX_IMAGE_REDIRECTS, MAX_IPFS_GATEWAY_RESPONSE_BYTES, PAID_UPSTREAM_MARKERS, POLICY_REFUSAL_CODES, PUBLIC_RPC_FALLBACKS, RESERVED_TRAITS, type RemixPolicy, type RemixPolicyInput, ResolvedFeeConfig, type RpcProxyConfig, STARKNET_COLLECTION_1155_CLASS_HASH, STARKNET_COLLECTION_1155_CONTRACT, STARKNET_COLLECTION_1155_FACTORY_CLASS_HASH, STARKNET_COLLECTION_1155_START_BLOCK, STARKNET_COLLECTION_721_CONTRACT, STARKNET_COLLECTION_721_START_BLOCK, STARKNET_CREATOR_COIN_CLASS_HASH, STARKNET_CREATOR_COIN_EKUBO_LAUNCHER, STARKNET_CREATOR_COIN_FACTORY_CLASS_HASH, STARKNET_CREATOR_COIN_FACTORY_CONTRACT, STARKNET_CREATOR_COIN_START_BLOCK, STARKNET_DROP_COLLECTION_CLASS_HASH, STARKNET_DROP_FACTORY_CONTRACT, STARKNET_EKUBO_CORE, STARKNET_GENESIS_MINT_BR_CONTRACT, STARKNET_GENESIS_MINT_GLOBAL_CONTRACT, STARKNET_GENESIS_MINT_LAUNCH_CONTRACT, STARKNET_IPCOLLECTION_CLASS_HASH, STARKNET_IPNFT_CLASS_HASH, STARKNET_IP_CLUB_COLLECTION_CLASS_HASH, STARKNET_IP_CLUB_FACTORY_CONTRACT, STARKNET_IP_SPONSORSHIP_CLASS_HASH, STARKNET_IP_SPONSORSHIP_CONTRACT, STARKNET_IP_TICKETS_FACTORY_CONTRACT, STARKNET_IP_TICKET_COLLECTION_CLASS_HASH, STARKNET_MARKETPLACE_1155_CLASS_HASH, STARKNET_MARKETPLACE_1155_CONTRACT, STARKNET_MARKETPLACE_1155_START_BLOCK, STARKNET_MARKETPLACE_721_CLASS_HASH, STARKNET_MARKETPLACE_721_CONTRACT, STARKNET_MARKETPLACE_721_START_BLOCK, STARKNET_NFTCOMMENTS_CONTRACT, STARKNET_POP_COLLECTION_CLASS_HASH, STARKNET_POP_FACTORY_CONTRACT, SUPPORTED_TOKENS, SUPPORTED_URL_CHAINS, ServiceCapability, ServiceDefinition, type ServiceId, type SiwsIdentity, type SupportedToken, type SupportedTokenSymbol, assetHref, buildAssetMetadata, chainFromSlug, chainSlug, coinHref, collectionHref, createBackendProxyHandler, createFailoverFetch, createRateLimiter, createRpcProxyHandler, encodeU256, formatAmount, getBackendSignedUrl, getDerivativesTerm, getListableTokens, getService, getServicesByCapability, getTokenByAddress, getTokenBySymbol, hasCapability, isPolicyRefusal, isPrivateHost, isSameOrigin, isServiceId, isTransientRpcError, isValidIpfsCidPath, issueAccountSessionToken, issueSiwsToken, listServices, normalizeAddress, normalizeHash, parseAmount, requestIp, resolveAppFeeConfig, resolveRemixPolicy, resolveSafeImageContentType, shortenAddress, stringifyBigInts, u256ToBigInt, uploadDirectoryToBackend, uploadFileToBackend, uploadJsonToBackend, validateUrl, verifyAccountSessionToken, verifySiwsToken };
|
|
659
|
+
export { ACCOUNT_SESSION_TTL_SECONDS, ALLOWED_IMAGE_CONTENT_TYPES, type AssetAttribute, type AssetMetadata, type BackendMetadataConfig, type BackendProxyConfig, type BackendUploadResult, type BuildAssetMetadataInput, type CanonicalHash, type CappedBody, Chain, DEFAULT_CURRENCY, type FailoverFetchOptions, type FeeEnv, IDENTITY_TTL_SECONDS, IPFS_SAFE_CONTENT_TYPE_PREFIXES, type ImageProxyConfig, MAX_IMAGE_PROXY_BYTES, MAX_IMAGE_REDIRECTS, MAX_IPFS_GATEWAY_RESPONSE_BYTES, PAID_UPSTREAM_MARKERS, POLICY_REFUSAL_CODES, PUBLIC_RPC_FALLBACKS, RESERVED_TRAITS, type RemixPolicy, type RemixPolicyInput, ResolvedFeeConfig, type RpcProxyConfig, STARKNET_COLLECTION_1155_CLASS_HASH, STARKNET_COLLECTION_1155_CONTRACT, STARKNET_COLLECTION_1155_FACTORY_CLASS_HASH, STARKNET_COLLECTION_1155_START_BLOCK, STARKNET_COLLECTION_721_CONTRACT, STARKNET_COLLECTION_721_START_BLOCK, STARKNET_CREATOR_COIN_CLASS_HASH, STARKNET_CREATOR_COIN_EKUBO_LAUNCHER, STARKNET_CREATOR_COIN_FACTORY_CLASS_HASH, STARKNET_CREATOR_COIN_FACTORY_CONTRACT, STARKNET_CREATOR_COIN_START_BLOCK, STARKNET_DROP_COLLECTION_CLASS_HASH, STARKNET_DROP_FACTORY_CONTRACT, STARKNET_EKUBO_CORE, STARKNET_GENESIS_MINT_BR_CONTRACT, STARKNET_GENESIS_MINT_GLOBAL_CONTRACT, STARKNET_GENESIS_MINT_LAUNCH_CONTRACT, STARKNET_IPCOLLECTION_CLASS_HASH, STARKNET_IPNFT_CLASS_HASH, STARKNET_IP_CLUB_COLLECTION_CLASS_HASH, STARKNET_IP_CLUB_FACTORY_CONTRACT, STARKNET_IP_SPONSORSHIP_CLASS_HASH, STARKNET_IP_SPONSORSHIP_CONTRACT, STARKNET_IP_TICKETS_FACTORY_CONTRACT, STARKNET_IP_TICKET_COLLECTION_CLASS_HASH, STARKNET_MARKETPLACE_1155_CLASS_HASH, STARKNET_MARKETPLACE_1155_CONTRACT, STARKNET_MARKETPLACE_1155_START_BLOCK, STARKNET_MARKETPLACE_721_CLASS_HASH, STARKNET_MARKETPLACE_721_CONTRACT, STARKNET_MARKETPLACE_721_START_BLOCK, STARKNET_NFTCOMMENTS_CONTRACT, STARKNET_POP_COLLECTION_CLASS_HASH, STARKNET_POP_FACTORY_CONTRACT, SUPPORTED_TOKENS, SUPPORTED_URL_CHAINS, ServiceCapability, ServiceDefinition, type ServiceId, type SiwsIdentity, type SupportedToken, type SupportedTokenSymbol, TRUSTED_APP_IP_HEADER, assetHref, buildAssetMetadata, chainFromSlug, chainSlug, coinHref, collectionHref, createBackendProxyHandler, createFailoverFetch, createImageProxyHandler, createRateLimiter, createRpcProxyHandler, encodeU256, formatAmount, getBackendSignedUrl, getDerivativesTerm, getListableTokens, getService, getServicesByCapability, getTokenByAddress, getTokenBySymbol, hasCapability, isPolicyRefusal, isPrivateHost, isPrivateOrInsecureUrl, isSameOrigin, isServiceId, isTransientRpcError, isValidIpfsCidPath, issueAccountSessionToken, issueSiwsToken, listServices, normalizeAddress, normalizeHash, parseAmount, readBodyWithCap, requestIp, resolveAppFeeConfig, resolveRemixPolicy, resolveSafeImageContentType, shortenAddress, stringifyBigInts, u256ToBigInt, uploadDirectoryToBackend, uploadFileToBackend, uploadJsonToBackend, validateUrl, verifyAccountSessionToken, verifySiwsToken };
|
package/dist/index.d.ts
CHANGED
|
@@ -497,12 +497,60 @@ declare const ALLOWED_IMAGE_CONTENT_TYPES: Set<string>;
|
|
|
497
497
|
declare const MAX_IMAGE_REDIRECTS = 5;
|
|
498
498
|
declare const MAX_IMAGE_PROXY_BYTES: number;
|
|
499
499
|
declare function isPrivateHost(hostname: string): boolean;
|
|
500
|
-
|
|
500
|
+
/**
|
|
501
|
+
* Validates a URL before it is fetched server-side. `requireHttps` is on by
|
|
502
|
+
* default; callers that legitimately accept plain http (a metadata URI already
|
|
503
|
+
* committed on chain, say) opt out explicitly rather than the guard being
|
|
504
|
+
* lenient for everyone.
|
|
505
|
+
*/
|
|
506
|
+
declare function validateUrl(raw: string, options?: {
|
|
507
|
+
requireHttps?: boolean;
|
|
508
|
+
}): {
|
|
501
509
|
url: URL;
|
|
502
510
|
} | {
|
|
503
511
|
error: string;
|
|
504
512
|
status: number;
|
|
505
513
|
};
|
|
514
|
+
/** Convenience for callers that only need a yes/no, mirroring the backend's prior helper. */
|
|
515
|
+
declare function isPrivateOrInsecureUrl(raw: string, requireHttps?: boolean): boolean;
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Proxies a remote image, which means fetching a URL an untrusted caller chose
|
|
519
|
+
* — the classic SSRF shape. Guarded in four places, each of which has to hold:
|
|
520
|
+
*
|
|
521
|
+
* 1. the URL is https, credential-free and not a private host
|
|
522
|
+
* 2. the hostname's *resolved* addresses are re-checked, since a public name
|
|
523
|
+
* can resolve to a private address
|
|
524
|
+
* 3. redirects are followed manually, re-validating each hop, because a
|
|
525
|
+
* permitted host can redirect into the private range
|
|
526
|
+
* 4. the response must be an allowed image type and is read under a byte cap
|
|
527
|
+
*
|
|
528
|
+
* This existed as a byte-identical copy in each app, so a fix to one would not
|
|
529
|
+
* have reached the other. DNS resolution is injected rather than imported: it
|
|
530
|
+
* is runtime-specific, and this package stays isomorphic.
|
|
531
|
+
*
|
|
532
|
+
* Note the remaining exposure: between resolving a hostname and fetching it,
|
|
533
|
+
* the name could resolve differently (DNS rebinding). Closing that needs the
|
|
534
|
+
* fetch pinned to the address already checked, which the platform fetch does
|
|
535
|
+
* not expose. The content-type allowlist and byte cap bound what an attacker
|
|
536
|
+
* gets if they win that race.
|
|
537
|
+
*/
|
|
538
|
+
interface ImageProxyConfig {
|
|
539
|
+
checkRateLimit: (ip: string) => boolean;
|
|
540
|
+
/** Returns every address a hostname resolves to. Injected; see above. */
|
|
541
|
+
resolveHostname: (hostname: string) => Promise<string[]>;
|
|
542
|
+
fetchImpl?: typeof fetch;
|
|
543
|
+
userAgent?: string;
|
|
544
|
+
}
|
|
545
|
+
interface CappedBody {
|
|
546
|
+
ok: boolean;
|
|
547
|
+
body?: Uint8Array;
|
|
548
|
+
error?: string;
|
|
549
|
+
status?: number;
|
|
550
|
+
}
|
|
551
|
+
/** Reads a response body, refusing anything past `maxBytes` rather than buffering it. */
|
|
552
|
+
declare function readBodyWithCap(res: Response, maxBytes: number): Promise<CappedBody>;
|
|
553
|
+
declare function createImageProxyHandler(config: ImageProxyConfig): (req: Request) => Promise<Response>;
|
|
506
554
|
|
|
507
555
|
interface BackendMetadataConfig {
|
|
508
556
|
backendUrl: string;
|
|
@@ -525,8 +573,20 @@ declare function uploadDirectoryToBackend(config: BackendMetadataConfig, files:
|
|
|
525
573
|
declare function getBackendSignedUrl(config: BackendMetadataConfig, kind?: "image" | "document" | "media"): Promise<string>;
|
|
526
574
|
|
|
527
575
|
declare function createRateLimiter(windowMs: number, max: number): (key: string) => boolean;
|
|
576
|
+
declare const TRUSTED_APP_IP_HEADER = "x-medialane-client-ip";
|
|
528
577
|
declare function requestIp(req: Request): string;
|
|
529
578
|
|
|
579
|
+
/**
|
|
580
|
+
* Same-origin guard for server routes. A missing `Origin` header is allowed,
|
|
581
|
+
* because same-origin navigations and server-to-server calls do not send one;
|
|
582
|
+
* a present `Origin` must match `Host`.
|
|
583
|
+
*
|
|
584
|
+
* Read that carefully before relying on it: this blocks cross-site *browser*
|
|
585
|
+
* abuse, and nothing else. A non-browser client simply omits `Origin` and
|
|
586
|
+
* passes. It is not a substitute for authentication, and on a route that
|
|
587
|
+
* spends money or credits it must be paired with a rate limit and, where the
|
|
588
|
+
* route touches a paid resource, real auth.
|
|
589
|
+
*/
|
|
530
590
|
declare function isSameOrigin(req: Request): boolean;
|
|
531
591
|
|
|
532
592
|
declare const IDENTITY_TTL_SECONDS = 86400;
|
|
@@ -596,4 +656,4 @@ declare const IPFS_SAFE_CONTENT_TYPE_PREFIXES: readonly ["image/jpeg", "image/pn
|
|
|
596
656
|
declare function resolveSafeImageContentType(contentType: string): string;
|
|
597
657
|
declare const MAX_IPFS_GATEWAY_RESPONSE_BYTES: number;
|
|
598
658
|
|
|
599
|
-
export { ACCOUNT_SESSION_TTL_SECONDS, ALLOWED_IMAGE_CONTENT_TYPES, type AssetAttribute, type AssetMetadata, type BackendMetadataConfig, type BackendProxyConfig, type BackendUploadResult, type BuildAssetMetadataInput, type CanonicalHash, Chain, DEFAULT_CURRENCY, type FailoverFetchOptions, type FeeEnv, IDENTITY_TTL_SECONDS, IPFS_SAFE_CONTENT_TYPE_PREFIXES, MAX_IMAGE_PROXY_BYTES, MAX_IMAGE_REDIRECTS, MAX_IPFS_GATEWAY_RESPONSE_BYTES, PAID_UPSTREAM_MARKERS, POLICY_REFUSAL_CODES, PUBLIC_RPC_FALLBACKS, RESERVED_TRAITS, type RemixPolicy, type RemixPolicyInput, ResolvedFeeConfig, type RpcProxyConfig, STARKNET_COLLECTION_1155_CLASS_HASH, STARKNET_COLLECTION_1155_CONTRACT, STARKNET_COLLECTION_1155_FACTORY_CLASS_HASH, STARKNET_COLLECTION_1155_START_BLOCK, STARKNET_COLLECTION_721_CONTRACT, STARKNET_COLLECTION_721_START_BLOCK, STARKNET_CREATOR_COIN_CLASS_HASH, STARKNET_CREATOR_COIN_EKUBO_LAUNCHER, STARKNET_CREATOR_COIN_FACTORY_CLASS_HASH, STARKNET_CREATOR_COIN_FACTORY_CONTRACT, STARKNET_CREATOR_COIN_START_BLOCK, STARKNET_DROP_COLLECTION_CLASS_HASH, STARKNET_DROP_FACTORY_CONTRACT, STARKNET_EKUBO_CORE, STARKNET_GENESIS_MINT_BR_CONTRACT, STARKNET_GENESIS_MINT_GLOBAL_CONTRACT, STARKNET_GENESIS_MINT_LAUNCH_CONTRACT, STARKNET_IPCOLLECTION_CLASS_HASH, STARKNET_IPNFT_CLASS_HASH, STARKNET_IP_CLUB_COLLECTION_CLASS_HASH, STARKNET_IP_CLUB_FACTORY_CONTRACT, STARKNET_IP_SPONSORSHIP_CLASS_HASH, STARKNET_IP_SPONSORSHIP_CONTRACT, STARKNET_IP_TICKETS_FACTORY_CONTRACT, STARKNET_IP_TICKET_COLLECTION_CLASS_HASH, STARKNET_MARKETPLACE_1155_CLASS_HASH, STARKNET_MARKETPLACE_1155_CONTRACT, STARKNET_MARKETPLACE_1155_START_BLOCK, STARKNET_MARKETPLACE_721_CLASS_HASH, STARKNET_MARKETPLACE_721_CONTRACT, STARKNET_MARKETPLACE_721_START_BLOCK, STARKNET_NFTCOMMENTS_CONTRACT, STARKNET_POP_COLLECTION_CLASS_HASH, STARKNET_POP_FACTORY_CONTRACT, SUPPORTED_TOKENS, SUPPORTED_URL_CHAINS, ServiceCapability, ServiceDefinition, type ServiceId, type SiwsIdentity, type SupportedToken, type SupportedTokenSymbol, assetHref, buildAssetMetadata, chainFromSlug, chainSlug, coinHref, collectionHref, createBackendProxyHandler, createFailoverFetch, createRateLimiter, createRpcProxyHandler, encodeU256, formatAmount, getBackendSignedUrl, getDerivativesTerm, getListableTokens, getService, getServicesByCapability, getTokenByAddress, getTokenBySymbol, hasCapability, isPolicyRefusal, isPrivateHost, isSameOrigin, isServiceId, isTransientRpcError, isValidIpfsCidPath, issueAccountSessionToken, issueSiwsToken, listServices, normalizeAddress, normalizeHash, parseAmount, requestIp, resolveAppFeeConfig, resolveRemixPolicy, resolveSafeImageContentType, shortenAddress, stringifyBigInts, u256ToBigInt, uploadDirectoryToBackend, uploadFileToBackend, uploadJsonToBackend, validateUrl, verifyAccountSessionToken, verifySiwsToken };
|
|
659
|
+
export { ACCOUNT_SESSION_TTL_SECONDS, ALLOWED_IMAGE_CONTENT_TYPES, type AssetAttribute, type AssetMetadata, type BackendMetadataConfig, type BackendProxyConfig, type BackendUploadResult, type BuildAssetMetadataInput, type CanonicalHash, type CappedBody, Chain, DEFAULT_CURRENCY, type FailoverFetchOptions, type FeeEnv, IDENTITY_TTL_SECONDS, IPFS_SAFE_CONTENT_TYPE_PREFIXES, type ImageProxyConfig, MAX_IMAGE_PROXY_BYTES, MAX_IMAGE_REDIRECTS, MAX_IPFS_GATEWAY_RESPONSE_BYTES, PAID_UPSTREAM_MARKERS, POLICY_REFUSAL_CODES, PUBLIC_RPC_FALLBACKS, RESERVED_TRAITS, type RemixPolicy, type RemixPolicyInput, ResolvedFeeConfig, type RpcProxyConfig, STARKNET_COLLECTION_1155_CLASS_HASH, STARKNET_COLLECTION_1155_CONTRACT, STARKNET_COLLECTION_1155_FACTORY_CLASS_HASH, STARKNET_COLLECTION_1155_START_BLOCK, STARKNET_COLLECTION_721_CONTRACT, STARKNET_COLLECTION_721_START_BLOCK, STARKNET_CREATOR_COIN_CLASS_HASH, STARKNET_CREATOR_COIN_EKUBO_LAUNCHER, STARKNET_CREATOR_COIN_FACTORY_CLASS_HASH, STARKNET_CREATOR_COIN_FACTORY_CONTRACT, STARKNET_CREATOR_COIN_START_BLOCK, STARKNET_DROP_COLLECTION_CLASS_HASH, STARKNET_DROP_FACTORY_CONTRACT, STARKNET_EKUBO_CORE, STARKNET_GENESIS_MINT_BR_CONTRACT, STARKNET_GENESIS_MINT_GLOBAL_CONTRACT, STARKNET_GENESIS_MINT_LAUNCH_CONTRACT, STARKNET_IPCOLLECTION_CLASS_HASH, STARKNET_IPNFT_CLASS_HASH, STARKNET_IP_CLUB_COLLECTION_CLASS_HASH, STARKNET_IP_CLUB_FACTORY_CONTRACT, STARKNET_IP_SPONSORSHIP_CLASS_HASH, STARKNET_IP_SPONSORSHIP_CONTRACT, STARKNET_IP_TICKETS_FACTORY_CONTRACT, STARKNET_IP_TICKET_COLLECTION_CLASS_HASH, STARKNET_MARKETPLACE_1155_CLASS_HASH, STARKNET_MARKETPLACE_1155_CONTRACT, STARKNET_MARKETPLACE_1155_START_BLOCK, STARKNET_MARKETPLACE_721_CLASS_HASH, STARKNET_MARKETPLACE_721_CONTRACT, STARKNET_MARKETPLACE_721_START_BLOCK, STARKNET_NFTCOMMENTS_CONTRACT, STARKNET_POP_COLLECTION_CLASS_HASH, STARKNET_POP_FACTORY_CONTRACT, SUPPORTED_TOKENS, SUPPORTED_URL_CHAINS, ServiceCapability, ServiceDefinition, type ServiceId, type SiwsIdentity, type SupportedToken, type SupportedTokenSymbol, TRUSTED_APP_IP_HEADER, assetHref, buildAssetMetadata, chainFromSlug, chainSlug, coinHref, collectionHref, createBackendProxyHandler, createFailoverFetch, createImageProxyHandler, createRateLimiter, createRpcProxyHandler, encodeU256, formatAmount, getBackendSignedUrl, getDerivativesTerm, getListableTokens, getService, getServicesByCapability, getTokenByAddress, getTokenBySymbol, hasCapability, isPolicyRefusal, isPrivateHost, isPrivateOrInsecureUrl, isSameOrigin, isServiceId, isTransientRpcError, isValidIpfsCidPath, issueAccountSessionToken, issueSiwsToken, listServices, normalizeAddress, normalizeHash, parseAmount, readBodyWithCap, requestIp, resolveAppFeeConfig, resolveRemixPolicy, resolveSafeImageContentType, shortenAddress, stringifyBigInts, u256ToBigInt, uploadDirectoryToBackend, uploadFileToBackend, uploadJsonToBackend, validateUrl, verifyAccountSessionToken, verifySiwsToken };
|
package/dist/index.js
CHANGED
|
@@ -1375,8 +1375,19 @@ function createRateLimiter(windowMs, max) {
|
|
|
1375
1375
|
return true;
|
|
1376
1376
|
};
|
|
1377
1377
|
}
|
|
1378
|
+
var TRUSTED_APP_IP_HEADER = "x-medialane-client-ip";
|
|
1378
1379
|
function requestIp(req) {
|
|
1379
|
-
|
|
1380
|
+
const fromApp = req.headers.get(TRUSTED_APP_IP_HEADER)?.trim();
|
|
1381
|
+
if (fromApp) return fromApp;
|
|
1382
|
+
const fromEdge = req.headers.get("x-vercel-forwarded-for")?.split(",")[0]?.trim();
|
|
1383
|
+
if (fromEdge) return fromEdge;
|
|
1384
|
+
const forwarded = req.headers.get("x-forwarded-for");
|
|
1385
|
+
if (forwarded) {
|
|
1386
|
+
const hops = forwarded.split(",").map((hop) => hop.trim()).filter(Boolean);
|
|
1387
|
+
const nearest = hops[hops.length - 1];
|
|
1388
|
+
if (nearest) return nearest;
|
|
1389
|
+
}
|
|
1390
|
+
return "unknown";
|
|
1380
1391
|
}
|
|
1381
1392
|
|
|
1382
1393
|
// src/server/origin.ts
|
|
@@ -1465,43 +1476,135 @@ var ALLOWED_IMAGE_CONTENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
1465
1476
|
]);
|
|
1466
1477
|
var MAX_IMAGE_REDIRECTS = 5;
|
|
1467
1478
|
var MAX_IMAGE_PROXY_BYTES = 15 * 1024 * 1024;
|
|
1479
|
+
function parseIpv4(ip) {
|
|
1480
|
+
const parts = ip.split(".");
|
|
1481
|
+
if (parts.length !== 4) return null;
|
|
1482
|
+
const bytes = [];
|
|
1483
|
+
for (const part of parts) {
|
|
1484
|
+
if (!/^\d{1,3}$/.test(part)) return null;
|
|
1485
|
+
const n = Number(part);
|
|
1486
|
+
if (n > 255) return null;
|
|
1487
|
+
bytes.push(n);
|
|
1488
|
+
}
|
|
1489
|
+
return bytes;
|
|
1490
|
+
}
|
|
1491
|
+
function isPrivateIpv4(bytes) {
|
|
1492
|
+
const a = bytes[0];
|
|
1493
|
+
const b = bytes[1];
|
|
1494
|
+
const c = bytes[2];
|
|
1495
|
+
if (a === 0) return true;
|
|
1496
|
+
if (a === 10) return true;
|
|
1497
|
+
if (a === 100 && b >= 64 && b <= 127) return true;
|
|
1498
|
+
if (a === 127) return true;
|
|
1499
|
+
if (a === 169 && b === 254) return true;
|
|
1500
|
+
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
1501
|
+
if (a === 192 && b === 0 && c === 0) return true;
|
|
1502
|
+
if (a === 192 && b === 168) return true;
|
|
1503
|
+
if (a === 198 && (b === 18 || b === 19)) return true;
|
|
1504
|
+
if (a >= 224) return true;
|
|
1505
|
+
return false;
|
|
1506
|
+
}
|
|
1507
|
+
function expandIpv6(rawIp) {
|
|
1508
|
+
let ip = rawIp;
|
|
1509
|
+
let embeddedV4 = null;
|
|
1510
|
+
const v4Tail = ip.match(/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
|
|
1511
|
+
if (v4Tail && ip.includes(":")) {
|
|
1512
|
+
embeddedV4 = parseIpv4(v4Tail[1]);
|
|
1513
|
+
if (!embeddedV4) return null;
|
|
1514
|
+
ip = ip.slice(0, ip.length - v4Tail[1].length) + "0:0";
|
|
1515
|
+
}
|
|
1516
|
+
const sides = ip.split("::");
|
|
1517
|
+
if (sides.length > 2) return null;
|
|
1518
|
+
const head = sides[0] ? sides[0].split(":").filter(Boolean) : [];
|
|
1519
|
+
const tail = sides.length === 2 && sides[1] ? sides[1].split(":").filter(Boolean) : [];
|
|
1520
|
+
let groups;
|
|
1521
|
+
if (sides.length === 1) {
|
|
1522
|
+
groups = head;
|
|
1523
|
+
if (groups.length !== 8) return null;
|
|
1524
|
+
} else {
|
|
1525
|
+
const missing = 8 - head.length - tail.length;
|
|
1526
|
+
if (missing < 0) return null;
|
|
1527
|
+
groups = [...head, ...Array(missing).fill("0"), ...tail];
|
|
1528
|
+
}
|
|
1529
|
+
if (groups.length !== 8) return null;
|
|
1530
|
+
const bytes = [];
|
|
1531
|
+
for (const group of groups) {
|
|
1532
|
+
if (!/^[0-9a-fA-F]{1,4}$/.test(group)) return null;
|
|
1533
|
+
const n = parseInt(group, 16);
|
|
1534
|
+
bytes.push(n >> 8 & 255, n & 255);
|
|
1535
|
+
}
|
|
1536
|
+
if (embeddedV4) {
|
|
1537
|
+
bytes[12] = embeddedV4[0];
|
|
1538
|
+
bytes[13] = embeddedV4[1];
|
|
1539
|
+
bytes[14] = embeddedV4[2];
|
|
1540
|
+
bytes[15] = embeddedV4[3];
|
|
1541
|
+
}
|
|
1542
|
+
return bytes;
|
|
1543
|
+
}
|
|
1544
|
+
function isPrivateIpv6(bytes) {
|
|
1545
|
+
if (bytes.every((b) => b === 0)) return true;
|
|
1546
|
+
if (bytes.slice(0, 15).every((b) => b === 0) && bytes[15] === 1) return true;
|
|
1547
|
+
if ((bytes[0] & 254) === 252) return true;
|
|
1548
|
+
if (bytes[0] === 254 && (bytes[1] & 192) === 128) return true;
|
|
1549
|
+
if (bytes.slice(0, 10).every((b) => b === 0) && bytes[10] === 255 && bytes[11] === 255) {
|
|
1550
|
+
return isPrivateIpv4(bytes.slice(12));
|
|
1551
|
+
}
|
|
1552
|
+
return false;
|
|
1553
|
+
}
|
|
1554
|
+
function parseNumber(part) {
|
|
1555
|
+
if (/^0x[0-9a-f]+$/i.test(part)) return parseInt(part.slice(2), 16);
|
|
1556
|
+
if (/^0[0-7]+$/.test(part)) return parseInt(part, 8);
|
|
1557
|
+
if (/^\d+$/.test(part)) return parseInt(part, 10);
|
|
1558
|
+
return null;
|
|
1559
|
+
}
|
|
1560
|
+
function normalizeNumericHostname(host) {
|
|
1561
|
+
const parts = host.trim().split(".");
|
|
1562
|
+
if (parts.length < 1 || parts.length > 4) return null;
|
|
1563
|
+
const values = [];
|
|
1564
|
+
for (const part of parts) {
|
|
1565
|
+
const value = parseNumber(part);
|
|
1566
|
+
if (value === null || value < 0) return null;
|
|
1567
|
+
values.push(value);
|
|
1568
|
+
}
|
|
1569
|
+
const leading = values.slice(0, -1);
|
|
1570
|
+
if (leading.some((v) => v > 255)) return null;
|
|
1571
|
+
const tail = values[values.length - 1];
|
|
1572
|
+
const tailBytes = 4 - leading.length;
|
|
1573
|
+
if (tail > 2 ** (8 * tailBytes) - 1) return null;
|
|
1574
|
+
const bytes = [...leading];
|
|
1575
|
+
for (let i = tailBytes - 1; i >= 0; i--) bytes.push(tail >>> 8 * i & 255);
|
|
1576
|
+
return bytes.join(".");
|
|
1577
|
+
}
|
|
1578
|
+
var BLOCKED_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
1579
|
+
"localhost",
|
|
1580
|
+
"metadata.google.internal",
|
|
1581
|
+
"metadata.azure.internal"
|
|
1582
|
+
]);
|
|
1468
1583
|
function isPrivateHost(hostname) {
|
|
1469
|
-
const
|
|
1470
|
-
if (
|
|
1471
|
-
if (
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
if (n === 2130706433 || n === 0 || n >= 2886729728 && n <= 2887778303 || n >= 3232235520 && n <= 3232301055 || n >= 167772160 && n <= 184549375 || n >= 2851995648 && n <= 2852061183) return true;
|
|
1478
|
-
}
|
|
1479
|
-
if (/^0\d+\.\d+\.\d+\.\d+$/.test(h)) return true;
|
|
1480
|
-
if (h === "::1" || /^0*:0*:0*:0*:0*:0*:0*:0*1$/.test(h)) return true;
|
|
1481
|
-
const v4mapped = h.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/i);
|
|
1482
|
-
if (v4mapped) return isPrivateHost(v4mapped[1]);
|
|
1483
|
-
if (/^10\./.test(h)) return true;
|
|
1484
|
-
if (/^172\.(1[6-9]|2\d|3[01])\./.test(h)) return true;
|
|
1485
|
-
if (/^192\.168\./.test(h)) return true;
|
|
1486
|
-
if (/^169\.254\./.test(h)) return true;
|
|
1487
|
-
if (/^100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\./.test(h)) return true;
|
|
1488
|
-
if (/^fe80:/i.test(h)) return true;
|
|
1489
|
-
if (/^f[cd][0-9a-f]{2}:/i.test(h)) return true;
|
|
1490
|
-
if (h.endsWith(".local")) return true;
|
|
1491
|
-
if (h === "metadata.google.internal") return true;
|
|
1492
|
-
if (h === "metadata.azure.internal") return true;
|
|
1584
|
+
const host = hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
1585
|
+
if (BLOCKED_HOSTNAMES.has(host)) return true;
|
|
1586
|
+
if (host.endsWith(".local") || host.endsWith(".internal")) return true;
|
|
1587
|
+
const candidate = normalizeNumericHostname(host) ?? host;
|
|
1588
|
+
const v4 = parseIpv4(candidate);
|
|
1589
|
+
if (v4) return isPrivateIpv4(v4);
|
|
1590
|
+
const v6 = expandIpv6(candidate);
|
|
1591
|
+
if (v6) return isPrivateIpv6(v6);
|
|
1493
1592
|
return false;
|
|
1494
1593
|
}
|
|
1495
|
-
function validateUrl(raw) {
|
|
1594
|
+
function validateUrl(raw, options = {}) {
|
|
1595
|
+
const requireHttps = options.requireHttps ?? true;
|
|
1496
1596
|
let parsed;
|
|
1497
1597
|
try {
|
|
1498
1598
|
parsed = new URL(raw);
|
|
1499
1599
|
} catch {
|
|
1500
1600
|
return { error: "Invalid url", status: 400 };
|
|
1501
1601
|
}
|
|
1502
|
-
if (parsed.protocol !== "https:") {
|
|
1602
|
+
if (requireHttps && parsed.protocol !== "https:") {
|
|
1503
1603
|
return { error: "Only https URLs allowed", status: 400 };
|
|
1504
1604
|
}
|
|
1605
|
+
if (!requireHttps && parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
1606
|
+
return { error: "Only http and https URLs allowed", status: 400 };
|
|
1607
|
+
}
|
|
1505
1608
|
if (parsed.username || parsed.password) {
|
|
1506
1609
|
return { error: "URL credentials not allowed", status: 400 };
|
|
1507
1610
|
}
|
|
@@ -1510,6 +1613,111 @@ function validateUrl(raw) {
|
|
|
1510
1613
|
}
|
|
1511
1614
|
return { url: parsed };
|
|
1512
1615
|
}
|
|
1616
|
+
function isPrivateOrInsecureUrl(raw, requireHttps = true) {
|
|
1617
|
+
return "error" in validateUrl(raw, { requireHttps });
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
// src/server/image-proxy.ts
|
|
1621
|
+
var DEFAULT_USER_AGENT = "Mozilla/5.0 (compatible; Medialane/1.0; +https://www.medialane.io)";
|
|
1622
|
+
function jsonError(message, status) {
|
|
1623
|
+
return Response.json({ error: message }, { status });
|
|
1624
|
+
}
|
|
1625
|
+
async function readBodyWithCap(res, maxBytes) {
|
|
1626
|
+
const declared = Number(res.headers.get("content-length") ?? 0);
|
|
1627
|
+
if (declared > maxBytes) {
|
|
1628
|
+
return { ok: false, error: "Image too large", status: 413 };
|
|
1629
|
+
}
|
|
1630
|
+
const reader = res.body?.getReader();
|
|
1631
|
+
if (!reader) return { ok: false, error: "Empty response body", status: 502 };
|
|
1632
|
+
const chunks = [];
|
|
1633
|
+
let total = 0;
|
|
1634
|
+
for (; ; ) {
|
|
1635
|
+
const { done, value } = await reader.read();
|
|
1636
|
+
if (done) break;
|
|
1637
|
+
if (!value) continue;
|
|
1638
|
+
total += value.byteLength;
|
|
1639
|
+
if (total > maxBytes) {
|
|
1640
|
+
await reader.cancel().catch(() => {
|
|
1641
|
+
});
|
|
1642
|
+
return { ok: false, error: "Image too large", status: 413 };
|
|
1643
|
+
}
|
|
1644
|
+
chunks.push(value);
|
|
1645
|
+
}
|
|
1646
|
+
const body = new Uint8Array(total);
|
|
1647
|
+
let offset = 0;
|
|
1648
|
+
for (const chunk of chunks) {
|
|
1649
|
+
body.set(chunk, offset);
|
|
1650
|
+
offset += chunk.byteLength;
|
|
1651
|
+
}
|
|
1652
|
+
return { ok: true, body };
|
|
1653
|
+
}
|
|
1654
|
+
function createImageProxyHandler(config) {
|
|
1655
|
+
const doFetch = config.fetchImpl ?? fetch;
|
|
1656
|
+
const userAgent = config.userAgent ?? DEFAULT_USER_AGENT;
|
|
1657
|
+
async function resolvesToPrivateHost(hostname) {
|
|
1658
|
+
try {
|
|
1659
|
+
const addresses = await config.resolveHostname(hostname);
|
|
1660
|
+
if (addresses.length === 0) return true;
|
|
1661
|
+
return addresses.some((address) => isPrivateHost(address));
|
|
1662
|
+
} catch {
|
|
1663
|
+
return true;
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
async function safeFetch(url, hopsLeft) {
|
|
1667
|
+
if (hopsLeft < 0) throw new Error("Too many redirects");
|
|
1668
|
+
if (await resolvesToPrivateHost(url.hostname)) {
|
|
1669
|
+
throw new Error("Blocked: hostname resolves to a private address");
|
|
1670
|
+
}
|
|
1671
|
+
const res = await doFetch(url.toString(), {
|
|
1672
|
+
redirect: "manual",
|
|
1673
|
+
headers: { "User-Agent": userAgent }
|
|
1674
|
+
});
|
|
1675
|
+
if (res.status >= 300 && res.status < 400) {
|
|
1676
|
+
const location = res.headers.get("location");
|
|
1677
|
+
if (!location) throw new Error("Redirect with no Location header");
|
|
1678
|
+
const next = new URL(location, url);
|
|
1679
|
+
const validated = validateUrl(next.toString());
|
|
1680
|
+
if ("error" in validated) throw new Error(`Redirect blocked: ${validated.error}`);
|
|
1681
|
+
return safeFetch(validated.url, hopsLeft - 1);
|
|
1682
|
+
}
|
|
1683
|
+
return res;
|
|
1684
|
+
}
|
|
1685
|
+
return async function handleImageProxy(req) {
|
|
1686
|
+
if (!config.checkRateLimit(requestIp(req))) {
|
|
1687
|
+
return jsonError("Too many requests", 429);
|
|
1688
|
+
}
|
|
1689
|
+
const raw = new URL(req.url).searchParams.get("url");
|
|
1690
|
+
if (!raw) return jsonError("Missing url", 400);
|
|
1691
|
+
const validated = validateUrl(raw);
|
|
1692
|
+
if ("error" in validated) return jsonError(validated.error, validated.status);
|
|
1693
|
+
let upstream;
|
|
1694
|
+
try {
|
|
1695
|
+
upstream = await safeFetch(validated.url, MAX_IMAGE_REDIRECTS);
|
|
1696
|
+
} catch {
|
|
1697
|
+
return jsonError("Failed to fetch image", 502);
|
|
1698
|
+
}
|
|
1699
|
+
if (!upstream.ok) {
|
|
1700
|
+
return jsonError(`Upstream returned ${upstream.status}`, upstream.status);
|
|
1701
|
+
}
|
|
1702
|
+
const contentType = upstream.headers.get("content-type") ?? "";
|
|
1703
|
+
const baseType = contentType.split(";")[0].trim().toLowerCase();
|
|
1704
|
+
if (!ALLOWED_IMAGE_CONTENT_TYPES.has(baseType)) {
|
|
1705
|
+
return jsonError("Not an image", 400);
|
|
1706
|
+
}
|
|
1707
|
+
const capped = await readBodyWithCap(upstream, MAX_IMAGE_PROXY_BYTES);
|
|
1708
|
+
if (!capped.ok) return jsonError(capped.error, capped.status);
|
|
1709
|
+
return new Response(capped.body, {
|
|
1710
|
+
status: 200,
|
|
1711
|
+
headers: {
|
|
1712
|
+
"Content-Type": contentType,
|
|
1713
|
+
"X-Content-Type-Options": "nosniff",
|
|
1714
|
+
"Content-Security-Policy": "default-src 'none'; img-src 'self' data:; style-src 'unsafe-inline'; sandbox",
|
|
1715
|
+
"Cache-Control": "public, max-age=86400, s-maxage=86400, stale-while-revalidate=604800",
|
|
1716
|
+
"Access-Control-Allow-Origin": "*"
|
|
1717
|
+
}
|
|
1718
|
+
});
|
|
1719
|
+
};
|
|
1720
|
+
}
|
|
1513
1721
|
|
|
1514
1722
|
// src/server/backend-metadata.ts
|
|
1515
1723
|
function endpoint(config, path) {
|
|
@@ -1728,6 +1936,6 @@ function resolveSafeImageContentType(contentType) {
|
|
|
1728
1936
|
}
|
|
1729
1937
|
var MAX_IPFS_GATEWAY_RESPONSE_BYTES = 25 * 1024 * 1024;
|
|
1730
1938
|
|
|
1731
|
-
export { ACCOUNT_SESSION_TTL_SECONDS, ALLOWED_IMAGE_CONTENT_TYPES, ApiClient, CHAINS, DEFAULT_CHAIN, DEFAULT_CURRENCY, FeeConfigSchema, IDENTITY_TTL_SECONDS, IPFS_SAFE_CONTENT_TYPE_PREFIXES, MAX_IMAGE_PROXY_BYTES, MAX_IMAGE_REDIRECTS, MAX_IPFS_GATEWAY_RESPONSE_BYTES, MedialaneApiError, OPEN_LICENSES, PAID_UPSTREAM_MARKERS, POLICY_REFUSAL_CODES, PUBLIC_RPC_FALLBACKS, RESERVED_TRAITS, STARKNET_COLLECTION_1155_CLASS_HASH, STARKNET_COLLECTION_1155_CONTRACT, STARKNET_COLLECTION_1155_FACTORY_CLASS_HASH, STARKNET_COLLECTION_1155_START_BLOCK, STARKNET_COLLECTION_721_CONTRACT, STARKNET_COLLECTION_721_START_BLOCK, STARKNET_CREATOR_COIN_CLASS_HASH, STARKNET_CREATOR_COIN_EKUBO_LAUNCHER, STARKNET_CREATOR_COIN_FACTORY_CLASS_HASH, STARKNET_CREATOR_COIN_FACTORY_CONTRACT, STARKNET_CREATOR_COIN_START_BLOCK, STARKNET_DROP_COLLECTION_CLASS_HASH, STARKNET_DROP_FACTORY_CONTRACT, STARKNET_EKUBO_CORE, STARKNET_GENESIS_MINT_BR_CONTRACT, STARKNET_GENESIS_MINT_GLOBAL_CONTRACT, STARKNET_GENESIS_MINT_LAUNCH_CONTRACT, STARKNET_IPCOLLECTION_CLASS_HASH, STARKNET_IPNFT_CLASS_HASH, STARKNET_IP_CLUB_COLLECTION_CLASS_HASH, STARKNET_IP_CLUB_FACTORY_CONTRACT, STARKNET_IP_SPONSORSHIP_CLASS_HASH, STARKNET_IP_SPONSORSHIP_CONTRACT, STARKNET_IP_TICKETS_FACTORY_CONTRACT, STARKNET_IP_TICKET_COLLECTION_CLASS_HASH, STARKNET_MARKETPLACE_1155_CLASS_HASH, STARKNET_MARKETPLACE_1155_CONTRACT, STARKNET_MARKETPLACE_1155_START_BLOCK, STARKNET_MARKETPLACE_721_CLASS_HASH, STARKNET_MARKETPLACE_721_CONTRACT, STARKNET_MARKETPLACE_721_START_BLOCK, STARKNET_NFTCOMMENTS_CONTRACT, STARKNET_POP_COLLECTION_CLASS_HASH, STARKNET_POP_FACTORY_CONTRACT, SUPPORTED_TOKENS, SUPPORTED_URL_CHAINS, assetHref, buildAssetMetadata, chainFromSlug, chainSlug, coinHref, collectionHref, createBackendProxyHandler, createFailoverFetch, createRateLimiter, createRpcProxyHandler, encodeU256, formatAmount, getBackendSignedUrl, getCoordinates, getDerivativesTerm, getListableTokens, getService, getServicesByCapability, getStarknetCoordinates, getTokenByAddress, getTokenBySymbol, hasCapability, isPolicyRefusal, isPrivateHost, isSameOrigin, isServiceId, isTransientRpcError, isValidIpfsCidPath, issueAccountSessionToken, issueSiwsToken, listServices, normalizeAddress, normalizeHash, parseAmount, requestIp, resolveAppFeeConfig, resolveConfig, resolveFeeConfig, resolveRemixPolicy, resolveSafeImageContentType, shortenAddress, stringifyBigInts, u256ToBigInt, uploadDirectoryToBackend, uploadFileToBackend, uploadJsonToBackend, validateUrl, verifyAccountSessionToken, verifySiwsToken };
|
|
1939
|
+
export { ACCOUNT_SESSION_TTL_SECONDS, ALLOWED_IMAGE_CONTENT_TYPES, ApiClient, CHAINS, DEFAULT_CHAIN, DEFAULT_CURRENCY, FeeConfigSchema, IDENTITY_TTL_SECONDS, IPFS_SAFE_CONTENT_TYPE_PREFIXES, MAX_IMAGE_PROXY_BYTES, MAX_IMAGE_REDIRECTS, MAX_IPFS_GATEWAY_RESPONSE_BYTES, MedialaneApiError, OPEN_LICENSES, PAID_UPSTREAM_MARKERS, POLICY_REFUSAL_CODES, PUBLIC_RPC_FALLBACKS, RESERVED_TRAITS, STARKNET_COLLECTION_1155_CLASS_HASH, STARKNET_COLLECTION_1155_CONTRACT, STARKNET_COLLECTION_1155_FACTORY_CLASS_HASH, STARKNET_COLLECTION_1155_START_BLOCK, STARKNET_COLLECTION_721_CONTRACT, STARKNET_COLLECTION_721_START_BLOCK, STARKNET_CREATOR_COIN_CLASS_HASH, STARKNET_CREATOR_COIN_EKUBO_LAUNCHER, STARKNET_CREATOR_COIN_FACTORY_CLASS_HASH, STARKNET_CREATOR_COIN_FACTORY_CONTRACT, STARKNET_CREATOR_COIN_START_BLOCK, STARKNET_DROP_COLLECTION_CLASS_HASH, STARKNET_DROP_FACTORY_CONTRACT, STARKNET_EKUBO_CORE, STARKNET_GENESIS_MINT_BR_CONTRACT, STARKNET_GENESIS_MINT_GLOBAL_CONTRACT, STARKNET_GENESIS_MINT_LAUNCH_CONTRACT, STARKNET_IPCOLLECTION_CLASS_HASH, STARKNET_IPNFT_CLASS_HASH, STARKNET_IP_CLUB_COLLECTION_CLASS_HASH, STARKNET_IP_CLUB_FACTORY_CONTRACT, STARKNET_IP_SPONSORSHIP_CLASS_HASH, STARKNET_IP_SPONSORSHIP_CONTRACT, STARKNET_IP_TICKETS_FACTORY_CONTRACT, STARKNET_IP_TICKET_COLLECTION_CLASS_HASH, STARKNET_MARKETPLACE_1155_CLASS_HASH, STARKNET_MARKETPLACE_1155_CONTRACT, STARKNET_MARKETPLACE_1155_START_BLOCK, STARKNET_MARKETPLACE_721_CLASS_HASH, STARKNET_MARKETPLACE_721_CONTRACT, STARKNET_MARKETPLACE_721_START_BLOCK, STARKNET_NFTCOMMENTS_CONTRACT, STARKNET_POP_COLLECTION_CLASS_HASH, STARKNET_POP_FACTORY_CONTRACT, SUPPORTED_TOKENS, SUPPORTED_URL_CHAINS, TRUSTED_APP_IP_HEADER, assetHref, buildAssetMetadata, chainFromSlug, chainSlug, coinHref, collectionHref, createBackendProxyHandler, createFailoverFetch, createImageProxyHandler, createRateLimiter, createRpcProxyHandler, encodeU256, formatAmount, getBackendSignedUrl, getCoordinates, getDerivativesTerm, getListableTokens, getService, getServicesByCapability, getStarknetCoordinates, getTokenByAddress, getTokenBySymbol, hasCapability, isPolicyRefusal, isPrivateHost, isPrivateOrInsecureUrl, isSameOrigin, isServiceId, isTransientRpcError, isValidIpfsCidPath, issueAccountSessionToken, issueSiwsToken, listServices, normalizeAddress, normalizeHash, parseAmount, readBodyWithCap, requestIp, resolveAppFeeConfig, resolveConfig, resolveFeeConfig, resolveRemixPolicy, resolveSafeImageContentType, shortenAddress, stringifyBigInts, u256ToBigInt, uploadDirectoryToBackend, uploadFileToBackend, uploadJsonToBackend, validateUrl, verifyAccountSessionToken, verifySiwsToken };
|
|
1732
1940
|
//# sourceMappingURL=index.js.map
|
|
1733
1941
|
//# sourceMappingURL=index.js.map
|