{"version":3,"file":"sort_xyz_blockchain.cjs","names":["BaseDocumentLoader","Document"],"sources":["../../../src/document_loaders/web/sort_xyz_blockchain.ts"],"sourcesContent":["import { Document } from \"@langchain/core/documents\";\nimport { BaseDocumentLoader } from \"@langchain/core/document_loaders/base\";\n\n/**\n * See https://docs.sort.xyz/docs/api-keys to get your free Sort API key.\n * See https://docs.sort.xyz for more information on the available queries.\n * See https://docs.sort.xyz/reference for more information about Sort's REST API.\n */\n\nexport interface Query {\n  type: \"NFTMetadata\" | \"latestTransactions\";\n  contractAddress: string;\n  blockchain: \"ethereum\" | \"polygon\" | \"goerli\";\n  limit?: number;\n}\n\n/**\n * Interface representing the parameters for the SortXYZBlockchainLoader\n * class.\n */\nexport interface SortXYZBlockchainLoaderParams {\n  apiKey: string;\n  query: Query | string;\n}\n\n/**\n * Interface representing the response from the SortXYZ API.\n */\nexport interface SortXYZBlockchainAPIResponse {\n  code: number;\n  data: {\n    durationMs: number;\n    id: string;\n    query: string;\n    records: Record<string, unknown>[];\n    recordCount: number;\n  };\n}\n\n/**\n * Class representing a document loader for loading data from the SortXYZ\n * blockchain using the SortXYZ API.\n * @example\n * ```typescript\n * const blockchainLoader = new SortXYZBlockchainLoader({\n *   apiKey: \"YOUR_SORTXYZ_API_KEY\",\n *   query: {\n *     type: \"NFTMetadata\",\n *     blockchain: \"ethereum\",\n *     contractAddress: \"0x887F3909C14DAbd9e9510128cA6cBb448E932d7f\".toLowerCase(),\n *   },\n * });\n *\n * const blockchainData = await blockchainLoader.load();\n *\n * const prompt =\n *   \"Describe the character with the attributes from the following json document in a 4 sentence story. \";\n * const model = new ChatOpenAI({ model: \"gpt-4o-mini\", temperature: 0.9 })\n * const response = await model.invoke(\n *   prompt + JSON.stringify(blockchainData[0], null, 2),\n * );\n * console.log(`user > ${prompt}`);\n * console.log(`chatgpt > ${response}`);\n * ```\n */\nexport class SortXYZBlockchainLoader extends BaseDocumentLoader {\n  public readonly contractAddress: string;\n\n  public readonly blockchain: string;\n\n  public readonly apiKey: string;\n\n  public readonly queryType: string;\n\n  public readonly sql: string;\n\n  public readonly limit: number;\n\n  constructor({ apiKey, query }: SortXYZBlockchainLoaderParams) {\n    super();\n\n    if (!apiKey) {\n      throw new Error(\n        `apiKey is required! Head over to https://docs.sort.xyz/docs/api-keys to get your free Sort API key.`\n      );\n    }\n\n    this.apiKey = apiKey;\n\n    if (typeof query === \"string\") {\n      this.sql = query;\n    } else {\n      this.contractAddress = query.contractAddress.toLowerCase();\n      this.blockchain = query.blockchain;\n      this.queryType = query.type;\n      this.limit = query.limit ?? 100;\n    }\n  }\n\n  /**\n   * Method that loads the data from the SortXYZ blockchain based on the\n   * specified query parameters. It makes requests to the SortXYZ API and\n   * returns an array of Documents representing the retrieved data.\n   * @returns Promise<Document[]> - An array of Documents representing the retrieved data.\n   */\n  public async load(): Promise<Document[]> {\n    if (this.limit > 1000) {\n      throw new Error(\n        `Limit is set too high. Please set limit to 1000 or lower.`\n      );\n    }\n\n    const docs: Document[] = [];\n    let queryOffset = 0;\n\n    while (true) {\n      let query = \"\";\n\n      if (this.sql) {\n        query = this.sql;\n      } else if (this.queryType === \"NFTMetadata\") {\n        // All parameters here are user defined\n        query = `SELECT * FROM ${this.blockchain}.nft_metadata WHERE contract_address = '${this.contractAddress}' ORDER BY token_id DESC LIMIT ${this.limit} OFFSET ${queryOffset}`;\n      } else if (this.queryType === \"latestTransactions\") {\n        // All parameters here are user defined\n        query = `SELECT * FROM ${this.blockchain}.transaction t, ethereum.block b WHERE t.to_address = '${this.contractAddress}' AND b.id=t.block_id ORDER BY b.timestamp DESC LIMIT ${this.limit} OFFSET ${queryOffset}`;\n      }\n\n      try {\n        const response = await fetch(\"https://api.sort.xyz/v1/queries/run\", {\n          method: \"POST\",\n          headers: {\n            \"x-api-key\": this.apiKey as string,\n            Accept: \"application/json\",\n            \"Content-Type\": \"application/json\",\n          },\n          body: JSON.stringify({ query }),\n        });\n\n        const fullResponse = await response.json();\n\n        // Reached the end, no more records\n        if (\n          fullResponse &&\n          fullResponse.data &&\n          fullResponse.data.records.length === 0\n        ) {\n          break;\n        }\n\n        const data = fullResponse?.data || [];\n\n        for (let i = 0; i < data.records.length; i += 1) {\n          const doc = new Document({\n            pageContent: JSON.stringify(data.records[i], null, 2),\n            metadata: {\n              row: i,\n            },\n          });\n\n          docs.push(doc);\n        }\n\n        queryOffset += this.limit;\n\n        if (queryOffset >= this.limit || this.sql) {\n          break;\n        }\n      } catch (error) {\n        console.error(\"Error:\", error);\n      }\n    }\n\n    return docs;\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiEA,IAAa,0BAAb,cAA6CA,sCAAAA,mBAAmB;CAC9D;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA,YAAY,EAAE,QAAQ,SAAwC;AAC5D,SAAO;AAEP,MAAI,CAAC,OACH,OAAM,IAAI,MACR,sGACD;AAGH,OAAK,SAAS;AAEd,MAAI,OAAO,UAAU,SACnB,MAAK,MAAM;OACN;AACL,QAAK,kBAAkB,MAAM,gBAAgB,aAAa;AAC1D,QAAK,aAAa,MAAM;AACxB,QAAK,YAAY,MAAM;AACvB,QAAK,QAAQ,MAAM,SAAS;;;;;;;;;CAUhC,MAAa,OAA4B;AACvC,MAAI,KAAK,QAAQ,IACf,OAAM,IAAI,MACR,4DACD;EAGH,MAAM,OAAmB,EAAE;EAC3B,IAAI,cAAc;AAElB,SAAO,MAAM;GACX,IAAI,QAAQ;AAEZ,OAAI,KAAK,IACP,SAAQ,KAAK;YACJ,KAAK,cAAc,cAE5B,SAAQ,iBAAiB,KAAK,WAAW,0CAA0C,KAAK,gBAAgB,iCAAiC,KAAK,MAAM,UAAU;YACrJ,KAAK,cAAc,qBAE5B,SAAQ,iBAAiB,KAAK,WAAW,yDAAyD,KAAK,gBAAgB,wDAAwD,KAAK,MAAM,UAAU;AAGtM,OAAI;IAWF,MAAM,eAAe,OAVJ,MAAM,MAAM,uCAAuC;KAClE,QAAQ;KACR,SAAS;MACP,aAAa,KAAK;MAClB,QAAQ;MACR,gBAAgB;MACjB;KACD,MAAM,KAAK,UAAU,EAAE,OAAO,CAAC;KAChC,CAAC,EAEkC,MAAM;AAG1C,QACE,gBACA,aAAa,QACb,aAAa,KAAK,QAAQ,WAAW,EAErC;IAGF,MAAM,OAAO,cAAc,QAAQ,EAAE;AAErC,SAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK,GAAG;KAC/C,MAAM,MAAM,IAAIC,0BAAAA,SAAS;MACvB,aAAa,KAAK,UAAU,KAAK,QAAQ,IAAI,MAAM,EAAE;MACrD,UAAU,EACR,KAAK,GACN;MACF,CAAC;AAEF,UAAK,KAAK,IAAI;;AAGhB,mBAAe,KAAK;AAEpB,QAAI,eAAe,KAAK,SAAS,KAAK,IACpC;YAEK,OAAO;AACd,YAAQ,MAAM,UAAU,MAAM;;;AAIlC,SAAO"}