Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/remove-registry-ibc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@sei-js/registry': major
---

Remove IBC and gas data from the registry package. `IBC_INFO`, `ChannelInfo`, `GAS_INFO`, `ChainGasInfo`, and `ModuleAdjustments` are no longer exported, and `TOKEN_LIST` no longer contains IBC or ICS-20 assets.

Refresh the bundled chain registry data with current network endpoints, explorers, and wallets. `WALLETS` is now available from the package root.

Align token metadata types with the community asset list: `Token.type_asset` replaces the non-runtime `Token.type_token` field, and `DenomUnit.aliases` is optional.
5 changes: 3 additions & 2 deletions packages/registry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ bun add @sei-js/registry

## Usage
```typescript
import { TOKEN_LIST, NETWORKS, IBC_INFO, GAS_INFO } from '@sei-js/registry'
import { TOKEN_LIST, NETWORKS, WALLETS } from '@sei-js/registry'

const uAtom = TOKEN_LIST.find(asset => asset.denom === 'uatom')
const sei = TOKEN_LIST['pacific-1'].find(asset => asset.base === 'usei')
const keplr = WALLETS.find(wallet => wallet.identifier === 'keplr')
```
4 changes: 4 additions & 0 deletions packages/registry/src/chain-info/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ describe('ChainInfo Tests', () => {
it("includes 'secp256k1' in key_algos", () => {
expect(CHAIN_INFO.key_algos).toContain('secp256k1');
});

it('contains the current supported wallets', () => {
expect(CHAIN_INFO.supported_wallets).toEqual(['keplr', 'coin98']);
});
});
37 changes: 0 additions & 37 deletions packages/registry/src/gas/__tests__/index.spec.ts

This file was deleted.

53 changes: 0 additions & 53 deletions packages/registry/src/gas/index.ts

This file was deleted.

36 changes: 0 additions & 36 deletions packages/registry/src/ibc/__tests__/index.spec.ts

This file was deleted.

53 changes: 0 additions & 53 deletions packages/registry/src/ibc/index.ts

This file was deleted.

3 changes: 1 addition & 2 deletions packages/registry/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export * from './chain-info';
export * from './gas';
export * from './ibc';
export * from './networks';
export type { Network } from './supported-networks';
export { CHAIN_IDS } from './supported-networks';
export * from './tokens';
export * from './wallets';
14 changes: 14 additions & 0 deletions packages/registry/src/networks/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,18 @@ describe('Networks configuration', () => {
}
}
});

it('contains the current RPC, EVM, and explorer metadata', () => {
const mainnet = NETWORKS['pacific-1'];
expect(mainnet.rpc.some(({ provider, url }) => provider === 'Rhino' && url === 'https://rpc.sei-apis.com')).toBeTrue();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] These assertions hardcode specific third-party provider names and URLs (Rhino/rpc.sei-apis.com, dRPC/sei.drpc.org, Seistream). If an upstream provider is swapped or an endpoint domain changes, CI breaks on a data refresh rather than on a code defect. A structural check — every rpc/evm_rpc entry has a non-empty provider and a parseable https:// (or wss://) url, and explorers is non-empty — would catch real regressions without coupling the suite to a specific vendor list.

expect(mainnet.evm_rpc?.some(({ provider, url }) => provider === 'dRPC' && url === 'https://sei.drpc.org')).toBeTrue();
expect(mainnet.evm_ws?.some(({ provider, url }) => provider === 'dRPC' && url === 'wss://sei.drpc.org')).toBeTrue();
expect(mainnet.explorers?.some(({ name }) => name === 'Seistream')).toBeTrue();

const testnet = NETWORKS['atlantic-2'];
expect(testnet.rpc.some(({ provider, url }) => provider === 'Sei' && url === 'https://rpc.atlantic-2.seinetwork.io')).toBeTrue();
expect(testnet.evm_rpc?.some(({ provider, url }) => provider === 'dRPC' && url === 'https://sei-testnet.drpc.org')).toBeTrue();
expect(testnet.evm_ws?.some(({ provider, url }) => provider === 'dRPC' && url === 'wss://sei-testnet.drpc.org')).toBeTrue();
expect(testnet.explorers?.some(({ name }) => name === 'Seiscan')).toBeTrue();
});
});
2 changes: 1 addition & 1 deletion packages/registry/src/networks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ type NetworksConfig = {
* ```tsx
* import { NETWORKS } from '@sei-js/registry';
*
* const pacific1 = NETWORKS.find((network) => network.chainId === 'pacific-1');
* const pacific1 = NETWORKS['pacific-1'];
* ```
*/
export const NETWORKS: NetworksConfig = pickSupportedNetworks(NetworksJSON) as NetworksConfig;
12 changes: 11 additions & 1 deletion packages/registry/src/tokens/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,17 @@ describe('AssetList Tests', () => {
if (asset.images.svg) expect(typeof asset.images.svg).toBe('string');
}
if (asset.coingecko_id) expect(typeof asset.coingecko_id).toBe('string');
if (asset.type_token) expect(typeof asset.type_token).toBe('string');
if (asset.type_asset) expect(typeof asset.type_asset).toBe('string');
}
}
});

it('excludes IBC assets', () => {
for (const assets of Object.values(TOKEN_LIST)) {
for (const asset of assets) {
expect(asset.base.toLowerCase().startsWith('ibc/')).toBeFalse();
expect(asset.denom_units.some(({ denom }) => denom.toLowerCase().startsWith('ibc/'))).toBeFalse();
expect(asset.type_asset?.toLowerCase()).not.toBe('ics20');
}
}
});
Expand Down
35 changes: 26 additions & 9 deletions packages/registry/src/tokens/index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,36 @@
import TokenListJSON from '../../community-assetlist/assetlist.json';
import { type Network, pickSupportedNetworks } from '../supported-networks';

interface AssetMetadata {
base: string;
denom_units: readonly {
denom: string;
}[];
type_asset?: string;
}

const isIbcDenomination = (denomination: string): boolean => denomination.toLowerCase().startsWith('ibc/');

const isIbcAsset = (asset: AssetMetadata): boolean =>
isIbcDenomination(asset.base) || asset.denom_units.some(({ denom }) => isIbcDenomination(denom)) || asset.type_asset?.toLowerCase() === 'ics20';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] asset.base.toLowerCase() and asset.denom_units.some(...) are unguarded. This runs at module-import time over community-maintained upstream data, so a single asset entry missing base or denom_units throws a TypeError that takes down the whole @sei-js/registry import rather than just skipping that asset. The build script hits the same access first, so it would surface at build time — but as a bare TypeError with no indication of which asset or file is at fault.

asset.base?.toLowerCase() / asset.denom_units?.some(...) (or a ?? []) costs nothing and keeps the failure mode contained.


/**
* DenomUnit represents a struct that describes a given
* denomination unit of the basic token.
*/
export interface DenomUnit {
/** denom represents the string name of the given denom unit (e.g uatom). */
/** denom represents the string name of the given denom unit (e.g. usei). */
denom: string;
/**
* exponent represents power of 10 exponent that one must
* raise the base_denom to in order to equal the given DenomUnit's denom
* 1 denom = 10^exponent base_denom
* (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with
* exponent = 6, thus: 1 atom = 10^6 uatom).
* (e.g. with a base_denom of usei, one can create a DenomUnit of 'sei' with
* exponent = 6, thus: 1 sei = 10^6 usei).
*/
exponent: number;
/** aliases is a list of string aliases for the given denom */
aliases: string[];
/** aliases is an optional list of string aliases for the given denom */
aliases?: string[];
}

/**
Expand All @@ -44,7 +57,7 @@ export interface Token {
/** An optional identifier for the token on the CoinGecko platform. */
coingecko_id?: string;
/** The type of the token, if applicable (e.g., "cw20" for CosmWasm tokens). */
type_token?: string;
type_asset?: string;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] The doc comment still describes the old type_token semantics. type_asset in the Cosmos asset-list schema carries a defined set of values (sdk.coin, cw20, erc20, ics20, …), and ics20 in particular is now the value this package filters on — worth saying so here, since it documents the exclusion rule for consumers.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] The doc comment above still reads (e.g., "cw20" for CosmWasm tokens), carried over from type_token. Under the Cosmos asset-list schema type_asset takes values like sdk.coin, ics20, erc20, and cw20 — worth listing a couple of those, especially since ics20 is now the value the new filter keys off.

}

/**
Expand All @@ -56,7 +69,7 @@ type SeiTokens = {
};

/**
* A constant that maps each Sei networks to its respective tokens, imported from the community ran [assetlist](https://github.com/Seitrace/sei-assetlist).
* A constant that maps each Sei network to its respective tokens, imported from the community-run [asset list](https://github.com/Seitrace/sei-assetlist).
*
* @remarks
* **Important**: This token list is community-driven and subject to change.
Expand All @@ -66,7 +79,11 @@ type SeiTokens = {
* ```tsx
* import { TOKEN_LIST } from '@sei-js/registry';
*
* const uSei = TOKEN_LIST['pacific-1'].find((asset) => asset.symbol === 'sei');
* const uSei = TOKEN_LIST['pacific-1'].find((asset) => asset.symbol === 'SEI');
* ```
*/
export const TOKEN_LIST: SeiTokens = pickSupportedNetworks(TokenListJSON) as unknown as SeiTokens;
const supportedTokenList = pickSupportedNetworks(TokenListJSON);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] The TOKEN_LIST JSDoc block (lines 71-84, with the @remarks community-data warning and the @example) is now attached to the internal supportedTokenList const rather than to the exported TOKEN_LIST on line 87. IDE hover and generated docs for the public export will show nothing, and the "verify and filter tokens yourself" warning — the one piece of documentation consumers most need — disappears from the published API surface.

Move the doc block down so it sits directly above export const TOKEN_LIST, and put a short internal comment on supportedTokenList if one is wanted.


export const TOKEN_LIST: SeiTokens = Object.fromEntries(
Object.entries(supportedTokenList).map(([network, assets]) => [network, assets.filter((asset) => !isIbcAsset(asset))])
) as unknown as SeiTokens;
15 changes: 10 additions & 5 deletions packages/registry/src/wallets/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { WALLETS, type Wallet } from '../index';
import { WALLETS } from '../../index';

describe('Wallet Extensions Configuration Tests', () => {
it('contains an array of wallet extensions', () => {
Expand All @@ -15,14 +15,19 @@ describe('Wallet Extensions Configuration Tests', () => {
}
});

it('contains specific wallet extension by identifier', () => {
const identifierToCheck = 'compass'; // Example identifier
it('contains only the current wallet identifiers', () => {
expect(WALLETS.map(({ identifier }) => identifier)).toEqual(['metamask', 'keplr', 'coin98']);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] Exact-array toEqual on upstream submodule data pins both the full set and the ordering of wallets.json. Any wallet added, removed, or reordered upstream fails this test on an otherwise-routine submodule bump, in a package whose whole job is to track upstream. Consider asserting the invariant instead:

const identifiers = WALLETS.map(({ identifier }) => identifier);
expect(identifiers).toEqual(expect.arrayContaining(['metamask', 'keplr', 'coin98']));

Same applies to the CHAIN_INFO.supported_wallets toEqual in chain-info/__tests__/index.spec.ts.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] This asserts exact array equality and ordering against data vendored from the chain-registry submodule. Same pattern at chain-info/__tests__/index.spec.ts:21 (supported_wallets toEqual ['keplr', 'coin98']) and, more loosely, networks/__tests__/index.spec.ts:32-41 (specific provider names and RPC/WS URLs).

The repo guidelines note the submodule JSON is vendored upstream and that review should target the TypeScript wrappers, not the data. These tests invert that: they turn the suite into an upstream-change detector, so a routine registry refresh that adds a wallet, reorders providers, or rotates an endpoint URL breaks CI on an unrelated PR — with a failure message that points at nothing the author changed.

Suggest asserting the wrapper's contract instead: that WALLETS is non-empty, that every entry has the required fields (already covered by the test above), and expect(identifiers).toContain('keplr') for the specific wallets you care about keeping.

});

it('contains the Keplr wallet metadata', () => {
const identifierToCheck = 'keplr';
const extension = WALLETS.find((ext) => ext.identifier === identifierToCheck);
expect(extension).toBeDefined();
if (extension) {
expect(extension.name).toBe('Compass Wallet');
expect(extension.url).toBe('https://compasswallet.io/');
expect(extension.name).toBe('Keplr Wallet');
expect(extension.url).toBe('https://www.keplr.app');
expect(extension.capabilities).toContain('native');
expect(extension.capabilities).toContain('evm');
}
});
});
2 changes: 1 addition & 1 deletion packages/registry/src/wallets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export interface Wallet {
* ```tsx
* import { WALLETS } from '@sei-js/registry';
*
* const compass = WALLETS.find((wallet) => wallet.identifier === 'compass');
* const keplr = WALLETS.find((wallet) => wallet.identifier === 'keplr');
* ```
*/
export const WALLETS: Wallet[] = WalletsJSON.extensions as Wallet[];
8 changes: 7 additions & 1 deletion packages/registry/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
{
"extends": "../../tsconfig.base.json",
"include": ["./src/**/*", "./chain-registry/**/*", "./community-assetlist/**/*"],
"include": [
"./src/**/*",
"./chain-registry/chain_info.json",
"./chain-registry/chains.json",
"./chain-registry/wallets.json",
"./community-assetlist/assetlist.json"
],
"exclude": ["src/**/__tests__", "src/**/*.spec.ts", "src/**/*.test.ts"],
"compilerOptions": {
"outDir": "./dist",
Expand Down
Loading
Loading