{"id":51915710,"url":"https://github.com/tetherto/wdk-asset-registry","last_synced_at":"2026-07-27T10:01:26.184Z","repository":{"id":371704126,"uuid":"1212409688","full_name":"tetherto/wdk-asset-registry","owner":"tetherto","description":null,"archived":false,"fork":false,"pushed_at":"2026-07-16T12:05:12.000Z","size":243,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-16T12:21:33.981Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tetherto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-16T10:54:34.000Z","updated_at":"2026-07-16T11:59:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tetherto/wdk-asset-registry","commit_stats":null,"previous_names":["tetherto/wdk-asset-registry"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/tetherto/wdk-asset-registry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fwdk-asset-registry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fwdk-asset-registry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fwdk-asset-registry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fwdk-asset-registry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tetherto","download_url":"https://codeload.github.com/tetherto/wdk-asset-registry/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tetherto%2Fwdk-asset-registry/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35947061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-27T02:00:06.776Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-27T10:01:25.425Z","updated_at":"2026-07-27T10:01:26.177Z","avatar_url":"https://github.com/tetherto.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @tetherto/wdk-asset-registry\n\n**Note**: This package is currently in beta. Please test thoroughly in development environments before using in production.\n\nA lightweight registry for accessing predefined blockchain assets across multiple chains. This package provides a generic base asset registry plus a token-specific registry for retrieving metadata such as symbol, decimals, asset identifiers, contract addresses, and native-asset status.\n\n## 🔍 About WDK\n\nThis module is part of the [**WDK (Wallet Development Kit)**](https://wallet.tether.io/) project, which empowers developers to build secure, non-custodial wallets with unified blockchain access, stateless architecture, and complete user control.\n\nFor detailed documentation about the complete WDK ecosystem, visit [docs.wallet.tether.io](https://docs.wallet.tether.io).\n\n## 🌟 Features\n\n- **Generic Asset Registry**: Build registries for reusable asset collections\n- **Token Asset Registry**: Use token-specific lookups such as id, symbol, address, and chain\n- **Bundled Asset Lists**: Import registry-ready assets from `@tetherto/wdk-asset-registry/assets/*`\n- **Standardized Schemas**: Validate base assets and token assets with Zod\n- **Flexible Lookup**: Query base assets with partial match filters\n- **Porting Helpers**: Normalize third-party token-list entries into `TokenAsset`\n- **Lightweight**: No RPC or blockchain interaction required\n- **In-Memory Registry**: Supports both lookup and local registration of assets\n\n## ⬇️ Installation\n\nTo install the `@tetherto/wdk-asset-registry` package, follow these instructions:\n\nYou can install it using npm:\n\n```bash\nnpm install @tetherto/wdk-asset-registry\n```\n\n## 🚀 Quick Start\n\n### Importing from `@tetherto/wdk-asset-registry`\n\n```javascript\nimport { WdkTokenAssetRegistry } from '@tetherto/wdk-asset-registry'\nimport commonTokens from '@tetherto/wdk-asset-registry/assets/common-tokens'\n\nconst registry = new WdkTokenAssetRegistry(commonTokens)\n```\n\nYou can also preload multiple asset sets:\n\n```javascript\nconst registry = new WdkTokenAssetRegistry(commonTokens, customTokens)\n```\n\n### Get Assets by Symbol\n\n```javascript\nconst usdt = registry.getTokenBySymbol('usdt')\nconsole.log(usdt)\n```\n\n### Get Assets by Address\n\n```javascript\nconst usdt = registry.getTokenByAddress(\n  '0xdAC17F958D2ee523a2206206994597C13D831ec7'\n)\nconsole.log(usdt)\n```\n\n### Get Assets by ID\n\n```javascript\nconst usdt = registry.getTokenById('eip155:1/0xdAC17F958D2ee523a2206206994597C13D831ec7')\nconsole.log(usdt)\n```\n\n### Filter by Chain ID\n\n```javascript\nconst ethereumUsdt = registry.getTokenByChain('eip155:1')\nconsole.log(ethereumUsdt)\n```\n\n### Query Base Assets with Partial Filters\n\n```javascript\nimport WdkBaseAssetRegistry, { BaseAssetSchema } from '@tetherto/wdk-asset-registry'\n\nclass CustomAssetRegistry extends WdkBaseAssetRegistry {\n  _assertAsset (asset) {\n    return BaseAssetSchema.parse(asset)\n  }\n}\n\nconst registry = new CustomAssetRegistry(commonTokens)\n\nconst ethereumUsdt = registry.getAsset([\n  {\n    id: 'eip155:1/0xdAC17F958D2ee523a2206206994597C13D831ec7',\n    chainId: 'eip155:1'\n  }\n])\n```\n\n### Query Base Assets with Multiple Filters\n\n```javascript\nconst selectedAssets = registry.getAsset([\n  {\n    id: 'eip155:1/0xdAC17F958D2ee523a2206206994597C13D831ec7',\n    chainId: 'eip155:1'\n  },\n  {\n    id: 'eip155:1/0x68749665ff8d2d112fa859aa293f07a622782f38',\n    chainId: 'eip155:1'\n  }\n])\n\n// Returns assets matching either condition above\nconsole.log(selectedAssets)\n```\n\n### Register a Custom Token\n\n```javascript\nregistry.registerAsset({\n  id: 'eip155:1/0x1111111111111111111111111111111111111111',\n  address: '0x1111111111111111111111111111111111111111',\n  symbol: 'TEST',\n  name: 'Test Token',\n  decimals: 18,\n  chainId: 'eip155:1',\n  isNative: false\n})\n```\n\n### Normalize Third-Party Token Lists\n\n```javascript\nimport { fromUniswapTokenList } from '@tetherto/wdk-asset-registry'\n\nconst normalizedTokens = fromUniswapTokenList(\n  source.tokens\n)\n```\n\nThe helper accepts the `tokens` array directly and converts each entry into a validated `TokenAsset`. It assumes Uniswap-style numeric EVM chain ids and maps them to `eip155:*`.\n\n## 📚 API Reference\n\n### Table of Contents\n\n| Section | Description | Methods |\n| --- | --- | --- |\n| [Types](#types) | Asset type definitions | [BaseAsset](#baseasset), [TokenAsset](#tokenasset), [BaseAssetFilter](#baseassetfilter), [BaseAssetOptions](#baseassetoptions), [TokenAddressLookupOptions](#tokenaddresslookupoptions) |\n| [Errors](#errors) | Error classes exported by the registry | [AssetRegistryError](#assetregistryerror) |\n| [WdkBaseAssetRegistry](#wdkbaseassetregistry) | Generic registry for assets with ids and chain IDs | [Constructor](#constructor), [Methods](#methods) |\n| [WdkTokenAssetRegistry](#wdktokenassetregistry) | Token-specific registry with id, symbol, address, and chain lookups | [Methods](#methods-1) |\n| [Token Asset Utils](#token-asset-utils) | Helpers for working with token assets | [Uniswap Utilities](#uniswap-utilities) |\n\n### Types\n\n#### BaseAsset\n\n```typescript\ntype BaseAsset = {\n  id: string;\n  chainId: string | number;\n};\n```\n\n#### TokenAsset\n\n```typescript\ntype TokenAsset = BaseAsset \u0026 {\n  address: string;\n  symbol: string;\n  name: string;\n  decimals: number;\n  isNative: boolean;\n};\n```\n\n#### BaseAssetOptions\n\n```typescript\ntype BaseAssetOptions = {\n  caseSensitive?: boolean;\n};\n```\n\n`caseSensitive` defaults to `false`: string filter values (such as symbols and chain ids) are lowercased before matching, so `usdt`, `USDT`, and `Usdt` all match. Set it to `true` to require an exact match.\n\n#### TokenAddressLookupOptions\n\n```typescript\ntype TokenAddressLookupOptions = {\n  caseSensitive?: boolean;\n};\n```\n\nOptions for `getTokenByAddress`. Same shape as `BaseAssetOptions`, but `caseSensitive` defaults to `true` so addresses match exactly.\n\n#### BaseAssetFilter\n\n```typescript\ntype BaseAssetFilter\u003cTSchema extends Object\u003e = Partial\u003cTSchema\u003e;\n```\n\nEach array item is a partial match condition. Properties inside a single object are matched together, and multiple objects are evaluated as a union of conditions.\n\n### Errors\n\n#### AssetRegistryError\n\n```javascript\nnew AssetRegistryError(message)\n```\n\n**Parameters:**\n\n- `message` (`string`): Error message describing the registry failure\n\n### WdkBaseAssetRegistry\n\nGeneric registry class for storing and looking up assets in memory.\n\nThe default base registry validates the `BaseAssetSchema` shape (`id` and `chainId`) while preserving additional fields on registered assets. Override `_assertAsset` when a registry needs stricter validation or a richer schema.\n\n#### Constructor\n\n```javascript\nnew WdkBaseAssetRegistry(...assets)\n```\n\n**Parameters:**\n\n- `...assets` (`T[][]`): One or more asset lists to preload into the registry\n\n**Example using a concrete token registry:**\n\n```javascript\nimport { WdkTokenAssetRegistry } from '@tetherto/wdk-asset-registry'\nimport commonTokens from '@tetherto/wdk-asset-registry/assets/common-tokens'\n\nconst registry = new WdkTokenAssetRegistry(commonTokens)\n```\n\n**Extend the base registry in TypeScript:**\n\n```typescript\nimport { z } from 'zod'\nimport WdkBaseAssetRegistry, { BaseAssetSchema } from '@tetherto/wdk-asset-registry'\n\ntype CustomAsset = {\n  id: string\n  chainId: string\n  label: string\n}\n\nconst CustomAssetSchema = BaseAssetSchema.extend({\n  label: z.string()\n})\n\nclass CustomAssetRegistry extends WdkBaseAssetRegistry\u003cCustomAsset\u003e {\n  _assertAsset (asset: CustomAsset): CustomAsset {\n    return CustomAssetSchema.parse(asset)\n  }\n}\n```\n\n#### Methods\n\n| Method | Description | Returns |\n| --- | --- | --- |\n| `registerAsset(asset, [upsert])` | Register a single asset | `void` |\n| `registerAssets(assets, [upsert])` | Register multiple assets | `void` |\n| `getAssets()` | Get all registered assets | `T[]` |\n| `getAssetById(id)` | Get one asset by identifier | `T \\| null` |\n| `getAsset(filter, [opts])` | Get assets using one or more partial match conditions | `T[]` |\n\n#### registerAsset\n\nRegister a single asset in the registry.\n\n**Parameters:**\n\n- `asset` (`T`): Asset definition to insert or replace\n- `upsert` (boolean, optional): When `true`, replaces an existing asset with the same id\n\n**Returns:** `void`\n\n#### registerAssets\n\nRegister multiple assets in the registry.\n\n**Parameters:**\n\n- `assets` (`T[]`): Asset definitions to insert or replace\n- `upsert` (boolean, optional): When `true`, replaces existing assets with the same id\n\n**Returns:** `void`\n\n#### getAssets\n\nGet all registered assets.\n\n**Returns:** `T[]`\n\n#### getAssetById\n\nGet a single asset by identifier.\n\n**Parameters:**\n\n- `id` (string): Asset identifier to look up\n\n**Returns:** `T | null`\n\n**Example:**\n\n```javascript\nconst asset = registry.getAssetById('eip155:1/0xdAC17F958D2ee523a2206206994597C13D831ec7')\nconsole.log(asset)\n```\n\n#### getAsset\n\nGet asset metadata using one or more partial match conditions.\n\n**Parameters:**\n\n- `filter` (`BaseAssetFilter\u003cT\u003e[]`): One or more partial asset match conditions. Within a condition, provided key-value pairs are matched with AND.\n- `opts` (`BaseAssetOptions`, optional): Lookup options such as `caseSensitive`\n\n**Returns:** `T[]`\n\n**Example:**\n\n```javascript\nconst assets = registry.getAsset([\n  {\n    id: 'eip155:1/0xdAC17F958D2ee523a2206206994597C13D831ec7',\n    chainId: 'eip155:1'\n  }\n])\nconsole.log(assets)\n```\n\n### WdkTokenAssetRegistry\n\nToken-specific registry built on top of `WdkBaseAssetRegistry\u003cTokenAsset\u003e`.\n\n#### Methods\n\n| Method | Description | Returns |\n| --- | --- | --- |\n| `getTokens()` | Get all registered tokens | `TokenAsset[]` |\n| `getTokenById(id)` | Get one token by id | `TokenAsset \\| null` |\n| `getTokenByAddress(address, [opts])` | Get tokens by address | `TokenAsset[]` |\n| `getTokenBySymbol(symbol, [opts])` | Get tokens by symbol | `TokenAsset[]` |\n| `getTokenByChain(chainId, [opts])` | Get tokens by chain id | `TokenAsset[]` |\n\n#### getTokens\n\nGet all registered tokens.\n\n**Returns:** `TokenAsset[]`\n\n#### getTokenBySymbol\n\nGet token metadata by symbol.\n\n**Parameters:**\n\n- `symbol` (string): Token symbol to look up, such as `usdt` or `usdt0`\n- `opts` (`BaseAssetOptions`, optional): Lookup options such as `caseSensitive`\n\n**Returns:** `TokenAsset[]`\n\n**Example:**\n\n```javascript\nconst assets = registry.getTokenBySymbol('usdt')\nconsole.log(assets)\n```\n\n#### getTokenById\n\nGet a single token by asset identifier.\n\n**Parameters:**\n\n- `id` (string): Token asset identifier to look up\n\n**Returns:** `TokenAsset | null`\n\n**Example:**\n\n```javascript\nconst asset = registry.getTokenById('eip155:1/0xdAC17F958D2ee523a2206206994597C13D831ec7')\nconsole.log(asset)\n```\n\n#### getTokenByChain\n\nGet token metadata by chain identifier.\n\n**Parameters:**\n\n- `chainId` (string | number): Chain identifier to look up\n- `opts` (`BaseAssetOptions`, optional): Lookup options such as `caseSensitive`\n\n**Returns:** `TokenAsset[]`\n\n**Example:**\n\n```javascript\nconst ethereumUsdt = registry.getTokenByChain('eip155:1')\nconsole.log(ethereumUsdt)\n```\n\n#### getTokenByAddress\n\nGet token metadata by contract address.\n\nUnlike the other lookups, address matching is **case-sensitive by default** (`caseSensitive: true`), since addresses on most chains are case-sensitive (e.g. Solana, Tron, TON). EVM addresses are the exception: casing never changes the address, so EVM callers can pass { caseSensitive: false }.\n\n**Parameters:**\n\n- `address` (string): Token address to look up\n- `opts` (`TokenAddressLookupOptions`, optional): Lookup options such as `caseSensitive` (defaults to `true`)\n\n**Returns:** `TokenAsset[]`\n\n**Example:**\n\n```javascript\n// Case-sensitive (default): must match the exact (checksummed) address\nconst assets = registry.getTokenByAddress(\n  '0xdAC17F958D2ee523a2206206994597C13D831ec7'\n)\nconsole.log(assets)\n\n// Case-insensitive: match regardless of casing\nconst anyCase = registry.getTokenByAddress(\n  '0xdac17f958d2ee523a2206206994597c13d831ec7',\n  { caseSensitive: false }\n)\nconsole.log(anyCase)\n```\n\n### Token Asset Utils\n\nHelpers for working with token assets.\n\n#### Uniswap Utilities\n\nHelpers for normalizing Uniswap Token Lists entries into `TokenAsset`.\n\n##### Methods\n\n| Method | Description | Returns |\n| --- | --- | --- |\n| `fromUniswapToken(token)` | Normalize one token-list entry into a `TokenAsset` | `TokenAsset` |\n| `fromUniswapTokenList(tokens)` | Normalize a token array into `TokenAsset[]` | `TokenAsset[]` |\n\n##### fromUniswapToken\n\nConvert one Uniswap-style token entry into a normalized `TokenAsset`.\n\n**Parameters:**\n\n- `token` (`UniswapTokenInfo`): Source token entry\n\n**Returns:** `TokenAsset`\n\n##### fromUniswapTokenList\n\nConvert a Uniswap Token Lists `tokens` array into normalized `TokenAsset[]`.\n\n**Parameters:**\n\n- `tokens` (`UniswapTokenInfo[]`): Source token entries\n\n**Returns:** `TokenAsset[]`\n\n**Example:**\n\n```javascript\nconst normalizedTokens = fromUniswapTokenList(\n  source.tokens\n)\n```\n\n### JSON Schemas\n\n| Schemas | Description |\n| --- | --- |\n| `BaseAssetJsonSchema` | JSON Schema representation of a single `BaseAsset` object |\n| `TokenAssetJsonSchema` | JSON Schema representation of a single `TokenAsset` object |\n\n## 🔒 Design Considerations\n\n- **No RPC Dependency**: Pure metadata access\n- **Deterministic Lookups**: Simple and predictable results\n- **Extensible Registry**: Supports runtime registration and replacement of assets\n- **Composable**: Designed to work alongside wallet/protocol modules (i.e. `wdk-wallet-*` and `wdk-protocol-*`)\n\n## 🛠️ Development\n\n### Building\n\n```bash\n# Install dependencies\nnpm install\n\n# Build TypeScript definitions\nnpm run build:types\n\n# Lint code\nnpm run lint\n\n# Fix linting issues\nnpm run lint:fix\n```\n\n### Testing\n\n```bash\n# Run tests\nnpm test\n\n# Run tests with coverage\nnpm run test:coverage\n```\n\n## 📜 License\n\nThis project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## 🆘 Support\n\nFor support, please open an issue on the GitHub repository.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftetherto%2Fwdk-asset-registry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftetherto%2Fwdk-asset-registry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftetherto%2Fwdk-asset-registry/lists"}