@subql/node-algorand 4.0.5 → 4.0.6-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.
|
@@ -18,8 +18,6 @@ export declare class AlgorandApi {
|
|
|
18
18
|
paginatedTransactions(blockHeight: number, nextToken?: string): Promise<AlgorandTransaction[]>;
|
|
19
19
|
combinePaginateBlock(blockHeight: number): Promise<AlgorandBlock>;
|
|
20
20
|
private constructBlock;
|
|
21
|
-
fetchBlocksArray(blockArray: number[]): Promise<any[]>;
|
|
22
|
-
fetchBlocksBatches(blockArray: number[]): Promise<AlgorandBlock[]>;
|
|
23
21
|
getGenesisHash(): string;
|
|
24
22
|
getChainId(): string;
|
|
25
23
|
getSafeApi(height: number): SafeAPIService;
|
|
@@ -131,12 +131,6 @@ class AlgorandApi {
|
|
|
131
131
|
newBlock.transactions = transactions;
|
|
132
132
|
return newBlock;
|
|
133
133
|
}
|
|
134
|
-
async fetchBlocksArray(blockArray) {
|
|
135
|
-
return Promise.all(blockArray.map(async (height) => this.getBlockByHeight(height)));
|
|
136
|
-
}
|
|
137
|
-
async fetchBlocksBatches(blockArray) {
|
|
138
|
-
return this.fetchBlocksArray(blockArray);
|
|
139
|
-
}
|
|
140
134
|
getGenesisHash() {
|
|
141
135
|
return this.genesisHash;
|
|
142
136
|
}
|
|
@@ -147,16 +141,7 @@ class AlgorandApi {
|
|
|
147
141
|
return new SafeAPIService(this, height);
|
|
148
142
|
}
|
|
149
143
|
async fetchBlocks(blockNums) {
|
|
150
|
-
|
|
151
|
-
for (let i = 0; i < blockNums.length; i++) {
|
|
152
|
-
const cached = this.blockInCache(blockNums[i]);
|
|
153
|
-
if (cached) {
|
|
154
|
-
blocks.push(cached);
|
|
155
|
-
blockNums.splice(i, 1);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
const fetchedBlocks = await this.fetchBlocksBatches(blockNums);
|
|
159
|
-
blocks = [...blocks, ...fetchedBlocks];
|
|
144
|
+
const blocks = await Promise.all(blockNums.map((num) => this.blockInCache(num) ?? this.getBlockByHeight(num)));
|
|
160
145
|
const formattedBlocks = await Promise.all(blocks.map(async (block) => {
|
|
161
146
|
block.hash = await this.getBlockHash(block.round, blocks);
|
|
162
147
|
return (0, utils_algorand_1.formatBlockUtil)(block);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.algorand.js","sourceRoot":"","sources":["../../src/algorand/api.algorand.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;AAEnC,oDAA4B;AAC5B,gDAA4D;AAO5D,sDAA2C;AAC3C,mCAA8B;AAC9B,qDAAuE;AAEvE,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,cAAc,CAAC,CAAC;AAEzC,MAAa,WAAW;IACd,YAAY,CAAU;IACtB,MAAM,CAAU;IACf,GAAG,CAAU;IACd,UAAU,GAAoB,EAAE,CAAC;IACjC,eAAe,GAAG,KAAK,CAAC;IAEhC,YAAoB,QAAgB,EAAE,MAAuB;QAC3D,IAAI,CAAC,GAAG,GAAG,IAAI,iBAAO,CAAC,OAAO,CAC5B,MAAM,CAAC,OAAO,EAAE,CAAC,qBAAqB,CAAC,IAAI,EAAE,EAC7C,QAAQ,EACR,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,oHAAoH;QAC5I,MAAM,CAAC,OAAO,CACf,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CACjB,QAAgB,EAChB,MAAuB;QAEvB,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAE9C,2BAA2B;QAC3B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAEhD,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC/C,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAEvC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAY,WAAW;QACrB,IAAA,gBAAM,EAAC,IAAI,CAAC,YAAY,EAAE,6BAA6B,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,IAAY,KAAK;QACf,IAAA,gBAAM,EAAC,IAAI,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,oBAAoB;QACxB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAE1D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,MAAc;QACnC,IAAI;YACF,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC;YAC1D,OAAO,IAAI,CAAC,cAAc,CAAC,IAAA,mCAAkB,EAAC,SAAS,CAAC,CAAC,CAAC;SAC3D;QAAC,OAAO,KAAU,EAAE;YACnB,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,iCAAiC,CAAC,EAAE;gBAC7D,MAAM,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;gBAExE,OAAO,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;aAC1C;iBAAM;gBACL,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,kCAAkC,MAAM,EAAE,CAAC,CAAC;gBAChE,MAAM,KAAK,CAAC;aACb;SACF;IACH,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,KAAa;QAC/B,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;YACvE,OAAO,IAAI,CAAC,cAAc,CAAC,MAAuB,CAAC,CAAC;SACrD;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC;YAChD,MAAM,CAAC,CAAC;SACT;IACH,CAAC;IAED,KAAK,CAAC,qBAAqB,CACzB,WAAmB,EACnB,SAAkB;QAElB,IAAI;YACF,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG;iBACf,qBAAqB,EAAE;iBACvB,KAAK,CAAC,WAAW,CAAC;iBAClB,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAE/B,IAAI,SAAS,EAAE;gBACb,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;aAChC;YAED,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC;YAC9B;;;;;eAKG;YAEH,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;gBAClC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAC/C,WAAW,EACX,MAAM,CAAC,YAAY,CAAC,CACrB,CAAC;gBACF,OAAO,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;aAC7C;YACD,OAAO,MAAM,CAAC,YAAY,CAAC;SAC5B;QAAC,OAAO,CAAM,EAAE;YACf,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,kCAAkC,CAAC,CAAC;YACpD,MAAM,CAAC,CAAC;SACT;IACH,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,WAAmB;QAC5C,IAAI;YACF,MAAM,CAAC,WAAW,EAAE,4BAA4B,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACpE,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC;gBAC/B,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC;aACxC,CAAC,CAAC;YAEH,OAAO,IAAI,CAAC,cAAc,CAAC;gBACzB,GAAG,IAAA,mCAAkB,EAAC,WAAW,CAAC;gBAClC,YAAY,EAAE,IAAA,mCAAkB,EAAC,4BAA4B,CAAC;aAC/D,CAAC,CAAC;SACJ;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,KAAK,CAAC,4BAA4B,WAAW,EAAE,CAAC,CAAC;YACxD,MAAM,CAAC,CAAC;SACT;IACH,CAAC;IAEO,cAAc,CAAC,KAAoB;QACzC,MAAM,QAAQ,GAAG;YACf,GAAG,KAAK;YACR,sBAAsB,EAAE,CAAC,OAAe,EAAE,EAAE,CAC1C,YAAY,EAAE,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,KAAK,OAAO,CAAC,IAAI,EAAE;YAC1D,MAAM;gBACJ,OAAO,IAAA,aAAI,EAAC,IAAI,EAAE,CAAC,wBAAwB,EAAE,QAAQ,CAAC,CAAC,CAAC;YAC1D,CAAC;SACF,CAAC;QACF,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACvD,GAAG,EAAE;YACL,KAAK,EAAE,QAAQ;YACf,MAAM;gBACJ,OAAO,IAAA,aAAI,EAAC,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;YACzC,CAAC;SACF,CAAC,CAAC,CAAC;QAEJ,sBAAsB;QACtB,QAAQ,CAAC,YAAY,GAAG,YAAY,CAAC;QAErC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,UAAoB;QACzC,OAAO,OAAO,CAAC,GAAG,CAChB,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAChE,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,kBAAkB,CAAC,UAAoB;QAC3C,OAAO,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC3C,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,UAAU,CAAC,MAAc;QACvB,OAAO,IAAI,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IACD,KAAK,CAAC,WAAW,CAAC,SAAmB;QACnC,IAAI,MAAM,GAAoB,EAAE,CAAC;QAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACzC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/C,IAAI,MAAM,EAAE;gBACV,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACpB,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;aACxB;SACF;QAED,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAE/D,MAAM,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,aAAa,CAAC,CAAC;QAEvC,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,GAAG,CACvC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACzB,KAAK,CAAC,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC1D,OAAO,IAAA,gCAAe,EAAC,KAAK,CAAC,CAAC;QAChC,CAAC,CAAC,CACH,CAAC;QAEF,OAAO,eAAe,CAAC;IACzB,CAAC;IAEO,YAAY,CAAC,MAAc;QACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YAC/C,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,EAAE;gBACvC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBACjC,8BAA8B;gBAC9B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7B,OAAO,KAAK,CAAC;aACd;SACF;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,KAAK,CAAC,YAAY,CACxB,KAAa,EACb,MAAuB;QAEvB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;YAC1B,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,GAAG,CAAC,EAAE;gBAC7B,OAAO,KAAK,CAAC,iBAAiB,CAAC;aAChC;SACF;QAED,IAAI;YACF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC5D,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAEnC,OAAO,YAAY,CAAC,iBAAiB,CAAC;SACvC;QAAC,OAAO,CAAC,EAAE;YACV,IAAI,WAAW,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;YACxD,IAAI,YAAY,GAAG,WAAW,CAAC,KAAK,CAAC;YACrC,IAAI,YAAY,IAAI,KAAK,GAAG,CAAC,EAAE;gBAC7B,MAAM,CAAC,CAAC;aACT;YACD,OAAO,YAAY,GAAG,KAAK,GAAG,CAAC,EAAE;gBAC/B,MAAM,IAAA,iBAAK,EAAC,CAAC,CAAC,CAAC,CAAC,wDAAwD;gBACxE,WAAW,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,wDAAwD;gBAC7G,YAAY,GAAG,WAAW,CAAC,KAAK,CAAC;aAClC;SACF;QACD,MAAM,IAAI,KAAK,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;IACjE,CAAC;CACF;AA5OD,kCA4OC;AAED,MAAa,cAAc;IAEL;IAAmC;IAD9C,OAAO,CAAU;IAC1B,YAAoB,GAAgB,EAAmB,MAAc;QAAjD,QAAG,GAAH,GAAG,CAAa;QAAmB,WAAM,GAAN,MAAM,CAAQ;QACnE,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC;IACzB,CAAC;IACD,KAAK,CAAC,QAAQ;QACZ,IAAI;YACF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3D,IAAI,CAAC,KAAK,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,EAAE,CAAC;YACpC,OAAO,KAAK,CAAC;SACd;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;SACtE;IACH,CAAC;IACD,KAAK,CAAC,OAAO;QACX,IAAI;YACF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3D,IAAI,CAAC,KAAK,CAAC,YAAY;gBAAE,MAAM,IAAI,KAAK,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC,YAAY,CAAC;SAC3B;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,IAAI,KAAK,CACb,0DAA0D,CAC3D,CAAC;SACH;IACH,CAAC;CACF;AAzBD,wCAyBC","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport assert from 'assert';\nimport { delay, getLogger, IBlock } from '@subql/node-core';\nimport {\n AlgorandBlock,\n AlgorandTransaction,\n SafeAPI,\n} from '@subql/types-algorand';\nimport { IEndpointConfig } from '@subql/types-core';\nimport algosdk, { Indexer } from 'algosdk';\nimport { omit } from 'lodash';\nimport { camelCaseObjectKey, formatBlockUtil } from './utils.algorand';\n\nconst logger = getLogger('api.algorand');\n\nexport class AlgorandApi {\n private _genesisHash?: string;\n private _chain?: string;\n readonly api: Indexer;\n private blockCache: AlgorandBlock[] = [];\n private paginationLimit = 10000;\n\n private constructor(endpoint: string, config: IEndpointConfig) {\n this.api = new algosdk.Indexer(\n config.headers?.['X-Indexer-API-Token'] ?? '',\n endpoint,\n new URL(endpoint).port, // Specify the port, by default it will be an empty string, we don't want undefined because it then defaults to 8080\n config.headers,\n );\n }\n\n static async create(\n endpoint: string,\n config: IEndpointConfig,\n ): Promise<AlgorandApi> {\n const api = new AlgorandApi(endpoint, config);\n\n // get genesisHash in block\n const block = await api.api.lookupBlock(1).do();\n\n api._genesisHash = block['genesis-hash'] ?? '';\n api._chain = block['genesis-id'] ?? '';\n\n return api;\n }\n\n private get genesisHash(): string {\n assert(this._genesisHash, 'genesisHash not initialized');\n return this._genesisHash;\n }\n\n private get chain(): string {\n assert(this._chain, 'chain not initialized');\n return this._chain;\n }\n\n async getLatestBlockHeader(): Promise<AlgorandBlock> {\n const checkHealth = await this.api.makeHealthCheck().do();\n const block = await this.getHeaderOnly(checkHealth.round);\n\n return block;\n }\n\n async getBlockByHeight(height: number): Promise<AlgorandBlock> {\n try {\n const blockInfo = await this.api.lookupBlock(height).do();\n return this.constructBlock(camelCaseObjectKey(blockInfo));\n } catch (error: any) {\n if (error.message.includes('Max transactions limit exceeded')) {\n logger.warn('Max transactions limit exceeded, paginating transactions');\n\n return this.combinePaginateBlock(height);\n } else {\n logger.error(error, `failed to fetch Block at round ${height}`);\n throw error;\n }\n }\n }\n\n async getHeaderOnly(block: number): Promise<AlgorandBlock> {\n try {\n const result = await this.api.lookupBlock(block).headerOnly(true).do();\n return this.constructBlock(result as AlgorandBlock);\n } catch (e) {\n logger.error('Failed to fetch round header', e);\n throw e;\n }\n }\n\n async paginatedTransactions(\n blockHeight: number,\n nextToken?: string,\n ): Promise<AlgorandTransaction[]> {\n try {\n let req = this.api\n .searchForTransactions()\n .round(blockHeight)\n .limit(this.paginationLimit);\n\n if (nextToken) {\n req = req.nextToken(nextToken);\n }\n\n const result = await req.do();\n /*\n Maximum number of results to return. There could be additional pages even if the limit is not reached.\n https://developer.algorand.org/docs/rest-apis/indexer/#get-v2transactions\n\n Hence, the condition below\n */\n\n if (result.transactions.length > 0) {\n const nextPage = await this.paginatedTransactions(\n blockHeight,\n result['next-token'],\n );\n return result.transactions.concat(nextPage);\n }\n return result.transactions;\n } catch (e: any) {\n logger.error(e, 'Failed to paginated transactions');\n throw e;\n }\n }\n\n async combinePaginateBlock(blockHeight: number): Promise<AlgorandBlock> {\n try {\n const [blockHeader, paginatedTransactionsResults] = await Promise.all([\n this.getHeaderOnly(blockHeight),\n this.paginatedTransactions(blockHeight),\n ]);\n\n return this.constructBlock({\n ...camelCaseObjectKey(blockHeader),\n transactions: camelCaseObjectKey(paginatedTransactionsResults),\n });\n } catch (e) {\n logger.error(`Failed to paginate round ${blockHeight}`);\n throw e;\n }\n }\n\n private constructBlock(block: AlgorandBlock): AlgorandBlock {\n const newBlock = {\n ...block,\n getTransactionsByGroup: (groupId: string) =>\n transactions?.filter((tx) => tx.group === groupId) ?? [],\n toJSON() {\n return omit(this, ['getTransactionsByGroup', 'toJSON']);\n },\n };\n const transactions = newBlock.transactions?.map((tx) => ({\n ...tx,\n block: newBlock,\n toJSON() {\n return omit(this, ['block', 'toJSON']);\n },\n }));\n\n // Update transactions\n newBlock.transactions = transactions;\n\n return newBlock;\n }\n\n async fetchBlocksArray(blockArray: number[]): Promise<any[]> {\n return Promise.all(\n blockArray.map(async (height) => this.getBlockByHeight(height)),\n );\n }\n async fetchBlocksBatches(blockArray: number[]): Promise<AlgorandBlock[]> {\n return this.fetchBlocksArray(blockArray);\n }\n\n getGenesisHash(): string {\n return this.genesisHash;\n }\n\n getChainId(): string {\n return this.chain;\n }\n\n getSafeApi(height: number): SafeAPIService {\n return new SafeAPIService(this, height);\n }\n async fetchBlocks(blockNums: number[]): Promise<IBlock<AlgorandBlock>[]> {\n let blocks: AlgorandBlock[] = [];\n\n for (let i = 0; i < blockNums.length; i++) {\n const cached = this.blockInCache(blockNums[i]);\n if (cached) {\n blocks.push(cached);\n blockNums.splice(i, 1);\n }\n }\n\n const fetchedBlocks = await this.fetchBlocksBatches(blockNums);\n\n blocks = [...blocks, ...fetchedBlocks];\n\n const formattedBlocks = await Promise.all(\n blocks.map(async (block) => {\n block.hash = await this.getBlockHash(block.round, blocks);\n return formatBlockUtil(block);\n }),\n );\n\n return formattedBlocks;\n }\n\n private blockInCache(number: number): AlgorandBlock | undefined {\n for (let i = 0; i < this.blockCache.length; i++) {\n if (this.blockCache[i].round === number) {\n const block = this.blockCache[i];\n //remove block cache once used\n this.blockCache.splice(i, 1);\n return block;\n }\n }\n return undefined;\n }\n\n private async getBlockHash(\n round: number,\n blocks: AlgorandBlock[],\n ): Promise<string> {\n for (const block of blocks) {\n if (block.round === round + 1) {\n return block.previousBlockHash;\n }\n }\n\n try {\n const fetchedBlock = await this.getBlockByHeight(round + 1);\n this.blockCache.push(fetchedBlock);\n\n return fetchedBlock.previousBlockHash;\n } catch (e) {\n let checkHealth = await this.api.makeHealthCheck().do();\n let currentRound = checkHealth.round;\n if (currentRound >= round + 1) {\n throw e;\n }\n while (currentRound < round + 1) {\n await delay(1); // eslint-disable-line @typescript-eslint/await-thenable\n checkHealth = await this.api.makeHealthCheck().do(); // eslint-disable-line @typescript-eslint/await-thenable\n currentRound = checkHealth.round;\n }\n }\n throw new Error(`Unable to get block hash for round ${round}`);\n }\n}\n\nexport class SafeAPIService implements SafeAPI {\n readonly indexer: Indexer;\n constructor(private api: AlgorandApi, private readonly height: number) {\n this.indexer = api.api;\n }\n async getBlock(): Promise<AlgorandBlock> {\n try {\n const block = await this.api.getBlockByHeight(this.height);\n if (!block.round) throw new Error();\n return block;\n } catch (error) {\n throw new Error('ERROR: failed to get block from safe api service.');\n }\n }\n async getTxns(): Promise<AlgorandTransaction[]> {\n try {\n const block = await this.api.getBlockByHeight(this.height);\n if (!block.transactions) throw new Error();\n return block.transactions;\n } catch (error) {\n throw new Error(\n 'ERROR: failed to get transactions from safe api service.',\n );\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"api.algorand.js","sourceRoot":"","sources":["../../src/algorand/api.algorand.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport assert from 'assert';\nimport { delay, getLogger, IBlock } from '@subql/node-core';\nimport {\n AlgorandBlock,\n AlgorandTransaction,\n SafeAPI,\n} from '@subql/types-algorand';\nimport { IEndpointConfig } from '@subql/types-core';\nimport algosdk, { Indexer } from 'algosdk';\nimport { omit } from 'lodash';\nimport { camelCaseObjectKey, formatBlockUtil } from './utils.algorand';\n\nconst logger = getLogger('api.algorand');\n\nexport class AlgorandApi {\n private _genesisHash?: string;\n private _chain?: string;\n readonly api: Indexer;\n private blockCache: AlgorandBlock[] = [];\n private paginationLimit = 10000;\n\n private constructor(endpoint: string, config: IEndpointConfig) {\n this.api = new algosdk.Indexer(\n config.headers?.['X-Indexer-API-Token'] ?? '',\n endpoint,\n new URL(endpoint).port, // Specify the port, by default it will be an empty string, we don't want undefined because it then defaults to 8080\n config.headers,\n );\n }\n\n static async create(\n endpoint: string,\n config: IEndpointConfig,\n ): Promise<AlgorandApi> {\n const api = new AlgorandApi(endpoint, config);\n\n // get genesisHash in block\n const block = await api.api.lookupBlock(1).do();\n\n api._genesisHash = block['genesis-hash'] ?? '';\n api._chain = block['genesis-id'] ?? '';\n\n return api;\n }\n\n private get genesisHash(): string {\n assert(this._genesisHash, 'genesisHash not initialized');\n return this._genesisHash;\n }\n\n private get chain(): string {\n assert(this._chain, 'chain not initialized');\n return this._chain;\n }\n\n async getLatestBlockHeader(): Promise<AlgorandBlock> {\n const checkHealth = await this.api.makeHealthCheck().do();\n const block = await this.getHeaderOnly(checkHealth.round);\n\n return block;\n }\n\n async getBlockByHeight(height: number): Promise<AlgorandBlock> {\n try {\n const blockInfo = await this.api.lookupBlock(height).do();\n\n return this.constructBlock(camelCaseObjectKey(blockInfo));\n } catch (error: any) {\n if (error.message.includes('Max transactions limit exceeded')) {\n logger.warn('Max transactions limit exceeded, paginating transactions');\n\n return this.combinePaginateBlock(height);\n } else {\n logger.error(error, `failed to fetch Block at round ${height}`);\n throw error;\n }\n }\n }\n\n async getHeaderOnly(block: number): Promise<AlgorandBlock> {\n try {\n const result = await this.api.lookupBlock(block).headerOnly(true).do();\n return this.constructBlock(result as AlgorandBlock);\n } catch (e) {\n logger.error('Failed to fetch round header', e);\n throw e;\n }\n }\n\n async paginatedTransactions(\n blockHeight: number,\n nextToken?: string,\n ): Promise<AlgorandTransaction[]> {\n try {\n let req = this.api\n .searchForTransactions()\n .round(blockHeight)\n .limit(this.paginationLimit);\n\n if (nextToken) {\n req = req.nextToken(nextToken);\n }\n\n const result = await req.do();\n /*\n Maximum number of results to return. There could be additional pages even if the limit is not reached.\n https://developer.algorand.org/docs/rest-apis/indexer/#get-v2transactions\n\n Hence, the condition below\n */\n\n if (result.transactions.length > 0) {\n const nextPage = await this.paginatedTransactions(\n blockHeight,\n result['next-token'],\n );\n return result.transactions.concat(nextPage);\n }\n return result.transactions;\n } catch (e: any) {\n logger.error(e, 'Failed to paginated transactions');\n throw e;\n }\n }\n\n async combinePaginateBlock(blockHeight: number): Promise<AlgorandBlock> {\n try {\n const [blockHeader, paginatedTransactionsResults] = await Promise.all([\n this.getHeaderOnly(blockHeight),\n this.paginatedTransactions(blockHeight),\n ]);\n\n return this.constructBlock({\n ...camelCaseObjectKey(blockHeader),\n transactions: camelCaseObjectKey(paginatedTransactionsResults),\n });\n } catch (e) {\n logger.error(`Failed to paginate round ${blockHeight}`);\n throw e;\n }\n }\n\n private constructBlock(block: AlgorandBlock): AlgorandBlock {\n const newBlock = {\n ...block,\n getTransactionsByGroup: (groupId: string) =>\n transactions?.filter((tx) => tx.group === groupId) ?? [],\n toJSON() {\n return omit(this, ['getTransactionsByGroup', 'toJSON']);\n },\n };\n const transactions = newBlock.transactions?.map((tx) => ({\n ...tx,\n block: newBlock,\n toJSON() {\n return omit(this, ['block', 'toJSON']);\n },\n }));\n\n // Update transactions\n newBlock.transactions = transactions;\n\n return newBlock;\n }\n\n getGenesisHash(): string {\n return this.genesisHash;\n }\n\n getChainId(): string {\n return this.chain;\n }\n\n getSafeApi(height: number): SafeAPIService {\n return new SafeAPIService(this, height);\n }\n async fetchBlocks(blockNums: number[]): Promise<IBlock<AlgorandBlock>[]> {\n const blocks = await Promise.all(\n blockNums.map(\n (num) => this.blockInCache(num) ?? this.getBlockByHeight(num),\n ),\n );\n\n const formattedBlocks = await Promise.all(\n blocks.map(async (block) => {\n block.hash = await this.getBlockHash(block.round, blocks);\n return formatBlockUtil(block);\n }),\n );\n\n return formattedBlocks;\n }\n\n private blockInCache(number: number): AlgorandBlock | undefined {\n for (let i = 0; i < this.blockCache.length; i++) {\n if (this.blockCache[i].round === number) {\n const block = this.blockCache[i];\n //remove block cache once used\n this.blockCache.splice(i, 1);\n return block;\n }\n }\n return undefined;\n }\n\n private async getBlockHash(\n round: number,\n blocks: AlgorandBlock[],\n ): Promise<string> {\n for (const block of blocks) {\n if (block.round === round + 1) {\n return block.previousBlockHash;\n }\n }\n\n try {\n const fetchedBlock = await this.getBlockByHeight(round + 1);\n this.blockCache.push(fetchedBlock);\n\n return fetchedBlock.previousBlockHash;\n } catch (e) {\n let checkHealth = await this.api.makeHealthCheck().do();\n let currentRound = checkHealth.round;\n if (currentRound >= round + 1) {\n throw e;\n }\n while (currentRound < round + 1) {\n await delay(1); // eslint-disable-line @typescript-eslint/await-thenable\n checkHealth = await this.api.makeHealthCheck().do(); // eslint-disable-line @typescript-eslint/await-thenable\n currentRound = checkHealth.round;\n }\n }\n throw new Error(`Unable to get block hash for round ${round}`);\n }\n}\n\nexport class SafeAPIService implements SafeAPI {\n readonly indexer: Indexer;\n constructor(private api: AlgorandApi, private readonly height: number) {\n this.indexer = api.api;\n }\n async getBlock(): Promise<AlgorandBlock> {\n try {\n const block = await this.api.getBlockByHeight(this.height);\n if (!block.round) throw new Error();\n return block;\n } catch (error) {\n throw new Error('ERROR: failed to get block from safe api service.');\n }\n }\n async getTxns(): Promise<AlgorandTransaction[]> {\n try {\n const block = await this.api.getBlockByHeight(this.height);\n if (!block.transactions) throw new Error();\n return block.transactions;\n } catch (error) {\n throw new Error(\n 'ERROR: failed to get transactions from safe api service.',\n );\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@subql/node-algorand",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.6-0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Ian He",
|
|
6
6
|
"license": "GPL-3.0",
|
|
@@ -62,5 +62,6 @@
|
|
|
62
62
|
"README.md",
|
|
63
63
|
"CHANGELOG.md",
|
|
64
64
|
"LICENSE"
|
|
65
|
-
]
|
|
65
|
+
],
|
|
66
|
+
"stableVersion": "4.0.5"
|
|
66
67
|
}
|