@trufnetwork/sdk-js 0.4.10 → 0.5.1

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.
Files changed (50) hide show
  1. package/README.md +94 -0
  2. package/dist/cjs/client/client.cjs +11 -0
  3. package/dist/cjs/client/client.cjs.map +2 -2
  4. package/dist/cjs/client/getLastTransactions.cjs +45 -38
  5. package/dist/cjs/client/getLastTransactions.cjs.map +2 -2
  6. package/dist/cjs/contracts-api/action.cjs +8 -2
  7. package/dist/cjs/contracts-api/action.cjs.map +2 -2
  8. package/dist/cjs/contracts-api/attestationAction.cjs +322 -0
  9. package/dist/cjs/contracts-api/attestationAction.cjs.map +7 -0
  10. package/dist/cjs/index.common.cjs +2 -0
  11. package/dist/cjs/index.common.cjs.map +2 -2
  12. package/dist/cjs/internal.cjs +2 -0
  13. package/dist/cjs/internal.cjs.map +2 -2
  14. package/dist/cjs/types/attestation.cjs +297 -0
  15. package/dist/cjs/types/attestation.cjs.map +7 -0
  16. package/dist/cjs/util/AttestationEncoding.cjs +157 -0
  17. package/dist/cjs/util/AttestationEncoding.cjs.map +7 -0
  18. package/dist/esm/client/client.mjs +11 -0
  19. package/dist/esm/client/client.mjs.map +2 -2
  20. package/dist/esm/client/getLastTransactions.mjs +45 -38
  21. package/dist/esm/client/getLastTransactions.mjs.map +2 -2
  22. package/dist/esm/contracts-api/action.mjs +8 -2
  23. package/dist/esm/contracts-api/action.mjs.map +2 -2
  24. package/dist/esm/contracts-api/attestationAction.mjs +303 -0
  25. package/dist/esm/contracts-api/attestationAction.mjs.map +7 -0
  26. package/dist/esm/index.common.mjs +2 -0
  27. package/dist/esm/index.common.mjs.map +2 -2
  28. package/dist/esm/internal.mjs +2 -0
  29. package/dist/esm/internal.mjs.map +2 -2
  30. package/dist/esm/types/attestation.mjs +275 -0
  31. package/dist/esm/types/attestation.mjs.map +7 -0
  32. package/dist/esm/util/AttestationEncoding.mjs +135 -0
  33. package/dist/esm/util/AttestationEncoding.mjs.map +7 -0
  34. package/dist/tsconfig.build.tsbuildinfo +1 -1
  35. package/dist/types/client/client.d.ts +6 -0
  36. package/dist/types/client/client.d.ts.map +1 -1
  37. package/dist/types/client/getLastTransactions.d.ts.map +1 -1
  38. package/dist/types/contracts-api/action.d.ts +8 -2
  39. package/dist/types/contracts-api/action.d.ts.map +1 -1
  40. package/dist/types/contracts-api/attestationAction.d.ts +131 -0
  41. package/dist/types/contracts-api/attestationAction.d.ts.map +1 -0
  42. package/dist/types/index.common.d.ts +2 -0
  43. package/dist/types/index.common.d.ts.map +1 -1
  44. package/dist/types/internal.d.ts +2 -0
  45. package/dist/types/internal.d.ts.map +1 -1
  46. package/dist/types/types/attestation.d.ts +155 -0
  47. package/dist/types/types/attestation.d.ts.map +1 -0
  48. package/dist/types/util/AttestationEncoding.d.ts +28 -0
  49. package/dist/types/util/AttestationEncoding.d.ts.map +1 -0
  50. package/package.json +2 -2
package/README.md CHANGED
@@ -200,6 +200,97 @@ await streamAction.allowReadWallet(
200
200
  - Weights in composed streams must sum to 1.0.
201
201
  - Streams can be made public or private, with fine-grained access control.
202
202
 
203
+
204
+ ### Data Attestations
205
+
206
+ Data attestations enable validators to cryptographically sign query results, providing verifiable proofs that can be consumed by smart contracts and external applications.
207
+
208
+ #### Requesting an Attestation
209
+
210
+ ```typescript
211
+ // Load the attestation action
212
+ const attestationAction = client.loadAttestationAction();
213
+
214
+ // Request a signed attestation of query results
215
+ const result = await attestationAction.requestAttestation({
216
+ dataProvider: "0x4710a8d8f0d845da110086812a32de6d90d7ff5c",
217
+ streamId: "stai0000000000000000000000000000",
218
+ actionName: "get_record", // Action to attest
219
+ args: [
220
+ "0x4710a8d8f0d845da110086812a32de6d90d7ff5c",
221
+ "stai0000000000000000000000000000",
222
+ Math.floor(Date.now() / 1000) - 86400, // from: 1 day ago
223
+ Math.floor(Date.now() / 1000), // to: now
224
+ null, // frozen_at
225
+ false, // use_cache
226
+ ],
227
+ encryptSig: false, // Encryption not implemented in MVP
228
+ maxFee: 1000000, // Maximum fee willing to pay
229
+ });
230
+
231
+ console.log(`Request TX ID: ${result.requestTxId}`);
232
+ ```
233
+
234
+ #### Retrieving a Signed Attestation
235
+
236
+ The leader validator signs attestations asynchronously after a few blocks. Poll to retrieve the signed payload:
237
+
238
+ ```typescript
239
+ // Wait for transaction confirmation
240
+ await client.waitForTx(result.requestTxId);
241
+
242
+ // Poll for signature (with retry logic)
243
+ let signed = null;
244
+ for (let i = 0; i < 15; i++) {
245
+ try {
246
+ signed = await attestationAction.getSignedAttestation({
247
+ requestTxId: result.requestTxId,
248
+ });
249
+ if (signed.payload.length > 65) break; // Got signature
250
+ } catch (e) {
251
+ await new Promise(resolve => setTimeout(resolve, 2000));
252
+ }
253
+ }
254
+
255
+ console.log(`Signed payload: ${signed.payload.length} bytes`);
256
+ ```
257
+
258
+ #### Listing Attestations
259
+
260
+ ```typescript
261
+ // Get your wallet address as bytes
262
+ const myAddress = client.address().getAddress();
263
+ const myAddressBytes = new Uint8Array(Buffer.from(myAddress.slice(2), "hex"));
264
+
265
+ // List your recent attestations
266
+ const attestations = await attestationAction.listAttestations({
267
+ requester: myAddressBytes,
268
+ limit: 10,
269
+ orderBy: "created_height desc",
270
+ });
271
+
272
+ attestations.forEach(att => {
273
+ console.log(`TX: ${att.requestTxId}, Signed: ${att.signedHeight ? "Yes" : "Pending"}`);
274
+ });
275
+ ```
276
+
277
+ #### Attestation Payload Structure
278
+
279
+ The signed attestation payload is a binary blob containing:
280
+ 1. Version (1 byte)
281
+ 2. Algorithm (1 byte, 0 = secp256k1)
282
+ 3. Block height (8 bytes)
283
+ 4. Data provider (20 bytes, length-prefixed)
284
+ 5. Stream ID (32 bytes, length-prefixed)
285
+ 6. Action ID (2 bytes)
286
+ 7. Arguments (variable, length-prefixed)
287
+ 8. Result (variable, length-prefixed)
288
+ 9. Signature (65 bytes, secp256k1)
289
+
290
+ This payload can be passed to EVM smart contracts for on-chain verification using `ecrecover`.
291
+
292
+ For a complete example, see [examples/attestation](./examples/attestation).
293
+
203
294
  ### Transaction Lifecycle and Best Practices ⚠️
204
295
 
205
296
  **Critical Understanding**: TN operations return success when transactions enter the mempool, NOT when they're executed on-chain. For operations where order matters, you must wait for transactions to be mined before proceeding.
@@ -335,6 +426,9 @@ For other bundlers or serverless platforms, consult their documentation on modul
335
426
  | Get stream data | `streamAction.getRecord({stream, from, to})` |
336
427
  | Set stream taxonomy | `composedAction.setTaxonomy({stream, taxonomyItems, startDate})` |
337
428
  | Get stream taxonomy | `composedAction.getTaxonomiesForStreams({streams, latestOnly})` |
429
+ | Request attestation | `attestationAction.requestAttestation({dataProvider, streamId, actionName, args, encryptSig, maxFee})` |
430
+ | Get signed attestation | `attestationAction.getSignedAttestation({requestTxId})` |
431
+ | List attestations | `attestationAction.listAttestations({requester, limit, offset, orderBy})` |
338
432
  | Destroy stream | `client.destroyStream(streamLocator)` |
339
433
 
340
434
  **Safe Operation Pattern:**
@@ -33,6 +33,7 @@ var import_EthereumAddress = require("../util/EthereumAddress.cjs");
33
33
  var import_listStreams = require("./listStreams.cjs");
34
34
  var import_getLastTransactions = require("./getLastTransactions.cjs");
35
35
  var import_roleManagement = require("../contracts-api/roleManagement.cjs");
36
+ var import_attestationAction = require("../contracts-api/attestationAction.cjs");
36
37
  var BaseTNClient = class {
37
38
  kwilClient;
38
39
  signerInfo;
@@ -162,6 +163,16 @@ var BaseTNClient = class {
162
163
  this.getKwilSigner()
163
164
  );
164
165
  }
166
+ /**
167
+ * Loads the attestation action API, permitting attestation operations.
168
+ * @returns An instance of AttestationAction.
169
+ */
170
+ loadAttestationAction() {
171
+ return new import_attestationAction.AttestationAction(
172
+ this.getKwilClient(),
173
+ this.getKwilSigner()
174
+ );
175
+ }
165
176
  /**
166
177
  * Creates a new stream locator.
167
178
  * @param streamId - The ID of the stream.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/client/client.ts"],
4
- "sourcesContent": ["import { Client, KwilSigner, NodeKwil, WebKwil, Types, EnvironmentType } from \"@trufnetwork/kwil-js\";\nimport { ComposedAction, ListTaxonomiesByHeightParams, GetTaxonomiesForStreamsParams, TaxonomyQueryResult } from \"../contracts-api/composedAction\";\nimport { deployStream } from \"../contracts-api/deployStream\";\nimport { deleteStream } from \"../contracts-api/deleteStream\";\nimport { PrimitiveAction } from \"../contracts-api/primitiveAction\";\nimport { Action, ListMetadataByHeightParams, MetadataQueryResult } from \"../contracts-api/action\";\nimport { StreamType } from \"../contracts-api/contractValues\";\nimport { StreamLocator, TNStream } from \"../types/stream\";\nimport { EthereumAddress } from \"../util/EthereumAddress\";\nimport { StreamId } from \"../util/StreamId\";\nimport { listStreams } from \"./listStreams\";\nimport { getLastTransactions } from \"./getLastTransactions\";\nimport { RoleManagement } from \"../contracts-api/roleManagement\";\nimport { OwnerIdentifier } from \"../types/role\";\n\nexport interface SignerInfo {\n // we need to have the address upfront to create the KwilSigner, instead of relying on the signer to return it asynchronously\n address: string;\n signer: Types.EthSigner;\n}\n\nexport type TNClientOptions = {\n endpoint: string;\n signerInfo: SignerInfo;\n} & Omit<Types.KwilConfig, \"kwilProvider\">;\n\nexport interface ListStreamsInput {\n dataProvider?: string;\n limit?: number;\n offset?: number;\n orderBy?: string;\n blockHeight?: number;\n}\n\n/**\n * @param dataProvider optional address; when omitted or null, returns for all providers\n * @param limitSize max rows to return (default 6, max 100)\n */\nexport interface GetLastTransactionsInput {\n dataProvider?: string;\n limitSize?: number;\n}\n\nexport abstract class BaseTNClient<T extends EnvironmentType> {\n protected kwilClient: Types.Kwil<T> | undefined;\n protected signerInfo: SignerInfo;\n\n protected constructor(options: TNClientOptions) {\n this.signerInfo = options.signerInfo;\n }\n\n /**\n * Waits for a transaction to be mined by TN.\n * @param txHash - The transaction hash to wait for.\n * @param timeout - The timeout in milliseconds.\n * @returns A promise that resolves to the transaction info receipt.\n */\n async waitForTx(txHash: string, timeout = 12000): Promise<Types.TxInfoReceipt> {\n return new Promise<Types.TxInfoReceipt>(async (resolve, reject) => {\n const interval = setInterval(async () => {\n const receipt = await this.getKwilClient()\n [\"txInfoClient\"](txHash)\n .catch(() => ({ data: undefined, status: undefined }));\n switch (receipt.status) {\n case 200:\n if (receipt.data?.tx_result?.log !== undefined && receipt.data?.tx_result?.log.includes(\"ERROR\")) {\n reject(\n new Error(\n `Transaction failed: status ${receipt.status} : log message ${receipt.data?.tx_result.log}`,\n ))\n } else {\n resolve(receipt.data!);\n }\n break;\n case undefined:\n break;\n default:\n reject(\n new Error(\n `Transaction failed: status ${receipt.status} : log message ${receipt.data?.tx_result.log}`,\n ),\n );\n }\n }, 1000);\n setTimeout(() => {\n clearInterval(interval);\n reject(new Error(\"Transaction failed: Timeout\"));\n }, timeout);\n });\n }\n\n /**\n * Returns the Kwil signer used by the client.\n * @returns An instance of KwilSigner.\n */\n getKwilSigner(): KwilSigner {\n return new KwilSigner(\n this.signerInfo.signer,\n this.address().getAddress(),\n );\n }\n\n /**\n * Returns the Kwil client used by the client.\n * @returns An instance of Kwil.\n * @throws If the Kwil client is not initialized.\n */\n getKwilClient(): Types.Kwil<EnvironmentType> {\n if (!this.kwilClient) {\n throw new Error(\"Kwil client not initialized\");\n }\n return this.kwilClient;\n }\n\n /**\n * Deploys a new stream.\n * @param streamId - The ID of the stream to deploy.\n * @param streamType - The type of the stream.\n * @param synchronous - Whether the deployment should be synchronous.\n * @param contractVersion\n * @returns A promise that resolves to a generic response containing the transaction receipt.\n */\n async deployStream(\n streamId: StreamId,\n streamType: StreamType,\n synchronous?: boolean,\n ): Promise<Types.GenericResponse<Types.TxReceipt>> {\n return await deployStream({\n streamId,\n streamType,\n synchronous,\n kwilClient: this.getKwilClient(),\n kwilSigner: this.getKwilSigner(),\n });\n }\n\n /**\n * Destroys a stream.\n * @param stream - The StreamLocator of the stream to destroy.\n * @param synchronous - Whether the destruction should be synchronous.\n * @returns A promise that resolves to a generic response containing the transaction receipt.\n */\n async destroyStream(\n stream: StreamLocator,\n synchronous?: boolean,\n ): Promise<Types.GenericResponse<Types.TxReceipt>> {\n return await deleteStream({\n stream,\n synchronous,\n kwilClient: this.getKwilClient(),\n kwilSigner: this.getKwilSigner(),\n });\n }\n\n /**\n * Loads an already deployed stream, permitting its API usage.\n * @returns An instance of IStream.\n */\n loadAction(): Action {\n return new Action(\n this.getKwilClient() as WebKwil | NodeKwil,\n this.getKwilSigner(),\n );\n }\n\n /**\n * Loads a primitive stream.\n * @returns An instance of IPrimitiveStream.\n */\n loadPrimitiveAction(): PrimitiveAction {\n return PrimitiveAction.fromStream(this.loadAction());\n }\n\n /**\n * Loads a composed stream.\n * @returns An instance of IComposedStream.\n */\n loadComposedAction(): ComposedAction {\n return ComposedAction.fromStream(this.loadAction());\n }\n\n /**\n * Loads the role management contract API, permitting its RBAC usage.\n */\n loadRoleManagementAction(): RoleManagement {\n return RoleManagement.fromClient(\n this.getKwilClient() as WebKwil | NodeKwil,\n this.getKwilSigner(),\n );\n }\n\n /**\n * Creates a new stream locator.\n * @param streamId - The ID of the stream.\n * @returns A StreamLocator object.\n */\n ownStreamLocator(streamId: StreamId): StreamLocator {\n return {\n streamId,\n dataProvider: this.address(),\n };\n }\n\n /**\n * Returns the address of the signer used by the client.\n * @returns An instance of EthereumAddress.\n */\n address(): EthereumAddress {\n return new EthereumAddress(this.signerInfo.address);\n }\n\n /**\n * Returns all streams from the TN network.\n * @param input - The input parameters for listing streams.\n * @returns A promise that resolves to a list of stream locators.\n */\n async getListStreams(input: ListStreamsInput): Promise<TNStream[]> {\n return listStreams(this.getKwilClient() as WebKwil | NodeKwil,this.getKwilSigner(),input);\n }\n\n /**\n * Returns the last write activity across streams.\n * @param input - The input parameters for getting last transactions.\n * @returns A promise that resolves to a list of last transactions.\n */\n async getLastTransactions(input: GetLastTransactionsInput): Promise<any[]> {\n return getLastTransactions(this.getKwilClient() as WebKwil | NodeKwil,this.getKwilSigner(),input);\n }\n\n /**\n * Lists taxonomies by height range for incremental synchronization.\n * High-level wrapper for ComposedAction.listTaxonomiesByHeight()\n * \n * @param params Height range and pagination parameters \n * @returns Promise resolving to taxonomy query results\n * \n * @example\n * ```typescript\n * const taxonomies = await client.listTaxonomiesByHeight({\n * fromHeight: 1000,\n * toHeight: 2000,\n * limit: 100,\n * latestOnly: true\n * });\n * ```\n */\n async listTaxonomiesByHeight(params: ListTaxonomiesByHeightParams = {}): Promise<TaxonomyQueryResult[]> {\n const composedAction = this.loadComposedAction();\n return composedAction.listTaxonomiesByHeight(params);\n }\n\n async listMetadataByHeight(params: ListMetadataByHeightParams = {}): Promise<MetadataQueryResult[]> {\n const action = this.loadAction();\n return action.listMetadataByHeight(params);\n }\n\n async getWalletBalance(chain: string, walletAddress: string) {\n const action = this.loadAction();\n return action.getWalletBalance(chain, walletAddress);\n }\n\n /**\n * Performs a withdrawal operation by bridging tokens\n * @param chain The chain identifier (e.g., \"sepolia\", \"mainnet\", \"polygon\", etc.)\n * @param amount The amount to withdraw\n * @returns Promise that resolves to the transaction hash, or throws on error\n */\n async withdraw(chain: string, amount: string, recipient: string): Promise<string> {\n const action = this.loadAction();\n \n // Bridge tokens in a single operation\n const bridgeResult = await action.bridgeTokens(chain, amount, recipient);\n if (!bridgeResult.data?.tx_hash) {\n throw new Error(\"Bridge tokens operation failed: no transaction hash returned\");\n }\n \n // Wait for bridge transaction to be mined - let waitForTx errors bubble up\n try {\n await this.waitForTx(bridgeResult.data.tx_hash);\n } catch (error) {\n throw new Error(`Bridge tokens transaction failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n \n // Return the transaction hash\n return bridgeResult.data.tx_hash;\n }\n\n /**\n * Lists wallet rewards for a specific wallet address on a blockchain network\n * @param chain The chain identifier (e.g., \"sepolia\", \"mainnet\", \"polygon\", etc.)\n * @param wallet The wallet address to list rewards for\n * @param withPending Whether to include pending rewards\n * @returns Promise that resolves to an array of rewards data\n */\n async listWalletRewards(chain: string, wallet: string, withPending: boolean): Promise<any[]> {\n const action = this.loadAction();\n return action.listWalletRewards(chain, wallet, withPending);\n }\n\n /**\n * Gets taxonomies for specific streams in batch.\n * High-level wrapper for ComposedAction.getTaxonomiesForStreams()\n * \n * @param params Stream locators and options\n * @returns Promise resolving to taxonomy query results\n * \n * @example\n * ```typescript\n * const streams = [\n * { dataProvider: provider1, streamId: streamId1 },\n * { dataProvider: provider2, streamId: streamId2 }\n * ];\n * const taxonomies = await client.getTaxonomiesForStreams({\n * streams,\n * latestOnly: true\n * });\n * ```\n */\n async getTaxonomiesForStreams(params: GetTaxonomiesForStreamsParams): Promise<TaxonomyQueryResult[]> {\n const composedAction = this.loadComposedAction();\n return composedAction.getTaxonomiesForStreams(params);\n }\n\n /**\n * Get the default chain id for a provider. Use with caution, as this decreases the security of the TN.\n * @param provider - The provider URL.\n * @returns A promise that resolves to the chain ID.\n */\n public static async getDefaultChainId(provider: string) {\n const kwilClient = new Client({\n kwilProvider: provider,\n });\n const chainInfo = await kwilClient[\"chainInfoClient\"]();\n return chainInfo.data?.chain_id;\n }\n\n /*\n * High-level role-management helpers. These wrap the lower-level\n * RoleManagement contract calls and expose a simpler API on the\n * TN client.\n */\n\n /** Grants a role to one or more wallets. */\n async grantRole(input: {\n owner: OwnerIdentifier;\n roleName: string;\n wallets: EthereumAddress | EthereumAddress[];\n synchronous?: boolean;\n }): Promise<string> {\n const rm = this.loadRoleManagementAction();\n const walletsArr: EthereumAddress[] = Array.isArray(input.wallets)\n ? input.wallets\n : [input.wallets];\n const tx = await rm.grantRole(\n {\n owner: input.owner,\n roleName: input.roleName,\n wallets: walletsArr,\n },\n input.synchronous,\n );\n return tx.data?.tx_hash as unknown as string;\n }\n\n /** Revokes a role from one or more wallets. */\n async revokeRole(input: {\n owner: OwnerIdentifier;\n roleName: string;\n wallets: EthereumAddress | EthereumAddress[];\n synchronous?: boolean;\n }): Promise<string> {\n const rm = this.loadRoleManagementAction();\n const walletsArr: EthereumAddress[] = Array.isArray(input.wallets)\n ? input.wallets\n : [input.wallets];\n const tx = await rm.revokeRole(\n {\n owner: input.owner,\n roleName: input.roleName,\n wallets: walletsArr,\n },\n input.synchronous,\n );\n return tx.data?.tx_hash as unknown as string;\n }\n\n /**\n * Checks if a wallet is member of a role.\n * Returns true if the wallet is a member.\n */\n async isMemberOf(input: {\n owner: OwnerIdentifier;\n roleName: string;\n wallet: EthereumAddress;\n }): Promise<boolean> {\n const rm = this.loadRoleManagementAction();\n const res = await rm.areMembersOf({\n owner: input.owner,\n roleName: input.roleName,\n wallets: [input.wallet],\n });\n return res.length > 0 && res[0].isMember;\n }\n\n /**\n * Lists role members \u2013 currently unsupported in the\n * smart-contract layer.\n */\n async listRoleMembers(input: {\n owner: OwnerIdentifier;\n roleName: string;\n limit?: number;\n offset?: number;\n }): Promise<import(\"../types/role\").RoleMember[]> {\n const rm = this.loadRoleManagementAction();\n return rm.listRoleMembers({\n owner: input.owner,\n roleName: input.roleName,\n limit: input.limit,\n offset: input.offset,\n });\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAA8E;AAC9E,4BAAiH;AACjH,0BAA6B;AAC7B,0BAA6B;AAC7B,6BAAgC;AAChC,oBAAwE;AAGxE,6BAAgC;AAEhC,yBAA4B;AAC5B,iCAAoC;AACpC,4BAA+B;AA+BxB,IAAe,eAAf,MAAuD;AAAA,EAClD;AAAA,EACA;AAAA,EAEA,YAAY,SAA0B;AAC9C,SAAK,aAAa,QAAQ;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,UAAU,QAAgB,UAAU,MAAqC;AAC7E,WAAO,IAAI,QAA6B,OAAO,SAAS,WAAW;AACjE,YAAM,WAAW,YAAY,YAAY;AACvC,cAAM,UAAU,MAAM,KAAK,cAAc,EACtC,cAAc,EAAE,MAAM,EACtB,MAAM,OAAO,EAAE,MAAM,QAAW,QAAQ,OAAU,EAAE;AACvD,gBAAQ,QAAQ,QAAQ;AAAA,UACtB,KAAK;AACH,gBAAI,QAAQ,MAAM,WAAW,QAAQ,UAAa,QAAQ,MAAM,WAAW,IAAI,SAAS,OAAO,GAAG;AAChG;AAAA,gBACI,IAAI;AAAA,kBACA,8BAA8B,QAAQ,MAAM,kBAAkB,QAAQ,MAAM,UAAU,GAAG;AAAA,gBAC7F;AAAA,cAAC;AAAA,YACP,OAAO;AACL,sBAAQ,QAAQ,IAAK;AAAA,YACvB;AACA;AAAA,UACF,KAAK;AACH;AAAA,UACF;AACE;AAAA,cACE,IAAI;AAAA,gBACF,8BAA8B,QAAQ,MAAM,kBAAkB,QAAQ,MAAM,UAAU,GAAG;AAAA,cAC3F;AAAA,YACF;AAAA,QACJ;AAAA,MACF,GAAG,GAAI;AACP,iBAAW,MAAM;AACf,sBAAc,QAAQ;AACtB,eAAO,IAAI,MAAM,6BAA6B,CAAC;AAAA,MACjD,GAAG,OAAO;AAAA,IACZ,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAA4B;AAC1B,WAAO,IAAI;AAAA,MACT,KAAK,WAAW;AAAA,MAChB,KAAK,QAAQ,EAAE,WAAW;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAA6C;AAC3C,QAAI,CAAC,KAAK,YAAY;AACpB,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aACJ,UACA,YACA,aACiD;AACjD,WAAO,UAAM,kCAAa;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,KAAK,cAAc;AAAA,MAC/B,YAAY,KAAK,cAAc;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cACJ,QACA,aACiD;AACjD,WAAO,UAAM,kCAAa;AAAA,MACxB;AAAA,MACA;AAAA,MACA,YAAY,KAAK,cAAc;AAAA,MAC/B,YAAY,KAAK,cAAc;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAqB;AACnB,WAAO,IAAI;AAAA,MACT,KAAK,cAAc;AAAA,MACnB,KAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,sBAAuC;AACrC,WAAO,uCAAgB,WAAW,KAAK,WAAW,CAAC;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,qBAAqC;AACnC,WAAO,qCAAe,WAAW,KAAK,WAAW,CAAC;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,2BAA2C;AACzC,WAAO,qCAAe;AAAA,MAClB,KAAK,cAAc;AAAA,MACnB,KAAK,cAAc;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAiB,UAAmC;AAClD,WAAO;AAAA,MACL;AAAA,MACA,cAAc,KAAK,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAA2B;AACzB,WAAO,IAAI,uCAAgB,KAAK,WAAW,OAAO;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eAAe,OAA8C;AACjE,eAAO,gCAAY,KAAK,cAAc,GAAwB,KAAK,cAAc,GAAE,KAAK;AAAA,EAC1F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOE,MAAM,oBAAoB,OAAiD;AACvE,eAAO,gDAAoB,KAAK,cAAc,GAAwB,KAAK,cAAc,GAAE,KAAK;AAAA,EACpG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBF,MAAM,uBAAuB,SAAuC,CAAC,GAAmC;AACtG,UAAM,iBAAiB,KAAK,mBAAmB;AAC/C,WAAO,eAAe,uBAAuB,MAAM;AAAA,EACrD;AAAA,EAEA,MAAM,qBAAqB,SAAqC,CAAC,GAAmC;AAClG,UAAM,SAAS,KAAK,WAAW;AAC/B,WAAO,OAAO,qBAAqB,MAAM;AAAA,EAC3C;AAAA,EAEA,MAAM,iBAAiB,OAAe,eAAuB;AAC3D,UAAM,SAAS,KAAK,WAAW;AAC/B,WAAO,OAAO,iBAAiB,OAAO,aAAa;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAS,OAAe,QAAgB,WAAoC;AAChF,UAAM,SAAS,KAAK,WAAW;AAG/B,UAAM,eAAe,MAAM,OAAO,aAAa,OAAO,QAAQ,SAAS;AACvE,QAAI,CAAC,aAAa,MAAM,SAAS;AAC/B,YAAM,IAAI,MAAM,8DAA8D;AAAA,IAChF;AAGA,QAAI;AACF,YAAM,KAAK,UAAU,aAAa,KAAK,OAAO;AAAA,IAChD,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,qCAAqC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,IAC/G;AAGA,WAAO,aAAa,KAAK;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,kBAAkB,OAAe,QAAgB,aAAsC;AAC3F,UAAM,SAAS,KAAK,WAAW;AAC/B,WAAO,OAAO,kBAAkB,OAAO,QAAQ,WAAW;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,wBAAwB,QAAuE;AACnG,UAAM,iBAAiB,KAAK,mBAAmB;AAC/C,WAAO,eAAe,wBAAwB,MAAM;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAoB,kBAAkB,UAAkB;AACtD,UAAM,aAAa,IAAI,sBAAO;AAAA,MAC5B,cAAc;AAAA,IAChB,CAAC;AACD,UAAM,YAAY,MAAM,WAAW,iBAAiB,EAAE;AACtD,WAAO,UAAU,MAAM;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAAU,OAKI;AAClB,UAAM,KAAK,KAAK,yBAAyB;AACzC,UAAM,aAAgC,MAAM,QAAQ,MAAM,OAAO,IAC7D,MAAM,UACN,CAAC,MAAM,OAAO;AAClB,UAAM,KAAK,MAAM,GAAG;AAAA,MAClB;AAAA,QACE,OAAO,MAAM;AAAA,QACb,UAAU,MAAM;AAAA,QAChB,SAAS;AAAA,MACX;AAAA,MACA,MAAM;AAAA,IACR;AACA,WAAO,GAAG,MAAM;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM,WAAW,OAKG;AAClB,UAAM,KAAK,KAAK,yBAAyB;AACzC,UAAM,aAAgC,MAAM,QAAQ,MAAM,OAAO,IAC7D,MAAM,UACN,CAAC,MAAM,OAAO;AAClB,UAAM,KAAK,MAAM,GAAG;AAAA,MAClB;AAAA,QACE,OAAO,MAAM;AAAA,QACb,UAAU,MAAM;AAAA,QAChB,SAAS;AAAA,MACX;AAAA,MACA,MAAM;AAAA,IACR;AACA,WAAO,GAAG,MAAM;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,OAII;AACnB,UAAM,KAAK,KAAK,yBAAyB;AACzC,UAAM,MAAM,MAAM,GAAG,aAAa;AAAA,MAChC,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,SAAS,CAAC,MAAM,MAAM;AAAA,IACxB,CAAC;AACD,WAAO,IAAI,SAAS,KAAK,IAAI,CAAC,EAAE;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBAAgB,OAK4B;AAChD,UAAM,KAAK,KAAK,yBAAyB;AACzC,WAAO,GAAG,gBAAgB;AAAA,MACxB,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,EACH;AACF;",
4
+ "sourcesContent": ["import { Client, KwilSigner, NodeKwil, WebKwil, Types, EnvironmentType } from \"@trufnetwork/kwil-js\";\nimport { ComposedAction, ListTaxonomiesByHeightParams, GetTaxonomiesForStreamsParams, TaxonomyQueryResult } from \"../contracts-api/composedAction\";\nimport { deployStream } from \"../contracts-api/deployStream\";\nimport { deleteStream } from \"../contracts-api/deleteStream\";\nimport { PrimitiveAction } from \"../contracts-api/primitiveAction\";\nimport { Action, ListMetadataByHeightParams, MetadataQueryResult } from \"../contracts-api/action\";\nimport { StreamType } from \"../contracts-api/contractValues\";\nimport { StreamLocator, TNStream } from \"../types/stream\";\nimport { EthereumAddress } from \"../util/EthereumAddress\";\nimport { StreamId } from \"../util/StreamId\";\nimport { listStreams } from \"./listStreams\";\nimport { getLastTransactions } from \"./getLastTransactions\";\nimport { RoleManagement } from \"../contracts-api/roleManagement\";\nimport { AttestationAction } from \"../contracts-api/attestationAction\";\nimport { OwnerIdentifier } from \"../types/role\";\n\nexport interface SignerInfo {\n // we need to have the address upfront to create the KwilSigner, instead of relying on the signer to return it asynchronously\n address: string;\n signer: Types.EthSigner;\n}\n\nexport type TNClientOptions = {\n endpoint: string;\n signerInfo: SignerInfo;\n} & Omit<Types.KwilConfig, \"kwilProvider\">;\n\nexport interface ListStreamsInput {\n dataProvider?: string;\n limit?: number;\n offset?: number;\n orderBy?: string;\n blockHeight?: number;\n}\n\n/**\n * @param dataProvider optional address; when omitted or null, returns for all providers\n * @param limitSize max rows to return (default 6, max 100)\n */\nexport interface GetLastTransactionsInput {\n dataProvider?: string;\n limitSize?: number;\n}\n\nexport abstract class BaseTNClient<T extends EnvironmentType> {\n protected kwilClient: Types.Kwil<T> | undefined;\n protected signerInfo: SignerInfo;\n\n protected constructor(options: TNClientOptions) {\n this.signerInfo = options.signerInfo;\n }\n\n /**\n * Waits for a transaction to be mined by TN.\n * @param txHash - The transaction hash to wait for.\n * @param timeout - The timeout in milliseconds.\n * @returns A promise that resolves to the transaction info receipt.\n */\n async waitForTx(txHash: string, timeout = 12000): Promise<Types.TxInfoReceipt> {\n return new Promise<Types.TxInfoReceipt>(async (resolve, reject) => {\n const interval = setInterval(async () => {\n const receipt = await this.getKwilClient()\n [\"txInfoClient\"](txHash)\n .catch(() => ({ data: undefined, status: undefined }));\n switch (receipt.status) {\n case 200:\n if (receipt.data?.tx_result?.log !== undefined && receipt.data?.tx_result?.log.includes(\"ERROR\")) {\n reject(\n new Error(\n `Transaction failed: status ${receipt.status} : log message ${receipt.data?.tx_result.log}`,\n ))\n } else {\n resolve(receipt.data!);\n }\n break;\n case undefined:\n break;\n default:\n reject(\n new Error(\n `Transaction failed: status ${receipt.status} : log message ${receipt.data?.tx_result.log}`,\n ),\n );\n }\n }, 1000);\n setTimeout(() => {\n clearInterval(interval);\n reject(new Error(\"Transaction failed: Timeout\"));\n }, timeout);\n });\n }\n\n /**\n * Returns the Kwil signer used by the client.\n * @returns An instance of KwilSigner.\n */\n getKwilSigner(): KwilSigner {\n return new KwilSigner(\n this.signerInfo.signer,\n this.address().getAddress(),\n );\n }\n\n /**\n * Returns the Kwil client used by the client.\n * @returns An instance of Kwil.\n * @throws If the Kwil client is not initialized.\n */\n getKwilClient(): Types.Kwil<EnvironmentType> {\n if (!this.kwilClient) {\n throw new Error(\"Kwil client not initialized\");\n }\n return this.kwilClient;\n }\n\n /**\n * Deploys a new stream.\n * @param streamId - The ID of the stream to deploy.\n * @param streamType - The type of the stream.\n * @param synchronous - Whether the deployment should be synchronous.\n * @param contractVersion\n * @returns A promise that resolves to a generic response containing the transaction receipt.\n */\n async deployStream(\n streamId: StreamId,\n streamType: StreamType,\n synchronous?: boolean,\n ): Promise<Types.GenericResponse<Types.TxReceipt>> {\n return await deployStream({\n streamId,\n streamType,\n synchronous,\n kwilClient: this.getKwilClient(),\n kwilSigner: this.getKwilSigner(),\n });\n }\n\n /**\n * Destroys a stream.\n * @param stream - The StreamLocator of the stream to destroy.\n * @param synchronous - Whether the destruction should be synchronous.\n * @returns A promise that resolves to a generic response containing the transaction receipt.\n */\n async destroyStream(\n stream: StreamLocator,\n synchronous?: boolean,\n ): Promise<Types.GenericResponse<Types.TxReceipt>> {\n return await deleteStream({\n stream,\n synchronous,\n kwilClient: this.getKwilClient(),\n kwilSigner: this.getKwilSigner(),\n });\n }\n\n /**\n * Loads an already deployed stream, permitting its API usage.\n * @returns An instance of IStream.\n */\n loadAction(): Action {\n return new Action(\n this.getKwilClient() as WebKwil | NodeKwil,\n this.getKwilSigner(),\n );\n }\n\n /**\n * Loads a primitive stream.\n * @returns An instance of IPrimitiveStream.\n */\n loadPrimitiveAction(): PrimitiveAction {\n return PrimitiveAction.fromStream(this.loadAction());\n }\n\n /**\n * Loads a composed stream.\n * @returns An instance of IComposedStream.\n */\n loadComposedAction(): ComposedAction {\n return ComposedAction.fromStream(this.loadAction());\n }\n\n /**\n * Loads the role management contract API, permitting its RBAC usage.\n */\n loadRoleManagementAction(): RoleManagement {\n return RoleManagement.fromClient(\n this.getKwilClient() as WebKwil | NodeKwil,\n this.getKwilSigner(),\n );\n }\n\n /**\n * Loads the attestation action API, permitting attestation operations.\n * @returns An instance of AttestationAction.\n */\n loadAttestationAction(): AttestationAction {\n return new AttestationAction(\n this.getKwilClient() as WebKwil | NodeKwil,\n this.getKwilSigner(),\n );\n }\n\n /**\n * Creates a new stream locator.\n * @param streamId - The ID of the stream.\n * @returns A StreamLocator object.\n */\n ownStreamLocator(streamId: StreamId): StreamLocator {\n return {\n streamId,\n dataProvider: this.address(),\n };\n }\n\n /**\n * Returns the address of the signer used by the client.\n * @returns An instance of EthereumAddress.\n */\n address(): EthereumAddress {\n return new EthereumAddress(this.signerInfo.address);\n }\n\n /**\n * Returns all streams from the TN network.\n * @param input - The input parameters for listing streams.\n * @returns A promise that resolves to a list of stream locators.\n */\n async getListStreams(input: ListStreamsInput): Promise<TNStream[]> {\n return listStreams(this.getKwilClient() as WebKwil | NodeKwil,this.getKwilSigner(),input);\n }\n\n /**\n * Returns the last write activity across streams.\n * @param input - The input parameters for getting last transactions.\n * @returns A promise that resolves to a list of last transactions.\n */\n async getLastTransactions(input: GetLastTransactionsInput): Promise<any[]> {\n return getLastTransactions(this.getKwilClient() as WebKwil | NodeKwil,this.getKwilSigner(),input);\n }\n\n /**\n * Lists taxonomies by height range for incremental synchronization.\n * High-level wrapper for ComposedAction.listTaxonomiesByHeight()\n * \n * @param params Height range and pagination parameters \n * @returns Promise resolving to taxonomy query results\n * \n * @example\n * ```typescript\n * const taxonomies = await client.listTaxonomiesByHeight({\n * fromHeight: 1000,\n * toHeight: 2000,\n * limit: 100,\n * latestOnly: true\n * });\n * ```\n */\n async listTaxonomiesByHeight(params: ListTaxonomiesByHeightParams = {}): Promise<TaxonomyQueryResult[]> {\n const composedAction = this.loadComposedAction();\n return composedAction.listTaxonomiesByHeight(params);\n }\n\n async listMetadataByHeight(params: ListMetadataByHeightParams = {}): Promise<MetadataQueryResult[]> {\n const action = this.loadAction();\n return action.listMetadataByHeight(params);\n }\n\n async getWalletBalance(chain: string, walletAddress: string) {\n const action = this.loadAction();\n return action.getWalletBalance(chain, walletAddress);\n }\n\n /**\n * Performs a withdrawal operation by bridging tokens\n * @param chain The chain identifier (e.g., \"sepolia\", \"mainnet\", \"polygon\", etc.)\n * @param amount The amount to withdraw\n * @returns Promise that resolves to the transaction hash, or throws on error\n */\n async withdraw(chain: string, amount: string, recipient: string): Promise<string> {\n const action = this.loadAction();\n \n // Bridge tokens in a single operation\n const bridgeResult = await action.bridgeTokens(chain, amount, recipient);\n if (!bridgeResult.data?.tx_hash) {\n throw new Error(\"Bridge tokens operation failed: no transaction hash returned\");\n }\n \n // Wait for bridge transaction to be mined - let waitForTx errors bubble up\n try {\n await this.waitForTx(bridgeResult.data.tx_hash);\n } catch (error) {\n throw new Error(`Bridge tokens transaction failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n \n // Return the transaction hash\n return bridgeResult.data.tx_hash;\n }\n\n /**\n * Lists wallet rewards for a specific wallet address on a blockchain network\n * @param chain The chain identifier (e.g., \"sepolia\", \"mainnet\", \"polygon\", etc.)\n * @param wallet The wallet address to list rewards for\n * @param withPending Whether to include pending rewards\n * @returns Promise that resolves to an array of rewards data\n */\n async listWalletRewards(chain: string, wallet: string, withPending: boolean): Promise<any[]> {\n const action = this.loadAction();\n return action.listWalletRewards(chain, wallet, withPending);\n }\n\n /**\n * Gets taxonomies for specific streams in batch.\n * High-level wrapper for ComposedAction.getTaxonomiesForStreams()\n * \n * @param params Stream locators and options\n * @returns Promise resolving to taxonomy query results\n * \n * @example\n * ```typescript\n * const streams = [\n * { dataProvider: provider1, streamId: streamId1 },\n * { dataProvider: provider2, streamId: streamId2 }\n * ];\n * const taxonomies = await client.getTaxonomiesForStreams({\n * streams,\n * latestOnly: true\n * });\n * ```\n */\n async getTaxonomiesForStreams(params: GetTaxonomiesForStreamsParams): Promise<TaxonomyQueryResult[]> {\n const composedAction = this.loadComposedAction();\n return composedAction.getTaxonomiesForStreams(params);\n }\n\n /**\n * Get the default chain id for a provider. Use with caution, as this decreases the security of the TN.\n * @param provider - The provider URL.\n * @returns A promise that resolves to the chain ID.\n */\n public static async getDefaultChainId(provider: string) {\n const kwilClient = new Client({\n kwilProvider: provider,\n });\n const chainInfo = await kwilClient[\"chainInfoClient\"]();\n return chainInfo.data?.chain_id;\n }\n\n /*\n * High-level role-management helpers. These wrap the lower-level\n * RoleManagement contract calls and expose a simpler API on the\n * TN client.\n */\n\n /** Grants a role to one or more wallets. */\n async grantRole(input: {\n owner: OwnerIdentifier;\n roleName: string;\n wallets: EthereumAddress | EthereumAddress[];\n synchronous?: boolean;\n }): Promise<string> {\n const rm = this.loadRoleManagementAction();\n const walletsArr: EthereumAddress[] = Array.isArray(input.wallets)\n ? input.wallets\n : [input.wallets];\n const tx = await rm.grantRole(\n {\n owner: input.owner,\n roleName: input.roleName,\n wallets: walletsArr,\n },\n input.synchronous,\n );\n return tx.data?.tx_hash as unknown as string;\n }\n\n /** Revokes a role from one or more wallets. */\n async revokeRole(input: {\n owner: OwnerIdentifier;\n roleName: string;\n wallets: EthereumAddress | EthereumAddress[];\n synchronous?: boolean;\n }): Promise<string> {\n const rm = this.loadRoleManagementAction();\n const walletsArr: EthereumAddress[] = Array.isArray(input.wallets)\n ? input.wallets\n : [input.wallets];\n const tx = await rm.revokeRole(\n {\n owner: input.owner,\n roleName: input.roleName,\n wallets: walletsArr,\n },\n input.synchronous,\n );\n return tx.data?.tx_hash as unknown as string;\n }\n\n /**\n * Checks if a wallet is member of a role.\n * Returns true if the wallet is a member.\n */\n async isMemberOf(input: {\n owner: OwnerIdentifier;\n roleName: string;\n wallet: EthereumAddress;\n }): Promise<boolean> {\n const rm = this.loadRoleManagementAction();\n const res = await rm.areMembersOf({\n owner: input.owner,\n roleName: input.roleName,\n wallets: [input.wallet],\n });\n return res.length > 0 && res[0].isMember;\n }\n\n /**\n * Lists role members \u2013 currently unsupported in the\n * smart-contract layer.\n */\n async listRoleMembers(input: {\n owner: OwnerIdentifier;\n roleName: string;\n limit?: number;\n offset?: number;\n }): Promise<import(\"../types/role\").RoleMember[]> {\n const rm = this.loadRoleManagementAction();\n return rm.listRoleMembers({\n owner: input.owner,\n roleName: input.roleName,\n limit: input.limit,\n offset: input.offset,\n });\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -24,7 +24,6 @@ __export(getLastTransactions_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(getLastTransactions_exports);
26
26
  var INDEXER_BASE = "https://indexer.infra.truf.network";
27
- var RPC_URL = "https://gateway.mainnet.truf.network/rpc/v1";
28
27
  async function getLastTransactions(kwilClient, kwilSigner, input) {
29
28
  const res = await kwilClient.call(
30
29
  {
@@ -38,48 +37,56 @@ async function getLastTransactions(kwilClient, kwilSigner, input) {
38
37
  kwilSigner
39
38
  );
40
39
  const rows = res.data?.result || [];
41
- const tasks = rows.map(({ created_at, method }) => {
40
+ if (rows.length === 0) {
41
+ return [];
42
+ }
43
+ const blockHeights = rows.map(({ created_at }) => {
42
44
  const blockHeight = Number(created_at);
43
45
  if (Number.isNaN(blockHeight)) {
44
- return Promise.reject(new Error(`Invalid block height returned: ${created_at}`));
46
+ throw new Error(`Invalid block height returned: ${created_at}`);
45
47
  }
46
- const txUrl = `${INDEXER_BASE}/v0/chain/transactions?from-block=${blockHeight}&to-block=${blockHeight}&order=asc&limit=1`;
47
- const txPromise = fetch(txUrl).then(async (resp) => {
48
- if (!resp.ok) throw new Error(`Indexer fetch failed: ${resp.status}`);
49
- const json = await resp.json();
50
- if (!json.ok || json.data.length === 0) {
51
- return { sender: "(unknown)", hash: "(unknown)" };
52
- }
53
- const { hash, sender } = json.data[0];
54
- return { sender, hash };
55
- });
56
- const rpcPromise = fetch(RPC_URL, {
57
- method: "POST",
58
- headers: { "Content-Type": "application/json" },
59
- body: JSON.stringify({
60
- jsonrpc: "2.0",
61
- method: "chain.block",
62
- params: { height: blockHeight },
63
- id: 1
64
- })
65
- }).then(async (resp) => {
66
- if (!resp.ok) {
67
- const txt = await resp.text();
68
- throw new Error(`RPC fetch failed: ${resp.status} \u2013 ${txt}`);
69
- }
70
- const rpc = await resp.json();
71
- return rpc.result.block.header.stamp_ms;
72
- });
73
- return Promise.all([txPromise, rpcPromise]).then(
74
- ([{ sender, hash }, stampMs]) => ({
48
+ return blockHeight;
49
+ });
50
+ const minBlock = Math.min(...blockHeights);
51
+ const maxBlock = Math.max(...blockHeights);
52
+ const txUrl = `${INDEXER_BASE}/v0/chain/transactions?from-block=${minBlock}&to-block=${maxBlock}&order=asc`;
53
+ const resp = await fetch(txUrl);
54
+ if (!resp.ok) {
55
+ throw new Error(`Indexer fetch failed: ${resp.status}`);
56
+ }
57
+ const json = await resp.json();
58
+ if (!json.ok) {
59
+ throw new Error("Indexer returned ok: false");
60
+ }
61
+ const blockToTx = /* @__PURE__ */ new Map();
62
+ for (const tx of json.data) {
63
+ if (!blockToTx.has(tx.block_height)) {
64
+ blockToTx.set(tx.block_height, {
65
+ hash: tx.hash,
66
+ sender: tx.sender,
67
+ stamp_ms: tx.stamp_ms
68
+ });
69
+ }
70
+ }
71
+ return rows.map(({ created_at, method }) => {
72
+ const blockHeight = Number(created_at);
73
+ const tx = blockToTx.get(blockHeight);
74
+ if (!tx) {
75
+ return {
75
76
  blockHeight,
76
77
  method,
77
- sender,
78
- transactionHash: hash,
79
- stampMs
80
- })
81
- );
78
+ sender: "(unknown)",
79
+ transactionHash: "(unknown)",
80
+ stampMs: 0
81
+ };
82
+ }
83
+ return {
84
+ blockHeight,
85
+ method,
86
+ sender: tx.sender,
87
+ transactionHash: tx.hash,
88
+ stampMs: tx.stamp_ms ?? 0
89
+ };
82
90
  });
83
- return Promise.all(tasks);
84
91
  }
85
92
  //# sourceMappingURL=getLastTransactions.cjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/client/getLastTransactions.ts"],
4
- "sourcesContent": ["import { WebKwil, NodeKwil, KwilSigner } from \"@trufnetwork/kwil-js\";\r\nimport { GetLastTransactionsInput } from \"../internal\";\r\nimport { LastTransaction } from \"../types/transaction\";\r\n\r\nconst INDEXER_BASE = \"https://indexer.infra.truf.network\";\r\nconst RPC_URL = \"https://gateway.mainnet.truf.network/rpc/v1\";\r\n\r\nexport async function getLastTransactions(\r\n kwilClient: WebKwil | NodeKwil,\r\n kwilSigner: KwilSigner,\r\n input: GetLastTransactionsInput\r\n): Promise<LastTransaction[]> {\r\n // 1) call your SQL action\r\n const res = await kwilClient.call(\r\n {\r\n name: \"get_last_transactions\",\r\n namespace: \"main\",\r\n inputs: {\r\n $data_provider: input.dataProvider ?? null,\r\n $limit_size: input.limitSize ?? 6,\r\n },\r\n },\r\n kwilSigner\r\n );\r\n const rows = (res.data?.result as { created_at: number; method: string }[]) || [];\r\n\r\n // 2) build per-block Promises\r\n const tasks = rows.map(({ created_at, method }) => {\r\n const blockHeight = Number(created_at);\r\n if (Number.isNaN(blockHeight)) {\r\n return Promise.reject(new Error(`Invalid block height returned: ${created_at}`));\r\n }\r\n\r\n const txUrl = `${INDEXER_BASE}/v0/chain/transactions`\r\n + `?from-block=${blockHeight}&to-block=${blockHeight}`\r\n + `&order=asc&limit=1`;\r\n\r\n // INDEXER: always return a { sender, hash } object\r\n const txPromise = fetch(txUrl).then(async (resp) => {\r\n if (!resp.ok) throw new Error(`Indexer fetch failed: ${resp.status}`);\r\n const json = (await resp.json()) as {\r\n ok: boolean;\r\n data: Array<{ hash: string; sender: string }>;\r\n };\r\n if (!json.ok || json.data.length === 0) {\r\n return { sender: \"(unknown)\", hash: \"(unknown)\" };\r\n }\r\n const { hash, sender } = json.data[0];\r\n return { sender, hash };\r\n });\r\n\r\n // RPC: get stamp_ms\r\n const rpcPromise = fetch(RPC_URL, {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({\r\n jsonrpc: \"2.0\",\r\n method: \"chain.block\",\r\n params: { height: blockHeight },\r\n id: 1,\r\n }),\r\n }).then(async (resp) => {\r\n if (!resp.ok) {\r\n const txt = await resp.text();\r\n throw new Error(`RPC fetch failed: ${resp.status} \u2013 ${txt}`);\r\n }\r\n const rpc = (await resp.json()) as {\r\n result: { block: { header: { stamp_ms: number } } };\r\n };\r\n return rpc.result.block.header.stamp_ms;\r\n });\r\n\r\n // wait for both\r\n return Promise.all([txPromise, rpcPromise]).then(\r\n ([{ sender, hash }, stampMs]) => ({\r\n blockHeight,\r\n method,\r\n sender,\r\n transactionHash: hash,\r\n stampMs,\r\n })\r\n );\r\n });\r\n\r\n // 3) await all in parallel\r\n return Promise.all(tasks);\r\n}\r\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,IAAM,eAAe;AACrB,IAAM,UAAe;AAErB,eAAsB,oBAClB,YACA,YACA,OAC0B;AAE1B,QAAM,MAAM,MAAM,WAAW;AAAA,IACzB;AAAA,MACI,MAAM;AAAA,MACN,WAAW;AAAA,MACX,QAAQ;AAAA,QACJ,gBAAgB,MAAM,gBAAgB;AAAA,QACtC,aAAa,MAAM,aAAa;AAAA,MACpC;AAAA,IACJ;AAAA,IACA;AAAA,EACJ;AACA,QAAM,OAAQ,IAAI,MAAM,UAAuD,CAAC;AAGhF,QAAM,QAAQ,KAAK,IAAI,CAAC,EAAE,YAAY,OAAO,MAAM;AAC/C,UAAM,cAAc,OAAO,UAAU;AACrC,QAAI,OAAO,MAAM,WAAW,GAAG;AAC3B,aAAO,QAAQ,OAAO,IAAI,MAAM,kCAAkC,UAAU,EAAE,CAAC;AAAA,IACnF;AAEA,UAAM,QAAQ,GAAG,YAAY,qCACR,WAAW,aAAa,WAAW;AAIxD,UAAM,YAAY,MAAM,KAAK,EAAE,KAAK,OAAO,SAAS;AAChD,UAAI,CAAC,KAAK,GAAI,OAAM,IAAI,MAAM,yBAAyB,KAAK,MAAM,EAAE;AACpE,YAAM,OAAQ,MAAM,KAAK,KAAK;AAI9B,UAAI,CAAC,KAAK,MAAM,KAAK,KAAK,WAAW,GAAG;AACpC,eAAO,EAAE,QAAQ,aAAa,MAAM,YAAY;AAAA,MACpD;AACA,YAAM,EAAE,MAAM,OAAO,IAAI,KAAK,KAAK,CAAC;AACpC,aAAO,EAAE,QAAQ,KAAK;AAAA,IAC1B,CAAC;AAGD,UAAM,aAAa,MAAM,SAAS;AAAA,MAC9B,QAAS;AAAA,MACT,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAS,KAAK,UAAU;AAAA,QACpB,SAAS;AAAA,QACT,QAAS;AAAA,QACT,QAAS,EAAE,QAAQ,YAAY;AAAA,QAC/B,IAAS;AAAA,MACb,CAAC;AAAA,IACL,CAAC,EAAE,KAAK,OAAO,SAAS;AACpB,UAAI,CAAC,KAAK,IAAI;AACV,cAAM,MAAM,MAAM,KAAK,KAAK;AAC5B,cAAM,IAAI,MAAM,qBAAqB,KAAK,MAAM,WAAM,GAAG,EAAE;AAAA,MAC/D;AACA,YAAM,MAAO,MAAM,KAAK,KAAK;AAG7B,aAAO,IAAI,OAAO,MAAM,OAAO;AAAA,IACnC,CAAC;AAGD,WAAO,QAAQ,IAAI,CAAC,WAAW,UAAU,CAAC,EAAE;AAAA,MACxC,CAAC,CAAC,EAAE,QAAQ,KAAK,GAAG,OAAO,OAAO;AAAA,QAC9B;AAAA,QACA;AAAA,QACA;AAAA,QACA,iBAAiB;AAAA,QACjB;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ,CAAC;AAGD,SAAO,QAAQ,IAAI,KAAK;AAC5B;",
4
+ "sourcesContent": ["import { WebKwil, NodeKwil, KwilSigner } from \"@trufnetwork/kwil-js\";\r\nimport { GetLastTransactionsInput } from \"../internal\";\r\nimport { LastTransaction } from \"../types/transaction\";\r\n\r\nconst INDEXER_BASE = \"https://indexer.infra.truf.network\";\r\n\r\nexport async function getLastTransactions(\r\n kwilClient: WebKwil | NodeKwil,\r\n kwilSigner: KwilSigner,\r\n input: GetLastTransactionsInput\r\n): Promise<LastTransaction[]> {\r\n // 1) call your SQL action\r\n const res = await kwilClient.call(\r\n {\r\n name: \"get_last_transactions\",\r\n namespace: \"main\",\r\n inputs: {\r\n $data_provider: input.dataProvider ?? null,\r\n $limit_size: input.limitSize ?? 6,\r\n },\r\n },\r\n kwilSigner\r\n );\r\n const rows = (res.data?.result as { created_at: number; method: string }[]) || [];\r\n\r\n if (rows.length === 0) {\r\n return [];\r\n }\r\n\r\n // 2) Parse block heights and validate\r\n const blockHeights = rows.map(({ created_at }) => {\r\n const blockHeight = Number(created_at);\r\n if (Number.isNaN(blockHeight)) {\r\n throw new Error(`Invalid block height returned: ${created_at}`);\r\n }\r\n return blockHeight;\r\n });\r\n\r\n // 3) Make a single range query to indexer for all blocks\r\n const minBlock = Math.min(...blockHeights);\r\n const maxBlock = Math.max(...blockHeights);\r\n\r\n const txUrl = `${INDEXER_BASE}/v0/chain/transactions`\r\n + `?from-block=${minBlock}&to-block=${maxBlock}`\r\n + `&order=asc`;\r\n\r\n const resp = await fetch(txUrl);\r\n if (!resp.ok) {\r\n throw new Error(`Indexer fetch failed: ${resp.status}`);\r\n }\r\n\r\n const json = (await resp.json()) as {\r\n ok: boolean;\r\n data: Array<{\r\n block_height: number;\r\n hash: string;\r\n sender: string;\r\n stamp_ms: number | null;\r\n }>;\r\n };\r\n\r\n if (!json.ok) {\r\n throw new Error(\"Indexer returned ok: false\");\r\n }\r\n\r\n // 4) Build a map of blockHeight -> first transaction\r\n const blockToTx = new Map<number, {\r\n hash: string;\r\n sender: string;\r\n stamp_ms: number | null;\r\n }>();\r\n\r\n for (const tx of json.data) {\r\n // Only keep the first transaction per block\r\n if (!blockToTx.has(tx.block_height)) {\r\n blockToTx.set(tx.block_height, {\r\n hash: tx.hash,\r\n sender: tx.sender,\r\n stamp_ms: tx.stamp_ms,\r\n });\r\n }\r\n }\r\n\r\n // 5) Map back to original order with methods from SQL query\r\n return rows.map(({ created_at, method }) => {\r\n const blockHeight = Number(created_at);\r\n const tx = blockToTx.get(blockHeight);\r\n\r\n if (!tx) {\r\n return {\r\n blockHeight,\r\n method,\r\n sender: \"(unknown)\",\r\n transactionHash: \"(unknown)\",\r\n stampMs: 0,\r\n };\r\n }\r\n\r\n return {\r\n blockHeight,\r\n method,\r\n sender: tx.sender,\r\n transactionHash: tx.hash,\r\n stampMs: tx.stamp_ms ?? 0,\r\n };\r\n });\r\n}\r\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,IAAM,eAAe;AAErB,eAAsB,oBAClB,YACA,YACA,OAC0B;AAE1B,QAAM,MAAM,MAAM,WAAW;AAAA,IACzB;AAAA,MACI,MAAM;AAAA,MACN,WAAW;AAAA,MACX,QAAQ;AAAA,QACJ,gBAAgB,MAAM,gBAAgB;AAAA,QACtC,aAAa,MAAM,aAAa;AAAA,MACpC;AAAA,IACJ;AAAA,IACA;AAAA,EACJ;AACA,QAAM,OAAQ,IAAI,MAAM,UAAuD,CAAC;AAEhF,MAAI,KAAK,WAAW,GAAG;AACnB,WAAO,CAAC;AAAA,EACZ;AAGA,QAAM,eAAe,KAAK,IAAI,CAAC,EAAE,WAAW,MAAM;AAC9C,UAAM,cAAc,OAAO,UAAU;AACrC,QAAI,OAAO,MAAM,WAAW,GAAG;AAC3B,YAAM,IAAI,MAAM,kCAAkC,UAAU,EAAE;AAAA,IAClE;AACA,WAAO;AAAA,EACX,CAAC;AAGD,QAAM,WAAW,KAAK,IAAI,GAAG,YAAY;AACzC,QAAM,WAAW,KAAK,IAAI,GAAG,YAAY;AAEzC,QAAM,QAAQ,GAAG,YAAY,qCACR,QAAQ,aAAa,QAAQ;AAGlD,QAAM,OAAO,MAAM,MAAM,KAAK;AAC9B,MAAI,CAAC,KAAK,IAAI;AACV,UAAM,IAAI,MAAM,yBAAyB,KAAK,MAAM,EAAE;AAAA,EAC1D;AAEA,QAAM,OAAQ,MAAM,KAAK,KAAK;AAU9B,MAAI,CAAC,KAAK,IAAI;AACV,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAChD;AAGA,QAAM,YAAY,oBAAI,IAInB;AAEH,aAAW,MAAM,KAAK,MAAM;AAExB,QAAI,CAAC,UAAU,IAAI,GAAG,YAAY,GAAG;AACjC,gBAAU,IAAI,GAAG,cAAc;AAAA,QAC3B,MAAM,GAAG;AAAA,QACT,QAAQ,GAAG;AAAA,QACX,UAAU,GAAG;AAAA,MACjB,CAAC;AAAA,IACL;AAAA,EACJ;AAGA,SAAO,KAAK,IAAI,CAAC,EAAE,YAAY,OAAO,MAAM;AACxC,UAAM,cAAc,OAAO,UAAU;AACrC,UAAM,KAAK,UAAU,IAAI,WAAW;AAEpC,QAAI,CAAC,IAAI;AACL,aAAO;AAAA,QACH;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,iBAAiB;AAAA,QACjB,SAAS;AAAA,MACb;AAAA,IACJ;AAEA,WAAO;AAAA,MACH;AAAA,MACA;AAAA,MACA,QAAQ,GAAG;AAAA,MACX,iBAAiB,GAAG;AAAA,MACpB,SAAS,GAAG,YAAY;AAAA,IAC5B;AAAA,EACJ,CAAC;AACL;",
6
6
  "names": []
7
7
  }
@@ -46,7 +46,10 @@ var Action = class _Action {
46
46
  this.kwilSigner = kwilSigner;
47
47
  }
48
48
  /**
49
- * Executes a method on the stream
49
+ * Executes a stream method with named parameters
50
+ * @param method - The action name to execute
51
+ * @param inputs - Named parameters for the action
52
+ * @returns Transaction receipt
50
53
  */
51
54
  async executeWithNamedParams(method, inputs) {
52
55
  return this.kwilClient.execute(
@@ -60,7 +63,10 @@ var Action = class _Action {
60
63
  );
61
64
  }
62
65
  /**
63
- * Executes a method on the stream
66
+ * Executes a stream action with a complete ActionBody
67
+ * @param inputs - Complete action body with all execution parameters
68
+ * @param synchronous - Whether to wait for transaction to be mined
69
+ * @returns Transaction receipt
64
70
  */
65
71
  async executeWithActionBody(inputs, synchronous = false) {
66
72
  return this.kwilClient.execute(inputs, this.kwilSigner, synchronous);