{"version":3,"sources":["../src/modules/torii-fetcher.ts","../src/marketplace/tokens.ts"],"sourcesContent":["import type { ToriiGrpcClient } from \"@dojoengine/grpc\";\nimport type { ToriiClient } from \"@dojoengine/torii-client\";\n\nexport interface PaginationOptions {\n  limit?: number;\n  cursor?: string;\n  direction?: \"Forward\" | \"Backward\";\n}\n\nexport interface ClientCallbackParams<TNative extends boolean = false> {\n  client: TNative extends true ? ToriiGrpcClient : ToriiClient;\n  signal: AbortSignal;\n}\n\nexport interface FetchToriiOptionsBase {\n  pagination?: PaginationOptions;\n}\n\nexport interface FetchToriiOptionsWithClient<TNative extends boolean = false>\n  extends FetchToriiOptionsBase {\n  /**\n   * Dojo client callback transport.\n   * For SQL transport, use `fetchToriisSql` from `./torii-sql-fetcher`.\n   */\n  client: (\n    params: ClientCallbackParams<TNative>,\n  ) => Promise<any> | void | AsyncGenerator<any, void, unknown>;\n  native?: TNative;\n}\n\nexport type FetchToriiOptions = FetchToriiOptionsWithClient<boolean>;\n\nexport interface FetchToriiResult {\n  data: any[];\n  errors?: Error[];\n  metadata?: {\n    totalEndpoints: number;\n    successfulEndpoints: number;\n    failedEndpoints: number;\n  };\n}\n\nexport interface FetchToriiStreamResult {\n  endpoint: string;\n  data?: any;\n  error?: Error;\n  metadata: {\n    completed: number;\n    total: number;\n    isLast: boolean;\n  };\n}\n\nconst ARCADE_MAIN_PROJECT = \"arcade-main\";\n\nfunction getToriiUrl(project: string): string {\n  const resolvedProject = project || ARCADE_MAIN_PROJECT;\n  return `https://api.cartridge.gg/x/${resolvedProject}/torii`;\n}\n\nasync function fetchFromEndpoint(\n  _endpoint: string,\n  toriiUrl: string,\n  options: FetchToriiOptions,\n  signal: AbortSignal,\n): Promise<any> {\n  if (!options.client) {\n    throw new Error(\n      \"Client callback is required in fetchToriis options. Use fetchToriisSql for SQL queries.\",\n    );\n  }\n\n  const cfg = {\n    toriiUrl,\n    worldAddress: \"0x0\",\n  };\n  const client = options.native\n    ? new (await import(\"@dojoengine/grpc\")).ToriiGrpcClient(cfg)\n    : await new (await import(\"@dojoengine/torii-client\")).ToriiClient(cfg);\n\n  try {\n    return await options.client({\n      client,\n      signal,\n    });\n  } catch (error) {\n    if (error instanceof Error) {\n      throw error;\n    }\n    throw new Error(String(error));\n  }\n  // leave this commented out for now.\n  // TODO: return client instance to free them at the end of caller function\n  // } finally {\n  //   if ('free' in client && typeof client.free === 'function') {\n  //     client.free();\n  //   }\n  // }\n}\n\nexport async function fetchToriis(\n  endpoints: string[],\n  options: FetchToriiOptions,\n): Promise<FetchToriiResult> {\n  const abortController = new AbortController();\n  const signal = abortController.signal;\n\n  const results: any[] = [];\n  const errors: Error[] = [];\n\n  const promises = endpoints.map(async (endpoint) => {\n    const toriiUrl = getToriiUrl(endpoint);\n\n    try {\n      const result = await fetchFromEndpoint(\n        endpoint,\n        toriiUrl,\n        options,\n        signal,\n      );\n      return { success: true as const, data: result, endpoint };\n    } catch (error) {\n      const err =\n        error instanceof Error\n          ? error\n          : new Error(`Failed to fetch from ${endpoint}: ${String(error)}`);\n      return { success: false as const, error: err, endpoint };\n    }\n  });\n\n  const responses = await Promise.allSettled(promises);\n\n  let successCount = 0;\n  let failCount = 0;\n\n  for (const response of responses) {\n    if (response.status === \"fulfilled\") {\n      const result = response.value;\n      if (result.success) {\n        results.push(result.data);\n        successCount++;\n        continue;\n      }\n      errors.push(result.error);\n      failCount++;\n      continue;\n    }\n    const reason = response.reason as any;\n    errors.push(\n      new Error(`Promise rejected: ${reason?.message || \"Unknown error\"}`),\n    );\n    failCount++;\n  }\n\n  return {\n    data: results,\n    errors: errors.length > 0 ? errors : undefined,\n    metadata: {\n      totalEndpoints: endpoints.length,\n      successfulEndpoints: successCount,\n      failedEndpoints: failCount,\n    },\n  };\n}\n\nexport async function* fetchToriisStream(\n  endpoints: string[],\n  options: FetchToriiOptions,\n): AsyncGenerator<FetchToriiStreamResult, void, unknown> {\n  const abortController = new AbortController();\n  const signal = abortController.signal;\n  const totalEndpoints = endpoints.length;\n\n  if (totalEndpoints === 0) {\n    return;\n  }\n\n  // Create promises with their indices\n  const pendingPromises = endpoints.map(async (endpoint, index) => {\n    const toriiUrl = getToriiUrl(endpoint);\n\n    try {\n      const result = await fetchFromEndpoint(\n        endpoint,\n        toriiUrl,\n        options,\n        signal,\n      );\n      return { index, success: true as const, data: result, endpoint };\n    } catch (error) {\n      const err =\n        error instanceof Error\n          ? error\n          : new Error(`Failed to fetch from ${endpoint}: ${String(error)}`);\n      return { index, success: false as const, error: err, endpoint };\n    }\n  });\n\n  let completed = 0;\n  const remainingIndices = new Set(\n    Array.from({ length: totalEndpoints }, (_, i) => i),\n  );\n\n  // Process promises as they complete using Promise.race\n  while (remainingIndices.size > 0) {\n    // Create a map of active promises\n    const activePromises = Array.from(remainingIndices).map((index) =>\n      pendingPromises[index].then((result) => ({\n        ...result,\n        promiseIndex: index,\n      })),\n    );\n\n    try {\n      // Wait for the first promise to complete\n      const result = await Promise.race(activePromises);\n\n      // Remove completed promise from remaining set\n      remainingIndices.delete(result.promiseIndex);\n      completed++;\n\n      // Check if result.data is an AsyncGenerator\n      if (result.success && result.data?.[Symbol.asyncIterator]) {\n        // Handle AsyncGenerator case - yield each item as it comes\n        for await (const item of result.data) {\n          yield {\n            endpoint: result.endpoint,\n            data: item,\n            error: undefined,\n            metadata: {\n              completed,\n              total: totalEndpoints,\n              isLast: completed === totalEndpoints,\n            },\n          };\n        }\n      } else {\n        // Handle regular data case (arrays, objects)\n        yield {\n          endpoint: result.endpoint,\n          data: result.success ? result.data : undefined,\n          error: result.success ? undefined : result.error,\n          metadata: {\n            completed,\n            total: totalEndpoints,\n            isLast: completed === totalEndpoints,\n          },\n        };\n      }\n    } catch (error) {\n      // Handle unexpected errors\n      completed++;\n      yield {\n        endpoint: \"unknown\",\n        error: error instanceof Error ? error : new Error(String(error)),\n        metadata: {\n          completed,\n          total: totalEndpoints,\n          isLast: completed === totalEndpoints,\n        },\n      };\n      break;\n    }\n  }\n}\n","import { addAddressPadding } from \"starknet\";\nimport type {\n  AttributeFilter,\n  ToriiClient,\n  Token as ToriiToken,\n} from \"@dojoengine/torii-wasm/types\";\nimport {\n  fetchToriis,\n  type ClientCallbackParams,\n} from \"../modules/torii-fetcher\";\nimport type {\n  CollectionTokensError,\n  CollectionTokensPage,\n  FetchCollectionTokensOptions,\n  FetchCollectionTokensResult,\n  FetchTokenBalancesOptions,\n  FetchTokenBalancesResult,\n  TokenBalancesError,\n  TokenBalancesPage,\n} from \"./types\";\nimport {\n  DEFAULT_PROJECT_ID,\n  normalizeAttributeFilters,\n  normalizeTokens,\n  resolveProjects,\n} from \"./utils\";\n\ntype TokenPage = Awaited<ReturnType<ToriiClient[\"getTokens\"]>>;\n\nconst DEFAULT_LIMIT = 100;\n\nconst normalizeTokenIdsForQuery = (tokenIds?: string[]): string[] => {\n  if (!tokenIds || tokenIds.length === 0) return [];\n  return tokenIds\n    .map(addAddressPadding)\n    .map((id) => (id.startsWith(\"0x\") ? id.slice(2) : id))\n    .filter((id) => id.length > 0);\n};\n\nexport async function fetchCollectionTokens(\n  options: FetchCollectionTokensOptions,\n): Promise<FetchCollectionTokensResult> {\n  const {\n    address,\n    project,\n    cursor,\n    attributeFilters,\n    tokenIds,\n    limit = DEFAULT_LIMIT,\n    fetchImages = false,\n    resolveTokenImage,\n  } = options;\n\n  const projectIds = resolveProjects(\n    project ? [project] : undefined,\n    options.defaultProjectId ?? DEFAULT_PROJECT_ID,\n  );\n  const projectId = projectIds[0];\n  const filters: AttributeFilter[] =\n    normalizeAttributeFilters(attributeFilters);\n  const normalizedTokenIds = normalizeTokenIdsForQuery(tokenIds);\n\n  try {\n    const response = await fetchToriis([projectId], {\n      client: async ({ client }: ClientCallbackParams) => {\n        return client.getTokens({\n          contract_addresses: [addAddressPadding(address)],\n          token_ids: normalizedTokenIds,\n          attribute_filters: filters,\n          pagination: {\n            limit,\n            cursor: cursor ?? undefined,\n            direction: \"Forward\",\n            order_by: [],\n          },\n        });\n      },\n    });\n\n    if (response.errors && response.errors.length > 0) {\n      const err = response.errors[0];\n      const collectionError: CollectionTokensError = {\n        error: err,\n      };\n      return {\n        page: null,\n        error: collectionError,\n      };\n    }\n\n    const pages = response.data as TokenPage[];\n    let nextCursor: string | null = null;\n    const normalizedTokens: Array<ToriiToken> = [];\n\n    for (const page of pages) {\n      nextCursor = page.next_cursor ?? null;\n      if (!page.items.length) continue;\n      normalizedTokens.push(...page.items);\n    }\n\n    const enriched = await normalizeTokens(normalizedTokens, projectId, {\n      fetchImages,\n      resolveTokenImage,\n    });\n\n    const page: CollectionTokensPage = {\n      tokens: enriched,\n      nextCursor,\n    };\n\n    return {\n      page,\n      error: null,\n    };\n  } catch (error) {\n    const err =\n      error instanceof Error\n        ? error\n        : new Error(\n            typeof error === \"string\"\n              ? error\n              : \"Failed to fetch collection tokens\",\n          );\n    const collectionError: CollectionTokensError = {\n      error: err,\n    };\n    return {\n      page: null,\n      error: collectionError,\n    };\n  }\n}\n\ntype TokenBalancePage = Awaited<ReturnType<ToriiClient[\"getTokenBalances\"]>>;\n\nexport async function fetchTokenBalances(\n  options: FetchTokenBalancesOptions,\n): Promise<FetchTokenBalancesResult> {\n  const {\n    project,\n    contractAddresses = [],\n    accountAddresses = [],\n    tokenIds = [],\n    cursor,\n    limit = DEFAULT_LIMIT,\n  } = options;\n\n  const projectIds = resolveProjects(\n    project ? [project] : undefined,\n    options.defaultProjectId ?? DEFAULT_PROJECT_ID,\n  );\n  const projectId = projectIds[0];\n\n  const normalizedContractAddresses = contractAddresses.map(addAddressPadding);\n  const normalizedAccountAddresses = accountAddresses.map(addAddressPadding);\n  const normalizedTokenIds = normalizeTokenIdsForQuery(tokenIds);\n\n  try {\n    const response = await fetchToriis([projectId], {\n      client: async ({ client }: ClientCallbackParams) => {\n        return client.getTokenBalances({\n          contract_addresses: normalizedContractAddresses,\n          account_addresses: normalizedAccountAddresses,\n          token_ids: normalizedTokenIds,\n          pagination: {\n            limit,\n            cursor: cursor ?? undefined,\n            direction: \"Forward\",\n            order_by: [],\n          },\n        });\n      },\n    });\n\n    if (response.errors && response.errors.length > 0) {\n      const err = response.errors[0];\n      const balancesError: TokenBalancesError = {\n        error: err,\n      };\n      return {\n        page: null,\n        error: balancesError,\n      };\n    }\n\n    const pages = response.data as TokenBalancePage[];\n    let nextCursor: string | null = null;\n    const balances: TokenBalancePage[\"items\"] = [];\n\n    for (const page of pages) {\n      nextCursor = page.next_cursor ?? null;\n      if (!page.items.length) continue;\n      balances.push(...page.items);\n    }\n\n    const page: TokenBalancesPage = {\n      balances,\n      nextCursor,\n    };\n\n    return {\n      page,\n      error: null,\n    };\n  } catch (error) {\n    const err =\n      error instanceof Error\n        ? error\n        : new Error(\n            typeof error === \"string\"\n              ? error\n              : \"Failed to fetch token balances\",\n          );\n    const balancesError: TokenBalancesError = {\n      error: err,\n    };\n    return {\n      page: null,\n      error: balancesError,\n    };\n  }\n}\n"],"mappings":"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","names":["page"]}