@indexing/jiti 0.0.75 → 0.0.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +69 -0
- package/README.md +128 -6
- package/dist/main.js +83 -3
- package/dist/main.js.map +1 -1
- package/dist/module.js +83 -3
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides context for AI assistants working on this codebase.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
JITI (Just In Time Indexing) is a TypeScript library that extracts structured data from raw blockchain blocks. It provides a unified `NetworkTransfer` type across 15+ blockchain VMs.
|
|
8
|
+
|
|
9
|
+
Published as `@indexing/jiti` on npm.
|
|
10
|
+
|
|
11
|
+
## Build & Test
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install # install dependencies
|
|
15
|
+
npm test # run tests (ts-node tests.ts) - requires API_KEY in .env
|
|
16
|
+
npm run build # build with parcel (outputs to dist/)
|
|
17
|
+
npm run lint # prettier + eslint
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Tests fetch real block data from `https://jiti.indexing.co/networks/{network}/{block}` and compare output against expected values using `assert.deepStrictEqual`. An `API_KEY` environment variable is required.
|
|
21
|
+
|
|
22
|
+
## Project Structure
|
|
23
|
+
|
|
24
|
+
- `src/index.ts` - Main entry point, exports templates and utilities
|
|
25
|
+
- `src/types.ts` - Core types: `Template`, `SubTemplate`, `VMType`, `NetworkType`
|
|
26
|
+
- `src/templates/token-transfers/` - Per-chain token transfer extraction (one file per VM type)
|
|
27
|
+
- `src/templates/token-transfers/index.ts` - Orchestrator that routes blocks to the right chain handler
|
|
28
|
+
- `src/templates/token-transfers/types.ts` - `NetworkTransfer` type definition
|
|
29
|
+
- `src/templates/filter-values.ts` - Filter values template
|
|
30
|
+
- `src/templates/raw.ts` - Pass-through raw block template (disabled)
|
|
31
|
+
- `src/utils/` - Multi-chain utility functions (block parsing, EVM helpers)
|
|
32
|
+
- `tests.ts` - Test runner that validates all template outputs
|
|
33
|
+
|
|
34
|
+
## Key Patterns
|
|
35
|
+
|
|
36
|
+
### Adding/Modifying Chain Support
|
|
37
|
+
|
|
38
|
+
Each chain's token transfer logic is in `src/templates/token-transfers/{chain}.ts` and implements the `SubTemplate` interface with `match`, `transform`, and `tests`.
|
|
39
|
+
|
|
40
|
+
- `match(block)` uses `blockToVM(block)` from `src/utils/block-to-vm.ts` to detect the chain
|
|
41
|
+
- `transform(block)` returns `NetworkTransfer[]`
|
|
42
|
+
- `tests` include real block URLs and expected outputs - tests are inline, not in separate files
|
|
43
|
+
|
|
44
|
+
To register a new chain, add it to the `SUB_TEMPLATES` array in `src/templates/token-transfers/index.ts`. Universal templates (EVM, Cosmos) go in `UNIVERSAL_SUB_TEMPLATES`.
|
|
45
|
+
|
|
46
|
+
### VM Detection
|
|
47
|
+
|
|
48
|
+
`blockToVM()` in `src/utils/block-to-vm.ts` maps network names to VM types. EVM is the default fallback. Chain-specific VMs (CARDANO, UTXO, SVM, etc.) are explicitly mapped.
|
|
49
|
+
|
|
50
|
+
### Filtering
|
|
51
|
+
|
|
52
|
+
The main `tokenTransfers` template in `index.ts` applies post-processing filters:
|
|
53
|
+
- `walletAddress` - matches against `from` or `to`
|
|
54
|
+
- `contractAddress` - matches against `token`
|
|
55
|
+
- `transactionHash` - exact match
|
|
56
|
+
- Deduplication via composite key
|
|
57
|
+
- Zero-amount transfers are excluded
|
|
58
|
+
|
|
59
|
+
## CI/CD
|
|
60
|
+
|
|
61
|
+
- `.github/workflows/publish.yml` - On push to main: test, bump patch version, build, commit version back (via deploy key), publish to npm
|
|
62
|
+
- `.github/workflows/artifacts.yml` - On push: build and upload dist artifacts
|
|
63
|
+
- Version bumps use `[skip ci]` to avoid infinite loops
|
|
64
|
+
|
|
65
|
+
## Code Style
|
|
66
|
+
|
|
67
|
+
- Prettier: single quotes, 120 char width, es5 trailing commas
|
|
68
|
+
- ESLint with prettier plugin
|
|
69
|
+
- TypeScript targeting ES2020
|
package/README.md
CHANGED
|
@@ -1,13 +1,135 @@
|
|
|
1
|
-
# Just In Time Indexing
|
|
1
|
+
# JITI - Just In Time Indexing
|
|
2
2
|
|
|
3
|
-
Open source template library for
|
|
3
|
+
Open source template library for extracting and transforming blockchain data across 15+ networks. Built by [Indexing Co](https://indexing.co).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install @indexing/jiti
|
|
9
|
+
```
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
JITI provides a unified interface for extracting structured data from raw blockchain blocks. It ships with built-in templates for common use cases and utility functions for working with multi-chain data.
|
|
14
|
+
|
|
15
|
+
### Supported Networks
|
|
16
|
+
|
|
17
|
+
| VM Type | Networks |
|
|
18
|
+
|---------|----------|
|
|
19
|
+
| **EVM** | Ethereum, Polygon, Arbitrum, Base, Optimism, Avalanche, and [100+ more](src/utils/evm-chain-to-id.ts) |
|
|
20
|
+
| **SVM** | Solana, Eclipse |
|
|
21
|
+
| **UTXO** | Bitcoin, Litecoin, Dogecoin, Zcash |
|
|
22
|
+
| **Substrate** | Polkadot, Kusama, Astar, Bittensor, Enjin |
|
|
23
|
+
| **Cosmos** | Cosmos Hub and Tendermint-based chains |
|
|
24
|
+
| **Aptos** | Aptos, Movement |
|
|
25
|
+
| **Cardano** | Cardano |
|
|
26
|
+
| **Sui** | Sui |
|
|
27
|
+
| **Starknet** | Starknet |
|
|
28
|
+
| **Stellar** | Stellar |
|
|
29
|
+
| **Filecoin** | Filecoin |
|
|
30
|
+
| **Ripple** | XRP Ledger |
|
|
31
|
+
| **TON** | The Open Network |
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
### Token Transfers
|
|
36
|
+
|
|
37
|
+
Extract token transfers from any supported block with a single interface:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { templates } from '@indexing/jiti';
|
|
41
|
+
|
|
42
|
+
const transfers = templates.tokenTransfers.transform(block, {
|
|
43
|
+
params: {
|
|
44
|
+
network: 'ETHEREUM',
|
|
45
|
+
walletAddress: '0x...', // optional - filter by wallet
|
|
46
|
+
contractAddress: '0x...', // optional - filter by token contract
|
|
47
|
+
tokenTypes: ['NATIVE', 'TOKEN', 'NFT'], // optional - filter by type
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Each transfer follows the `NetworkTransfer` type:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
type NetworkTransfer = {
|
|
56
|
+
amount: number | bigint;
|
|
57
|
+
blockNumber: number;
|
|
58
|
+
from: string;
|
|
59
|
+
to: string;
|
|
60
|
+
token?: string;
|
|
61
|
+
tokenId?: string;
|
|
62
|
+
tokenType: 'NATIVE' | 'TOKEN' | 'NFT';
|
|
63
|
+
transactionHash: string;
|
|
64
|
+
transactionGasFee: bigint;
|
|
65
|
+
timestamp: string;
|
|
66
|
+
};
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Utilities
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { utils } from '@indexing/jiti';
|
|
73
|
+
|
|
74
|
+
// Detect the VM type from a raw block
|
|
75
|
+
utils.blockToVM(block); // 'EVM' | 'SVM' | 'CARDANO' | ...
|
|
76
|
+
|
|
77
|
+
// Extract block number, timestamp, or tx hashes from any block
|
|
78
|
+
utils.blockToBeat(block);
|
|
79
|
+
utils.blockToTimestamp(block);
|
|
80
|
+
utils.blockToTransactionHashes(block);
|
|
81
|
+
|
|
82
|
+
// EVM-specific helpers
|
|
83
|
+
utils.evmChainToId('ETHEREUM'); // 1
|
|
84
|
+
utils.evmIdToChain(137); // 'POLYGON'
|
|
85
|
+
utils.evmAddressToChecksum('0xabc...');
|
|
86
|
+
utils.evmDecodeLog(log, abi);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Development
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Install dependencies
|
|
93
|
+
npm install
|
|
94
|
+
|
|
95
|
+
# Run tests
|
|
96
|
+
npm test
|
|
97
|
+
|
|
98
|
+
# Build
|
|
99
|
+
npm run build
|
|
100
|
+
|
|
101
|
+
# Lint & format
|
|
102
|
+
npm run lint
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Adding a New Network
|
|
106
|
+
|
|
107
|
+
Token transfer templates live in `src/templates/token-transfers/`. Each network implements the `SubTemplate` interface:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { SubTemplate } from '../../types';
|
|
111
|
+
|
|
112
|
+
export const MyChainTokenTransfers: SubTemplate = {
|
|
113
|
+
match: (block) => /* return true if this block belongs to your chain */,
|
|
114
|
+
transform(block) {
|
|
115
|
+
// Parse the block and return NetworkTransfer[]
|
|
116
|
+
},
|
|
117
|
+
tests: [
|
|
118
|
+
{
|
|
119
|
+
params: { network: 'MY_CHAIN', walletAddress: '...' },
|
|
120
|
+
payload: 'https://jiti.indexing.co/networks/my_chain/12345',
|
|
121
|
+
output: [/* expected NetworkTransfer objects */],
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
};
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Then register it in `src/templates/token-transfers/index.ts`.
|
|
128
|
+
|
|
129
|
+
## Contributing
|
|
130
|
+
|
|
131
|
+
Contributions are welcome! Please open an issue or submit a pull request.
|
|
10
132
|
|
|
11
133
|
## License
|
|
12
134
|
|
|
13
|
-
|
|
135
|
+
[GPL-3.0-or-later](LICENSE.md) - Copyright 2024 The Indexing Company
|
package/dist/main.js
CHANGED
|
@@ -284,6 +284,7 @@ function $596a656635c74d50$export$db81f9ea057ab646(address) {
|
|
|
284
284
|
var $e5566e47593dc3e2$exports = {};
|
|
285
285
|
|
|
286
286
|
$parcel$export($e5566e47593dc3e2$exports, "evmChainToId", () => $e5566e47593dc3e2$export$f93b8abed77a4120);
|
|
287
|
+
$parcel$export($e5566e47593dc3e2$exports, "evmIdToChain", () => $e5566e47593dc3e2$export$88f733cc92705522);
|
|
287
288
|
const $e5566e47593dc3e2$var$CHAIN_ID = {
|
|
288
289
|
"0G": 16661,
|
|
289
290
|
ABSTRACT: 2741,
|
|
@@ -409,6 +410,11 @@ const $e5566e47593dc3e2$var$CHAIN_ID = {
|
|
|
409
410
|
function $e5566e47593dc3e2$export$f93b8abed77a4120(chain) {
|
|
410
411
|
return $e5566e47593dc3e2$var$CHAIN_ID[chain?.toUpperCase()];
|
|
411
412
|
}
|
|
413
|
+
const $e5566e47593dc3e2$var$ID_TO_CHAIN = {};
|
|
414
|
+
for (const [chain, id] of Object.entries($e5566e47593dc3e2$var$CHAIN_ID))if (!(id in $e5566e47593dc3e2$var$ID_TO_CHAIN)) $e5566e47593dc3e2$var$ID_TO_CHAIN[id] = chain;
|
|
415
|
+
function $e5566e47593dc3e2$export$88f733cc92705522(id) {
|
|
416
|
+
return $e5566e47593dc3e2$var$ID_TO_CHAIN[typeof id === "string" ? Number(id) : id];
|
|
417
|
+
}
|
|
412
418
|
|
|
413
419
|
|
|
414
420
|
var $da55be3e40667945$exports = {};
|
|
@@ -899,20 +905,41 @@ const $60d24c82dc5feb2e$export$893111d8d332e195 = {
|
|
|
899
905
|
return acc + val;
|
|
900
906
|
}, BigInt(0));
|
|
901
907
|
const transactionFee = sumInputs + BigInt(sumOutputs);
|
|
908
|
+
const absFee = transactionFee < 0 ? -transactionFee : transactionFee;
|
|
909
|
+
const blockNumber = block.block_identifier.index;
|
|
902
910
|
for (const out of outputs){
|
|
911
|
+
const toAddress = out.account?.address || "";
|
|
912
|
+
// ADA (native) transfer
|
|
903
913
|
const rawValue = out.amount?.value || "0";
|
|
904
914
|
const absoluteValue = BigInt(rawValue);
|
|
905
915
|
transfers.push({
|
|
906
916
|
amount: absoluteValue < 0 ? -absoluteValue : absoluteValue,
|
|
907
|
-
blockNumber:
|
|
917
|
+
blockNumber: blockNumber,
|
|
908
918
|
from: fromAddress,
|
|
909
919
|
timestamp: blockTimestamp,
|
|
910
|
-
to:
|
|
920
|
+
to: toAddress,
|
|
911
921
|
token: out.amount?.currency?.symbol?.toUpperCase() === "ADA" ? null : out.amount?.currency?.symbol,
|
|
912
922
|
tokenType: out.amount?.currency?.symbol?.toUpperCase() === "ADA" ? "NATIVE" : "TOKEN",
|
|
913
|
-
transactionGasFee:
|
|
923
|
+
transactionGasFee: absFee,
|
|
914
924
|
transactionHash: transactionHash
|
|
915
925
|
});
|
|
926
|
+
// Native tokens from tokenBundle metadata
|
|
927
|
+
if (out.metadata?.tokenBundle) {
|
|
928
|
+
for (const bundle of out.metadata.tokenBundle)for (const tkn of bundle.tokens){
|
|
929
|
+
const tokenValue = BigInt(tkn.value);
|
|
930
|
+
transfers.push({
|
|
931
|
+
amount: tokenValue < 0 ? -tokenValue : tokenValue,
|
|
932
|
+
blockNumber: blockNumber,
|
|
933
|
+
from: fromAddress,
|
|
934
|
+
timestamp: blockTimestamp,
|
|
935
|
+
to: toAddress,
|
|
936
|
+
token: `${bundle.policyId}.${tkn.currency.symbol}`,
|
|
937
|
+
tokenType: "TOKEN",
|
|
938
|
+
transactionGasFee: absFee,
|
|
939
|
+
transactionHash: transactionHash
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
}
|
|
916
943
|
}
|
|
917
944
|
}
|
|
918
945
|
return transfers;
|
|
@@ -938,6 +965,59 @@ const $60d24c82dc5feb2e$export$893111d8d332e195 = {
|
|
|
938
965
|
transactionHash: "261c42ba9124f55d8e169ebb692cd3759d796a54369acb316ee449b546e79309"
|
|
939
966
|
}
|
|
940
967
|
]
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
params: {
|
|
971
|
+
network: "CARDANO",
|
|
972
|
+
transactionHash: "c807ee792e47b47178aea89c9e760020ea24ed80897f9de82a2cd23e05da4d18"
|
|
973
|
+
},
|
|
974
|
+
payload: "https://jiti.indexing.co/networks/cardano/13119492",
|
|
975
|
+
output: [
|
|
976
|
+
{
|
|
977
|
+
amount: 1159390n,
|
|
978
|
+
blockNumber: 13119492,
|
|
979
|
+
from: "addr1q9k660rwqcdsr8e4ema5jd9qahmfquf44n8uszvacvvfswlrzr27g03klu862usxqsru794d03gzkk8n86ta34n85z0s6j9ylh",
|
|
980
|
+
timestamp: "2026-03-05T09:34:59.000Z",
|
|
981
|
+
to: "addr1qxvhvz9860r2qzcmx0qz55gzdt58etren35hhn9etpe3j5yewcy2057x5q93kv7q9fgsy6hg0jk8n8rf00xtjkrnr9gq7mz2sz",
|
|
982
|
+
token: null,
|
|
983
|
+
tokenType: "NATIVE",
|
|
984
|
+
transactionGasFee: 178481n,
|
|
985
|
+
transactionHash: "c807ee792e47b47178aea89c9e760020ea24ed80897f9de82a2cd23e05da4d18"
|
|
986
|
+
},
|
|
987
|
+
{
|
|
988
|
+
amount: 100000000n,
|
|
989
|
+
blockNumber: 13119492,
|
|
990
|
+
from: "addr1q9k660rwqcdsr8e4ema5jd9qahmfquf44n8uszvacvvfswlrzr27g03klu862usxqsru794d03gzkk8n86ta34n85z0s6j9ylh",
|
|
991
|
+
timestamp: "2026-03-05T09:34:59.000Z",
|
|
992
|
+
to: "addr1qxvhvz9860r2qzcmx0qz55gzdt58etren35hhn9etpe3j5yewcy2057x5q93kv7q9fgsy6hg0jk8n8rf00xtjkrnr9gq7mz2sz",
|
|
993
|
+
token: "0691b2fecca1ac4f53cb6dfb00b7013e561d1f34403b957cbb5af1fa.4e49474854",
|
|
994
|
+
tokenType: "TOKEN",
|
|
995
|
+
transactionGasFee: 178481n,
|
|
996
|
+
transactionHash: "c807ee792e47b47178aea89c9e760020ea24ed80897f9de82a2cd23e05da4d18"
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
amount: 172823143n,
|
|
1000
|
+
blockNumber: 13119492,
|
|
1001
|
+
from: "addr1q9k660rwqcdsr8e4ema5jd9qahmfquf44n8uszvacvvfswlrzr27g03klu862usxqsru794d03gzkk8n86ta34n85z0s6j9ylh",
|
|
1002
|
+
timestamp: "2026-03-05T09:34:59.000Z",
|
|
1003
|
+
to: "addr1q8dusprx8fr89xkl88g3gq5kya46s9r4fcnwyx5yhdp3rx8rzr27g03klu862usxqsru794d03gzkk8n86ta34n85z0s8728d0",
|
|
1004
|
+
token: null,
|
|
1005
|
+
tokenType: "NATIVE",
|
|
1006
|
+
transactionGasFee: 178481n,
|
|
1007
|
+
transactionHash: "c807ee792e47b47178aea89c9e760020ea24ed80897f9de82a2cd23e05da4d18"
|
|
1008
|
+
},
|
|
1009
|
+
{
|
|
1010
|
+
amount: 204930000n,
|
|
1011
|
+
blockNumber: 13119492,
|
|
1012
|
+
from: "addr1q9k660rwqcdsr8e4ema5jd9qahmfquf44n8uszvacvvfswlrzr27g03klu862usxqsru794d03gzkk8n86ta34n85z0s6j9ylh",
|
|
1013
|
+
timestamp: "2026-03-05T09:34:59.000Z",
|
|
1014
|
+
to: "addr1q8dusprx8fr89xkl88g3gq5kya46s9r4fcnwyx5yhdp3rx8rzr27g03klu862usxqsru794d03gzkk8n86ta34n85z0s8728d0",
|
|
1015
|
+
token: "0691b2fecca1ac4f53cb6dfb00b7013e561d1f34403b957cbb5af1fa.4e49474854",
|
|
1016
|
+
tokenType: "TOKEN",
|
|
1017
|
+
transactionGasFee: 178481n,
|
|
1018
|
+
transactionHash: "c807ee792e47b47178aea89c9e760020ea24ed80897f9de82a2cd23e05da4d18"
|
|
1019
|
+
}
|
|
1020
|
+
]
|
|
941
1021
|
}
|
|
942
1022
|
]
|
|
943
1023
|
};
|