@avaprotocol/protocols 0.2.0 → 0.3.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.
- package/README.md +79 -0
- package/dist/index.cjs +169 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +167 -0
- package/dist/tokens/base-sepolia.json +14 -0
- package/dist/tokens/base.json +20 -0
- package/dist/tokens/bnb-mainnet.json +14 -0
- package/dist/tokens/ethereum.json +32 -0
- package/dist/tokens/index.d.ts +53 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/sepolia.json +20 -0
- package/dist/tokens/types.d.ts +47 -0
- package/dist/tokens/types.d.ts.map +1 -0
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -149,6 +149,85 @@ There's no equivalent multi-protocol + multi-chain + addresses + ABIs + topics p
|
|
|
149
149
|
|
|
150
150
|
Address verification: link to the canonical source (Etherscan-verified deployment, protocol docs, official address book). PRs that don't cite a source for the addresses won't merge.
|
|
151
151
|
|
|
152
|
+
## Tokens sidecar (for non-TS consumers)
|
|
153
|
+
|
|
154
|
+
`yarn build` writes a per-chain JSON file under `dist/tokens/` alongside the JS + d.ts outputs:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
dist/tokens/
|
|
158
|
+
├── ethereum.json (chain 1)
|
|
159
|
+
├── sepolia.json (chain 11155111)
|
|
160
|
+
├── base.json (chain 8453)
|
|
161
|
+
├── base-sepolia.json (chain 84532)
|
|
162
|
+
├── bnb-mainnet.json (chain 56)
|
|
163
|
+
└── holesky.json (chain 17000)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Each file is a stable-sorted array of `{ id, name, symbol, decimals }` entries — the same schema the EigenLayer-AVS Go aggregator already consumes under `token_whitelist/*.json`, so a Go service can pick up the catalog without depending on the TS toolchain. `id` is the lowercased address (matching Go's read-side normalization). Metadata fields TS consumers use (`description`, `website`, `logoUrl`, `links`) are intentionally omitted; TS callers import the `Tokens` namespace from source instead.
|
|
167
|
+
|
|
168
|
+
### When to run it
|
|
169
|
+
|
|
170
|
+
- **Automatically** — `yarn build` invokes `yarn build:tokens-sidecar` as its last step, so any release publishes a fresh sidecar in the npm tarball.
|
|
171
|
+
- **Standalone** — `yarn build:tokens-sidecar` when you've edited `src/tokens/` and want to inspect the generated JSON without rebuilding declarations + JS.
|
|
172
|
+
|
|
173
|
+
### Adding a new chain
|
|
174
|
+
|
|
175
|
+
The script throws fast if the catalog grows a token on a chain that isn't registered in `CHAIN_FILE_NAMES` inside `scripts/build-tokens-sidecar.ts`:
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
[tokens-sidecar] no file name registered for chain <id>.
|
|
179
|
+
Add it to CHAIN_FILE_NAMES in scripts/build-tokens-sidecar.ts.
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Fix is one line — append `[Chains.NewChain]: "newchain-mainnet"` to the map. The error message points at the exact file so this can't silently ship an incomplete sidecar.
|
|
183
|
+
|
|
184
|
+
### Consuming the sidecar (Go example)
|
|
185
|
+
|
|
186
|
+
```go
|
|
187
|
+
// EigenLayer-AVS already does this for its checked-in
|
|
188
|
+
// token_whitelist/*.json; the dist/tokens/*.json from this package
|
|
189
|
+
// match the same schema.
|
|
190
|
+
type tokenEntry struct {
|
|
191
|
+
ID string `json:"id"`
|
|
192
|
+
Name string `json:"name"`
|
|
193
|
+
Symbol string `json:"symbol"`
|
|
194
|
+
Decimals int `json:"decimals"`
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
raw, err := os.ReadFile("path/to/dist/tokens/sepolia.json")
|
|
198
|
+
// ... json.Unmarshal(raw, &entries) ...
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Releasing
|
|
202
|
+
|
|
203
|
+
This package uses [changesets](https://github.com/changesets/changesets) for versioning. The day-to-day flow:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# 1. Make your code changes on a feature branch.
|
|
207
|
+
yarn changeset # interactive prompt; pick bump level + write the changelog entry
|
|
208
|
+
git add .changeset && git commit -m "..."
|
|
209
|
+
git push # open PR as normal
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
When the PR merges to `main`, the `Release` workflow (`.github/workflows/release.yml`) either:
|
|
213
|
+
|
|
214
|
+
- Opens (or updates) a "Version Packages" PR that runs `yarn changeset version` — bumps `package.json` + writes `CHANGELOG.md`. Review and merge that PR.
|
|
215
|
+
- Or, if there are no pending changesets, runs `yarn release` (`yarn build && yarn changeset publish`) — which publishes to npm with the right dist-tag automatically (stable → `latest`, pre-release → its identifier).
|
|
216
|
+
|
|
217
|
+
### Publishing manually (escape hatch)
|
|
218
|
+
|
|
219
|
+
If you need to publish without the GitHub Action — e.g. an emergency release from a machine that has `npm login` credentials:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
yarn build # produces dist/ + tokens sidecar
|
|
223
|
+
npm whoami # verify logged in
|
|
224
|
+
npm publish --access public # for stable versions; goes to `latest`
|
|
225
|
+
# or for a pre-release:
|
|
226
|
+
npm publish --access public --tag dev
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
`prepublishOnly: yarn build` runs the build chain automatically if you forget, so even `npm publish` alone is safe.
|
|
230
|
+
|
|
152
231
|
## Versioning
|
|
153
232
|
|
|
154
233
|
Semver. Until `1.0.0`, breaking changes can land in minor versions (`0.x`), but address corrections are always patches.
|
package/dist/index.cjs
CHANGED
|
@@ -22,6 +22,7 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
Chains: () => Chains,
|
|
24
24
|
Protocols: () => Protocols,
|
|
25
|
+
Tokens: () => Tokens,
|
|
25
26
|
aaveV3: () => aaveV3,
|
|
26
27
|
aerodrome: () => aerodrome,
|
|
27
28
|
aggregatorV3Abi: () => aggregatorV3Abi,
|
|
@@ -32,6 +33,7 @@ __export(index_exports, {
|
|
|
32
33
|
ethena: () => ethena,
|
|
33
34
|
fraxEther: () => fraxEther,
|
|
34
35
|
lido: () => lido,
|
|
36
|
+
lookupToken: () => lookupToken,
|
|
35
37
|
morphoBlue: () => morphoBlue,
|
|
36
38
|
rocketPool: () => rocketPool,
|
|
37
39
|
sky: () => sky,
|
|
@@ -844,10 +846,176 @@ var Protocols = Object.freeze({
|
|
|
844
846
|
uniswapV3,
|
|
845
847
|
wrapped
|
|
846
848
|
});
|
|
849
|
+
|
|
850
|
+
// src/tokens/index.ts
|
|
851
|
+
var USDC = {
|
|
852
|
+
[Chains.EthereumMainnet]: {
|
|
853
|
+
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
854
|
+
decimals: 6,
|
|
855
|
+
name: "USD Coin",
|
|
856
|
+
description: "Fully-reserved USD stablecoin issued by Circle.",
|
|
857
|
+
website: "https://www.circle.com/usdc",
|
|
858
|
+
explorer: "https://etherscan.io/token/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
859
|
+
logoUrl: "https://raw.githubusercontent.com/AvaProtocol/protocols/main/logos/ethereum/USDC.png",
|
|
860
|
+
links: {
|
|
861
|
+
coingecko: "https://www.coingecko.com/en/coins/usd-coin",
|
|
862
|
+
coinmarketcap: "https://coinmarketcap.com/currencies/usd-coin/"
|
|
863
|
+
}
|
|
864
|
+
},
|
|
865
|
+
[Chains.BaseMainnet]: {
|
|
866
|
+
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
867
|
+
decimals: 6,
|
|
868
|
+
name: "USD Coin",
|
|
869
|
+
explorer: "https://basescan.org/token/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
870
|
+
},
|
|
871
|
+
[Chains.Sepolia]: {
|
|
872
|
+
address: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
873
|
+
decimals: 6,
|
|
874
|
+
name: "USD Coin (Sepolia)",
|
|
875
|
+
explorer: "https://sepolia.etherscan.io/token/0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
|
|
876
|
+
},
|
|
877
|
+
[Chains.BaseSepolia]: {
|
|
878
|
+
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
879
|
+
decimals: 6,
|
|
880
|
+
name: "USD Coin (Base Sepolia)",
|
|
881
|
+
explorer: "https://sepolia.basescan.org/token/0x036CbD53842c5426634e7929541eC2318f3dCF7e"
|
|
882
|
+
},
|
|
883
|
+
[Chains.BnbMainnet]: {
|
|
884
|
+
address: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
|
|
885
|
+
decimals: 18,
|
|
886
|
+
name: "Binance-Peg USD Coin",
|
|
887
|
+
explorer: "https://bscscan.com/token/0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"
|
|
888
|
+
}
|
|
889
|
+
};
|
|
890
|
+
var USDT = {
|
|
891
|
+
[Chains.EthereumMainnet]: {
|
|
892
|
+
address: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
893
|
+
decimals: 6,
|
|
894
|
+
name: "Tether USD",
|
|
895
|
+
description: "USD-pegged stablecoin issued by Tether.",
|
|
896
|
+
website: "https://tether.to",
|
|
897
|
+
explorer: "https://etherscan.io/token/0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
898
|
+
logoUrl: "https://raw.githubusercontent.com/AvaProtocol/protocols/main/logos/ethereum/USDT.png",
|
|
899
|
+
links: {
|
|
900
|
+
coingecko: "https://www.coingecko.com/en/coins/tether",
|
|
901
|
+
coinmarketcap: "https://coinmarketcap.com/currencies/tether/"
|
|
902
|
+
}
|
|
903
|
+
},
|
|
904
|
+
[Chains.BnbMainnet]: {
|
|
905
|
+
address: "0x55d398326f99059fF775485246999027B3197955",
|
|
906
|
+
decimals: 18,
|
|
907
|
+
name: "Binance-Peg Tether USD",
|
|
908
|
+
explorer: "https://bscscan.com/token/0x55d398326f99059fF775485246999027B3197955"
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
var WETH = {
|
|
912
|
+
[Chains.EthereumMainnet]: {
|
|
913
|
+
address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
914
|
+
decimals: 18,
|
|
915
|
+
name: "Wrapped Ether",
|
|
916
|
+
description: "ERC-20 wrapper around native ETH, 1:1 backed.",
|
|
917
|
+
explorer: "https://etherscan.io/token/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
918
|
+
logoUrl: "https://raw.githubusercontent.com/AvaProtocol/protocols/main/logos/ethereum/WETH.png",
|
|
919
|
+
links: {
|
|
920
|
+
coingecko: "https://www.coingecko.com/en/coins/weth"
|
|
921
|
+
}
|
|
922
|
+
},
|
|
923
|
+
[Chains.Sepolia]: {
|
|
924
|
+
address: "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14",
|
|
925
|
+
decimals: 18,
|
|
926
|
+
name: "Wrapped Ether (Sepolia)",
|
|
927
|
+
explorer: "https://sepolia.etherscan.io/token/0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14"
|
|
928
|
+
},
|
|
929
|
+
[Chains.BaseMainnet]: {
|
|
930
|
+
address: "0x4200000000000000000000000000000000000006",
|
|
931
|
+
decimals: 18,
|
|
932
|
+
name: "Wrapped Ether",
|
|
933
|
+
explorer: "https://basescan.org/token/0x4200000000000000000000000000000000000006"
|
|
934
|
+
},
|
|
935
|
+
[Chains.BaseSepolia]: {
|
|
936
|
+
address: "0x4200000000000000000000000000000000000006",
|
|
937
|
+
decimals: 18,
|
|
938
|
+
name: "Wrapped Ether (Base Sepolia)",
|
|
939
|
+
explorer: "https://sepolia.basescan.org/token/0x4200000000000000000000000000000000000006"
|
|
940
|
+
}
|
|
941
|
+
};
|
|
942
|
+
var DAI = {
|
|
943
|
+
[Chains.EthereumMainnet]: {
|
|
944
|
+
address: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
945
|
+
decimals: 18,
|
|
946
|
+
name: "Dai Stablecoin",
|
|
947
|
+
description: "Decentralized USD-pegged stablecoin issued by MakerDAO.",
|
|
948
|
+
website: "https://makerdao.com",
|
|
949
|
+
explorer: "https://etherscan.io/token/0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
950
|
+
logoUrl: "https://raw.githubusercontent.com/AvaProtocol/protocols/main/logos/ethereum/DAI.png",
|
|
951
|
+
links: {
|
|
952
|
+
coingecko: "https://www.coingecko.com/en/coins/dai",
|
|
953
|
+
coinmarketcap: "https://coinmarketcap.com/currencies/multi-collateral-dai/"
|
|
954
|
+
}
|
|
955
|
+
},
|
|
956
|
+
[Chains.BaseMainnet]: {
|
|
957
|
+
address: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
|
958
|
+
decimals: 18,
|
|
959
|
+
name: "Dai Stablecoin",
|
|
960
|
+
explorer: "https://basescan.org/token/0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb"
|
|
961
|
+
}
|
|
962
|
+
};
|
|
963
|
+
var LINK = {
|
|
964
|
+
[Chains.EthereumMainnet]: {
|
|
965
|
+
address: "0x514910771AF9Ca656af840dff83E8264EcF986CA",
|
|
966
|
+
decimals: 18,
|
|
967
|
+
name: "ChainLink Token",
|
|
968
|
+
description: "Native token of the Chainlink decentralized oracle network.",
|
|
969
|
+
website: "https://chain.link",
|
|
970
|
+
explorer: "https://etherscan.io/token/0x514910771AF9Ca656af840dff83E8264EcF986CA",
|
|
971
|
+
logoUrl: "https://raw.githubusercontent.com/AvaProtocol/protocols/main/logos/ethereum/LINK.png",
|
|
972
|
+
links: {
|
|
973
|
+
coingecko: "https://www.coingecko.com/en/coins/chainlink",
|
|
974
|
+
coinmarketcap: "https://coinmarketcap.com/currencies/chainlink/"
|
|
975
|
+
}
|
|
976
|
+
},
|
|
977
|
+
[Chains.Sepolia]: {
|
|
978
|
+
// AAVE V3 faucet-mintable LINK on Sepolia — NOT canonical Chainlink LINK.
|
|
979
|
+
// Templates targeting the AAVE Sepolia market need this address; the real
|
|
980
|
+
// Chainlink LINK on Sepolia is at 0x779877A7B0D9E8603169DdbD7836e478b4624789.
|
|
981
|
+
address: "0xf8Fb3713D459D7C1018BD0A49D19b4C44290EBE5",
|
|
982
|
+
decimals: 18,
|
|
983
|
+
name: "ChainLink Token (AAVE Sepolia faucet)",
|
|
984
|
+
explorer: "https://sepolia.etherscan.io/token/0xf8Fb3713D459D7C1018BD0A49D19b4C44290EBE5"
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
var Tokens = Object.freeze({
|
|
988
|
+
USDC,
|
|
989
|
+
USDT,
|
|
990
|
+
WETH,
|
|
991
|
+
DAI,
|
|
992
|
+
LINK
|
|
993
|
+
});
|
|
994
|
+
function lookupToken(chainId, address) {
|
|
995
|
+
if (!address) return void 0;
|
|
996
|
+
const target = address.toLowerCase();
|
|
997
|
+
if (chainId) {
|
|
998
|
+
for (const [symbol, byChain] of Object.entries(Tokens)) {
|
|
999
|
+
const entry = byChain[chainId];
|
|
1000
|
+
if (entry && entry.address.toLowerCase() === target) {
|
|
1001
|
+
return { symbol, ...entry };
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
for (const [symbol, byChain] of Object.entries(Tokens)) {
|
|
1006
|
+
for (const entry of Object.values(byChain)) {
|
|
1007
|
+
if (entry && entry.address.toLowerCase() === target) {
|
|
1008
|
+
return { symbol, ...entry };
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
return void 0;
|
|
1013
|
+
}
|
|
847
1014
|
// Annotate the CommonJS export names for ESM import in node:
|
|
848
1015
|
0 && (module.exports = {
|
|
849
1016
|
Chains,
|
|
850
1017
|
Protocols,
|
|
1018
|
+
Tokens,
|
|
851
1019
|
aaveV3,
|
|
852
1020
|
aerodrome,
|
|
853
1021
|
aggregatorV3Abi,
|
|
@@ -858,6 +1026,7 @@ var Protocols = Object.freeze({
|
|
|
858
1026
|
ethena,
|
|
859
1027
|
fraxEther,
|
|
860
1028
|
lido,
|
|
1029
|
+
lookupToken,
|
|
861
1030
|
morphoBlue,
|
|
862
1031
|
rocketPool,
|
|
863
1032
|
sky,
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgBA,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC/C,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -800,9 +800,175 @@ var Protocols = Object.freeze({
|
|
|
800
800
|
uniswapV3,
|
|
801
801
|
wrapped
|
|
802
802
|
});
|
|
803
|
+
|
|
804
|
+
// src/tokens/index.ts
|
|
805
|
+
var USDC = {
|
|
806
|
+
[Chains.EthereumMainnet]: {
|
|
807
|
+
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
808
|
+
decimals: 6,
|
|
809
|
+
name: "USD Coin",
|
|
810
|
+
description: "Fully-reserved USD stablecoin issued by Circle.",
|
|
811
|
+
website: "https://www.circle.com/usdc",
|
|
812
|
+
explorer: "https://etherscan.io/token/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
813
|
+
logoUrl: "https://raw.githubusercontent.com/AvaProtocol/protocols/main/logos/ethereum/USDC.png",
|
|
814
|
+
links: {
|
|
815
|
+
coingecko: "https://www.coingecko.com/en/coins/usd-coin",
|
|
816
|
+
coinmarketcap: "https://coinmarketcap.com/currencies/usd-coin/"
|
|
817
|
+
}
|
|
818
|
+
},
|
|
819
|
+
[Chains.BaseMainnet]: {
|
|
820
|
+
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
821
|
+
decimals: 6,
|
|
822
|
+
name: "USD Coin",
|
|
823
|
+
explorer: "https://basescan.org/token/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
824
|
+
},
|
|
825
|
+
[Chains.Sepolia]: {
|
|
826
|
+
address: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
827
|
+
decimals: 6,
|
|
828
|
+
name: "USD Coin (Sepolia)",
|
|
829
|
+
explorer: "https://sepolia.etherscan.io/token/0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
|
|
830
|
+
},
|
|
831
|
+
[Chains.BaseSepolia]: {
|
|
832
|
+
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
833
|
+
decimals: 6,
|
|
834
|
+
name: "USD Coin (Base Sepolia)",
|
|
835
|
+
explorer: "https://sepolia.basescan.org/token/0x036CbD53842c5426634e7929541eC2318f3dCF7e"
|
|
836
|
+
},
|
|
837
|
+
[Chains.BnbMainnet]: {
|
|
838
|
+
address: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
|
|
839
|
+
decimals: 18,
|
|
840
|
+
name: "Binance-Peg USD Coin",
|
|
841
|
+
explorer: "https://bscscan.com/token/0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
var USDT = {
|
|
845
|
+
[Chains.EthereumMainnet]: {
|
|
846
|
+
address: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
847
|
+
decimals: 6,
|
|
848
|
+
name: "Tether USD",
|
|
849
|
+
description: "USD-pegged stablecoin issued by Tether.",
|
|
850
|
+
website: "https://tether.to",
|
|
851
|
+
explorer: "https://etherscan.io/token/0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
852
|
+
logoUrl: "https://raw.githubusercontent.com/AvaProtocol/protocols/main/logos/ethereum/USDT.png",
|
|
853
|
+
links: {
|
|
854
|
+
coingecko: "https://www.coingecko.com/en/coins/tether",
|
|
855
|
+
coinmarketcap: "https://coinmarketcap.com/currencies/tether/"
|
|
856
|
+
}
|
|
857
|
+
},
|
|
858
|
+
[Chains.BnbMainnet]: {
|
|
859
|
+
address: "0x55d398326f99059fF775485246999027B3197955",
|
|
860
|
+
decimals: 18,
|
|
861
|
+
name: "Binance-Peg Tether USD",
|
|
862
|
+
explorer: "https://bscscan.com/token/0x55d398326f99059fF775485246999027B3197955"
|
|
863
|
+
}
|
|
864
|
+
};
|
|
865
|
+
var WETH = {
|
|
866
|
+
[Chains.EthereumMainnet]: {
|
|
867
|
+
address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
868
|
+
decimals: 18,
|
|
869
|
+
name: "Wrapped Ether",
|
|
870
|
+
description: "ERC-20 wrapper around native ETH, 1:1 backed.",
|
|
871
|
+
explorer: "https://etherscan.io/token/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
872
|
+
logoUrl: "https://raw.githubusercontent.com/AvaProtocol/protocols/main/logos/ethereum/WETH.png",
|
|
873
|
+
links: {
|
|
874
|
+
coingecko: "https://www.coingecko.com/en/coins/weth"
|
|
875
|
+
}
|
|
876
|
+
},
|
|
877
|
+
[Chains.Sepolia]: {
|
|
878
|
+
address: "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14",
|
|
879
|
+
decimals: 18,
|
|
880
|
+
name: "Wrapped Ether (Sepolia)",
|
|
881
|
+
explorer: "https://sepolia.etherscan.io/token/0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14"
|
|
882
|
+
},
|
|
883
|
+
[Chains.BaseMainnet]: {
|
|
884
|
+
address: "0x4200000000000000000000000000000000000006",
|
|
885
|
+
decimals: 18,
|
|
886
|
+
name: "Wrapped Ether",
|
|
887
|
+
explorer: "https://basescan.org/token/0x4200000000000000000000000000000000000006"
|
|
888
|
+
},
|
|
889
|
+
[Chains.BaseSepolia]: {
|
|
890
|
+
address: "0x4200000000000000000000000000000000000006",
|
|
891
|
+
decimals: 18,
|
|
892
|
+
name: "Wrapped Ether (Base Sepolia)",
|
|
893
|
+
explorer: "https://sepolia.basescan.org/token/0x4200000000000000000000000000000000000006"
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
var DAI = {
|
|
897
|
+
[Chains.EthereumMainnet]: {
|
|
898
|
+
address: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
899
|
+
decimals: 18,
|
|
900
|
+
name: "Dai Stablecoin",
|
|
901
|
+
description: "Decentralized USD-pegged stablecoin issued by MakerDAO.",
|
|
902
|
+
website: "https://makerdao.com",
|
|
903
|
+
explorer: "https://etherscan.io/token/0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
904
|
+
logoUrl: "https://raw.githubusercontent.com/AvaProtocol/protocols/main/logos/ethereum/DAI.png",
|
|
905
|
+
links: {
|
|
906
|
+
coingecko: "https://www.coingecko.com/en/coins/dai",
|
|
907
|
+
coinmarketcap: "https://coinmarketcap.com/currencies/multi-collateral-dai/"
|
|
908
|
+
}
|
|
909
|
+
},
|
|
910
|
+
[Chains.BaseMainnet]: {
|
|
911
|
+
address: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
|
912
|
+
decimals: 18,
|
|
913
|
+
name: "Dai Stablecoin",
|
|
914
|
+
explorer: "https://basescan.org/token/0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb"
|
|
915
|
+
}
|
|
916
|
+
};
|
|
917
|
+
var LINK = {
|
|
918
|
+
[Chains.EthereumMainnet]: {
|
|
919
|
+
address: "0x514910771AF9Ca656af840dff83E8264EcF986CA",
|
|
920
|
+
decimals: 18,
|
|
921
|
+
name: "ChainLink Token",
|
|
922
|
+
description: "Native token of the Chainlink decentralized oracle network.",
|
|
923
|
+
website: "https://chain.link",
|
|
924
|
+
explorer: "https://etherscan.io/token/0x514910771AF9Ca656af840dff83E8264EcF986CA",
|
|
925
|
+
logoUrl: "https://raw.githubusercontent.com/AvaProtocol/protocols/main/logos/ethereum/LINK.png",
|
|
926
|
+
links: {
|
|
927
|
+
coingecko: "https://www.coingecko.com/en/coins/chainlink",
|
|
928
|
+
coinmarketcap: "https://coinmarketcap.com/currencies/chainlink/"
|
|
929
|
+
}
|
|
930
|
+
},
|
|
931
|
+
[Chains.Sepolia]: {
|
|
932
|
+
// AAVE V3 faucet-mintable LINK on Sepolia — NOT canonical Chainlink LINK.
|
|
933
|
+
// Templates targeting the AAVE Sepolia market need this address; the real
|
|
934
|
+
// Chainlink LINK on Sepolia is at 0x779877A7B0D9E8603169DdbD7836e478b4624789.
|
|
935
|
+
address: "0xf8Fb3713D459D7C1018BD0A49D19b4C44290EBE5",
|
|
936
|
+
decimals: 18,
|
|
937
|
+
name: "ChainLink Token (AAVE Sepolia faucet)",
|
|
938
|
+
explorer: "https://sepolia.etherscan.io/token/0xf8Fb3713D459D7C1018BD0A49D19b4C44290EBE5"
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
var Tokens = Object.freeze({
|
|
942
|
+
USDC,
|
|
943
|
+
USDT,
|
|
944
|
+
WETH,
|
|
945
|
+
DAI,
|
|
946
|
+
LINK
|
|
947
|
+
});
|
|
948
|
+
function lookupToken(chainId, address) {
|
|
949
|
+
if (!address) return void 0;
|
|
950
|
+
const target = address.toLowerCase();
|
|
951
|
+
if (chainId) {
|
|
952
|
+
for (const [symbol, byChain] of Object.entries(Tokens)) {
|
|
953
|
+
const entry = byChain[chainId];
|
|
954
|
+
if (entry && entry.address.toLowerCase() === target) {
|
|
955
|
+
return { symbol, ...entry };
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
for (const [symbol, byChain] of Object.entries(Tokens)) {
|
|
960
|
+
for (const entry of Object.values(byChain)) {
|
|
961
|
+
if (entry && entry.address.toLowerCase() === target) {
|
|
962
|
+
return { symbol, ...entry };
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
return void 0;
|
|
967
|
+
}
|
|
803
968
|
export {
|
|
804
969
|
Chains,
|
|
805
970
|
Protocols,
|
|
971
|
+
Tokens,
|
|
806
972
|
aaveV3,
|
|
807
973
|
aerodrome,
|
|
808
974
|
aggregatorV3Abi,
|
|
@@ -813,6 +979,7 @@ export {
|
|
|
813
979
|
ethena,
|
|
814
980
|
fraxEther,
|
|
815
981
|
lido,
|
|
982
|
+
lookupToken,
|
|
816
983
|
morphoBlue,
|
|
817
984
|
rocketPool,
|
|
818
985
|
sky,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "0x036cbd53842c5426634e7929541ec2318f3dcf7e",
|
|
4
|
+
"name": "USD Coin (Base Sepolia)",
|
|
5
|
+
"symbol": "USDC",
|
|
6
|
+
"decimals": 6
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "0x4200000000000000000000000000000000000006",
|
|
10
|
+
"name": "Wrapped Ether (Base Sepolia)",
|
|
11
|
+
"symbol": "WETH",
|
|
12
|
+
"decimals": 18
|
|
13
|
+
}
|
|
14
|
+
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "0x50c5725949a6f0c72e6c4a641f24049a917db0cb",
|
|
4
|
+
"name": "Dai Stablecoin",
|
|
5
|
+
"symbol": "DAI",
|
|
6
|
+
"decimals": 18
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
|
|
10
|
+
"name": "USD Coin",
|
|
11
|
+
"symbol": "USDC",
|
|
12
|
+
"decimals": 6
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "0x4200000000000000000000000000000000000006",
|
|
16
|
+
"name": "Wrapped Ether",
|
|
17
|
+
"symbol": "WETH",
|
|
18
|
+
"decimals": 18
|
|
19
|
+
}
|
|
20
|
+
]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
|
|
4
|
+
"name": "Binance-Peg USD Coin",
|
|
5
|
+
"symbol": "USDC",
|
|
6
|
+
"decimals": 18
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "0x55d398326f99059ff775485246999027b3197955",
|
|
10
|
+
"name": "Binance-Peg Tether USD",
|
|
11
|
+
"symbol": "USDT",
|
|
12
|
+
"decimals": 18
|
|
13
|
+
}
|
|
14
|
+
]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "0x6b175474e89094c44da98b954eedeac495271d0f",
|
|
4
|
+
"name": "Dai Stablecoin",
|
|
5
|
+
"symbol": "DAI",
|
|
6
|
+
"decimals": 18
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "0x514910771af9ca656af840dff83e8264ecf986ca",
|
|
10
|
+
"name": "ChainLink Token",
|
|
11
|
+
"symbol": "LINK",
|
|
12
|
+
"decimals": 18
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
|
|
16
|
+
"name": "USD Coin",
|
|
17
|
+
"symbol": "USDC",
|
|
18
|
+
"decimals": 6
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "0xdac17f958d2ee523a2206206994597c13d831ec7",
|
|
22
|
+
"name": "Tether USD",
|
|
23
|
+
"symbol": "USDT",
|
|
24
|
+
"decimals": 6
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
|
|
28
|
+
"name": "Wrapped Ether",
|
|
29
|
+
"symbol": "WETH",
|
|
30
|
+
"decimals": 18
|
|
31
|
+
}
|
|
32
|
+
]
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type TokenChainEntry } from "./types";
|
|
2
|
+
export type { TokenByChain, TokenChainEntry, TokenLinks } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Symbol → per-chain entry. The outer object is frozen at module
|
|
5
|
+
* load, so the symbol set is immutable. The inner per-chain maps
|
|
6
|
+
* (e.g. `Tokens.USDC`) are NOT deep-frozen — callers must treat
|
|
7
|
+
* them as logically read-only. The shallow freeze is the right
|
|
8
|
+
* tradeoff: deep-freezing the chain maps + their entries on every
|
|
9
|
+
* import would add overhead for a guarantee no consumer has asked
|
|
10
|
+
* for. Add a deep-freeze pass here if a real misuse case emerges.
|
|
11
|
+
*
|
|
12
|
+
* Symbol keys are the canonical uppercase ERC-20 ticker (USDC, not
|
|
13
|
+
* usdc/Usdc). The catalog is intentionally not case-insensitive at
|
|
14
|
+
* this level — callers needing a fuzzy lookup should normalize at
|
|
15
|
+
* their own boundary.
|
|
16
|
+
*/
|
|
17
|
+
export declare const Tokens: Readonly<{
|
|
18
|
+
USDC: Partial<Record<number, TokenChainEntry>>;
|
|
19
|
+
USDT: Partial<Record<number, TokenChainEntry>>;
|
|
20
|
+
WETH: Partial<Record<number, TokenChainEntry>>;
|
|
21
|
+
DAI: Partial<Record<number, TokenChainEntry>>;
|
|
22
|
+
LINK: Partial<Record<number, TokenChainEntry>>;
|
|
23
|
+
}>;
|
|
24
|
+
/**
|
|
25
|
+
* Reverse lookup: given a contract address, find the token entry plus
|
|
26
|
+
* its symbol. Address matching is case-insensitive so callers can pass
|
|
27
|
+
* checksum or lowercase without normalizing upstream.
|
|
28
|
+
*
|
|
29
|
+
* Resolution strategy:
|
|
30
|
+
* 1. When `chainId` is provided, prefer a match registered for that
|
|
31
|
+
* chain.
|
|
32
|
+
* 2. If no chain-specific match (or no chainId), scan every chain
|
|
33
|
+
* for the address. Necessary when the caller's chain context
|
|
34
|
+
* diverges from where the address actually lives — happens in
|
|
35
|
+
* multi-chain dev gateways where the workflow targets one chain
|
|
36
|
+
* but the runtime is bound to a different one. Most ERC-20
|
|
37
|
+
* addresses are globally unique so this collapses to a single
|
|
38
|
+
* match; for OP-stack predeploys (e.g. WETH at 0x4200…0006 on
|
|
39
|
+
* both Base and Base Sepolia), any match yields the correct
|
|
40
|
+
* symbol and decimals.
|
|
41
|
+
*
|
|
42
|
+
* Returns `undefined` when no chain in the catalog carries the
|
|
43
|
+
* address, or when the address is missing/falsy.
|
|
44
|
+
*
|
|
45
|
+
* Typical use: aggregator payloads ship `tokenSymbol="UNKNOWN"` for
|
|
46
|
+
* tokens whose chain-specific RPC enrichment failed; consumers fall
|
|
47
|
+
* through to `lookupToken(chainId, contractAddress)` and recover the
|
|
48
|
+
* symbol + decimals from this catalog.
|
|
49
|
+
*/
|
|
50
|
+
export declare function lookupToken(chainId: number | undefined, address: string | undefined): (TokenChainEntry & {
|
|
51
|
+
symbol: string;
|
|
52
|
+
}) | undefined;
|
|
53
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tokens/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AAElE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AA+IzE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,MAAM;;;;;;EAMgC,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,CAAC,eAAe,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,CAsBpD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "0xf8fb3713d459d7c1018bd0a49d19b4c44290ebe5",
|
|
4
|
+
"name": "ChainLink Token (AAVE Sepolia faucet)",
|
|
5
|
+
"symbol": "LINK",
|
|
6
|
+
"decimals": 18
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "0x1c7d4b196cb0c7b01d743fbc6116a902379c7238",
|
|
10
|
+
"name": "USD Coin (Sepolia)",
|
|
11
|
+
"symbol": "USDC",
|
|
12
|
+
"decimals": 6
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "0xfff9976782d46cc05630d1f6ebab18b2324d6b14",
|
|
16
|
+
"name": "Wrapped Ether (Sepolia)",
|
|
17
|
+
"symbol": "WETH",
|
|
18
|
+
"decimals": 18
|
|
19
|
+
}
|
|
20
|
+
]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type ChainId } from "../chains";
|
|
2
|
+
/**
|
|
3
|
+
* External reference links for a token. All fields optional — the
|
|
4
|
+
* catalog only records what's actually known per token. Add new keys
|
|
5
|
+
* here when adding a category we want to surface; consumers ignore
|
|
6
|
+
* unknown keys harmlessly.
|
|
7
|
+
*/
|
|
8
|
+
export interface TokenLinks {
|
|
9
|
+
readonly github?: string;
|
|
10
|
+
readonly twitter?: string;
|
|
11
|
+
readonly coingecko?: string;
|
|
12
|
+
readonly coinmarketcap?: string;
|
|
13
|
+
readonly reddit?: string;
|
|
14
|
+
readonly blog?: string;
|
|
15
|
+
readonly whitepaper?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Per-chain token deployment record. `address` and `decimals` are
|
|
19
|
+
* required because they're the universal lookup primitives every
|
|
20
|
+
* consumer needs. All other fields are optional metadata.
|
|
21
|
+
*
|
|
22
|
+
* `name` is per-chain because some tokens use different display names
|
|
23
|
+
* on different deployments (e.g. AAVE's faucet-LINK on Sepolia is
|
|
24
|
+
* "ChainLink Token" vs. "Chainlink" on mainnet). When the chains
|
|
25
|
+
* agree, the same string is fine to repeat.
|
|
26
|
+
*
|
|
27
|
+
* `logoUrl` is a fully qualified URL — typically a GitHub Raw or CDN
|
|
28
|
+
* link. Studio renders local PNGs by resolving symbol+chain itself
|
|
29
|
+
* and ignores this field; backend consumers may surface the URL
|
|
30
|
+
* directly in summaries or skip it.
|
|
31
|
+
*/
|
|
32
|
+
export interface TokenChainEntry {
|
|
33
|
+
readonly address: `0x${string}`;
|
|
34
|
+
readonly decimals: number;
|
|
35
|
+
readonly name?: string;
|
|
36
|
+
readonly description?: string;
|
|
37
|
+
readonly website?: string;
|
|
38
|
+
readonly explorer?: string;
|
|
39
|
+
readonly logoUrl?: string;
|
|
40
|
+
readonly links?: TokenLinks;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Map of `ChainId → TokenChainEntry`. `Partial` because no token is
|
|
44
|
+
* deployed on every chain in the catalog.
|
|
45
|
+
*/
|
|
46
|
+
export type TokenByChain = Partial<Record<ChainId, TokenChainEntry>>;
|
|
47
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tokens/types.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avaprotocol/protocols",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Multi-chain catalog of DeFi protocol contract addresses, ABI fragments, and event topic hashes — covers AAVE V3, Uniswap V3, Chainlink, Lido, Morpho, and more.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"defi",
|
|
@@ -50,17 +50,23 @@
|
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build:declarations": "tsc -p tsconfig.build.json",
|
|
52
52
|
"build:js": "tsup src/index.ts --format cjs,esm --target es2020",
|
|
53
|
-
"build": "
|
|
53
|
+
"build:tokens-sidecar": "tsx scripts/build-tokens-sidecar.ts",
|
|
54
|
+
"build": "yarn clean:dist && yarn build:declarations && yarn build:js && yarn build:tokens-sidecar",
|
|
54
55
|
"clean": "rm -rf node_modules dist tsconfig.tsbuildinfo",
|
|
55
56
|
"clean:dist": "rm -rf dist tsconfig.tsbuildinfo",
|
|
56
57
|
"test": "vitest",
|
|
57
58
|
"test:run": "vitest run",
|
|
58
59
|
"typecheck": "tsc --noEmit",
|
|
59
60
|
"lint": "tsc --noEmit",
|
|
60
|
-
"prepublishOnly": "yarn build"
|
|
61
|
+
"prepublishOnly": "yarn build",
|
|
62
|
+
"changeset": "changeset",
|
|
63
|
+
"version-packages": "changeset version",
|
|
64
|
+
"release": "yarn build && changeset publish"
|
|
61
65
|
},
|
|
62
66
|
"devDependencies": {
|
|
67
|
+
"@changesets/cli": "^2.31.0",
|
|
63
68
|
"tsup": "^8.5.0",
|
|
69
|
+
"tsx": "^4.19.0",
|
|
64
70
|
"typescript": "^5.5.4",
|
|
65
71
|
"vitest": "^1.6.0"
|
|
66
72
|
},
|