@bifrostwallet/assets 0.0.0-stage → 0.0.1-beta

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 CHANGED
@@ -1,3 +1,84 @@
1
- # Temporary Holding Version
1
+ # @bifrostwallet/assets
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Curated assets for Bifrost Wallet: providers, validators, tokens, dapps, and more as the catalog grows.
4
+
5
+ Zero runtime dependencies: JSON data plus pure lookup helpers. Logos are **not** bundled; published `logoURL` values are absolute (GitHub raw by default). For production or sensitive apps, mirror logos to your own bucket or CDN.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @bifrostwallet/assets
11
+ ```
12
+
13
+ Or install with Yarn or pnpm using the same package name.
14
+
15
+ ## Quick start
16
+
17
+ ```js
18
+ const {
19
+ getProvider,
20
+ getListedProviders,
21
+ findProviderByValidator,
22
+ getNativeToken,
23
+ getToken,
24
+ } = require("@bifrostwallet/assets");
25
+
26
+ // Chain ids are CAIP-2 (e.g. "eip155:14", "eip155:19")
27
+ const bifrost = getProvider("eip155:14", "0x1650d2760baee638c034200dedcbe17b050d0364");
28
+ const logoURL = bifrost.logoURL; // already absolute
29
+ const byNode = findProviderByValidator(
30
+ "eip155:14",
31
+ "NodeID-5oLazJm5PtV8JFb2GpzuCVMZdi1GxkwYP",
32
+ ); // → Bifrost Wallet
33
+ const picker = getListedProviders("eip155:14"); // listed: true only
34
+
35
+ const flr = getNativeToken("eip155:14"); // native gas token (address === null)
36
+ // WNAT / WFLR on Flare (lookup is case-insensitive)
37
+ const wflr = getToken("eip155:14", "0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d");
38
+ ```
39
+
40
+ TypeScript / ESM:
41
+
42
+ ```ts
43
+ import {
44
+ getProvider,
45
+ getListedProviders,
46
+ findProviderByValidator,
47
+ getNativeToken,
48
+ } from "@bifrostwallet/assets";
49
+
50
+ const bifrost = getProvider("eip155:14", "0x1650d2760baee638c034200dedcbe17b050d0364");
51
+ const listed = getListedProviders("eip155:14");
52
+ const native = getNativeToken("eip155:14");
53
+ ```
54
+
55
+ ## Provider picker vs confirmations
56
+
57
+ | UI | Rule |
58
+ | --- | --- |
59
+ | Provider **picker** / discovery | Show only `listed: true` (`getListedProviders`) |
60
+ | Already-selected provider (confirmations, details) | Show the entry even if `listed` is false (`getProvider` / `getProviders`) |
61
+
62
+ ## Without NPM
63
+
64
+ **Not recommended.** Prefer the NPM package. GitHub raw is a fallback only:
65
+
66
+ ```
67
+ https://raw.githubusercontent.com/bifrostwallet/assets/main/data/providers/eip155-14/all.json
68
+ https://raw.githubusercontent.com/bifrostwallet/assets/main/data/tokens/eip155-14/all.json
69
+ ```
70
+
71
+ Relative `logoURL` values resolve against:
72
+
73
+ ```
74
+ https://raw.githubusercontent.com/bifrostwallet/assets/main/data/
75
+ ```
76
+
77
+ For production or sensitive applications, mirror logos to your own bucket or CDN instead of relying on GitHub’s CDN.
78
+
79
+ ## Docs
80
+
81
+ Full integrator guide (data model, media format, optional CDN manifest):
82
+ [docs.bifrostwallet.com: Consuming Assets](https://docs.bifrostwallet.com/list/consuming-assets)
83
+
84
+ Source of truth: [github.com/bifrostwallet/assets](https://github.com/bifrostwallet/assets)
package/index.d.ts ADDED
@@ -0,0 +1,142 @@
1
+ // @bifrostwallet/assets — generated file, do not edit.
2
+
3
+ export interface ProviderInfo {
4
+ name: string;
5
+ description: string;
6
+ websiteURL: string;
7
+ links: {
8
+ github?: string;
9
+ x?: string;
10
+ discord?: string;
11
+ telegram?: string;
12
+ youtube?: string;
13
+ reddit?: string;
14
+ linkedin?: string;
15
+ tiktok?: string;
16
+ };
17
+ /**
18
+ * Absolute logo URL in published lists (GitHub raw by default).
19
+ * info.json in git keeps a relative path; resolveAssetURL() still works for either form.
20
+ */
21
+ logoURL: string;
22
+ /** SHA-256 of the logo file, covered by provider signatures */
23
+ logoHash: string;
24
+ identityAddress: string;
25
+ delegationAddress: string;
26
+ signingPolicyAddress: string;
27
+ submitAddress: string;
28
+ submitSignaturesAddress: string;
29
+ publicKey: string;
30
+ /** Avalanche-style NodeIDs of the provider's validators */
31
+ validators: string[];
32
+ /** Curator-granted listing flag for Bifrost Wallet UIs */
33
+ listed: boolean;
34
+ /** Flare FTSO Management Group membership (synced on-chain) */
35
+ managementGroup: boolean;
36
+ /** Optional domain linkage, refreshed nightly from websiteURL */
37
+ domainLinked: boolean;
38
+ /** Same brand present on both Flare and Songbird in this catalog (curator-reviewed) */
39
+ dualNetwork: boolean;
40
+ /** Earliest known provider activity on this network (write-once, curator-managed) */
41
+ firstTransaction?: {
42
+ hash: string;
43
+ blockNumber: number;
44
+ /** ISO 8601 UTC */
45
+ timestamp: string;
46
+ };
47
+ }
48
+
49
+ export interface TokenInfo {
50
+ name: string;
51
+ symbol: string;
52
+ decimals: number;
53
+ /** Lowercase 0x… for contracts; null for the chain native gas token */
54
+ address: string | null;
55
+ /** Always present — string CoinGecko id, or null when unmapped / unpriced */
56
+ coingeckoId: string | null;
57
+ logoURL: string;
58
+ logoHash: string;
59
+ }
60
+
61
+ export interface TokenBlocklistEntry {
62
+ chainPath: string;
63
+ address: string;
64
+ identifier: string;
65
+ }
66
+
67
+ export interface ManifestSectionHashes {
68
+ contentHash: string;
69
+ chains?: Record<string, string>;
70
+ }
71
+
72
+ /** CAIP-2 chain id, e.g. "eip155:14" or "eip155:19" */
73
+ export type ChainId = string;
74
+
75
+ export declare const DEFAULT_ASSET_BASE_URL: string;
76
+ export declare const PROVIDER_CHAIN_IDS: string[];
77
+ export declare const TOKEN_CHAIN_IDS: string[];
78
+ /** Ed25519 SPKI PEM for verifying CDN manifest.json (empty string if key not generated yet) */
79
+ export declare const MANIFEST_PUBLIC_KEY: string;
80
+
81
+ /** Section content hashes baked into this package release (compare to CDN manifest) */
82
+ export declare function getSectionHashes(): {
83
+ providers?: ManifestSectionHashes;
84
+ contracts?: ManifestSectionHashes;
85
+ dapps?: ManifestSectionHashes;
86
+ tokens?: ManifestSectionHashes;
87
+ };
88
+
89
+ export interface AssetsManifestBody {
90
+ generatedAt: string;
91
+ sections: {
92
+ providers?: ManifestSectionHashes;
93
+ contracts?: ManifestSectionHashes;
94
+ dapps?: ManifestSectionHashes;
95
+ tokens?: ManifestSectionHashes;
96
+ };
97
+ }
98
+
99
+ export interface AssetsManifest extends AssetsManifestBody {
100
+ signature: string;
101
+ }
102
+
103
+ /** Canonical JSON string signed by the Bifrost Ed25519 publish key */
104
+ export declare function canonicalManifestBody(body: AssetsManifestBody): string;
105
+ /**
106
+ * Verify CDN manifest with node:crypto Ed25519.
107
+ * Defaults to MANIFEST_PUBLIC_KEY when publicKeyPem is omitted.
108
+ */
109
+ export declare function verifyManifest(
110
+ manifest: AssetsManifest,
111
+ publicKeyPem?: string
112
+ ): boolean;
113
+
114
+ /** All curated providers for a chain (throws on unknown chain) */
115
+ export declare function getProviders(chainId: ChainId): ProviderInfo[];
116
+ /** A single provider by identity address (case-insensitive), or null */
117
+ export declare function getProvider(
118
+ chainId: ChainId,
119
+ identityAddress: string
120
+ ): ProviderInfo | null;
121
+ /** Providers listed in Bifrost Wallet UIs */
122
+ export declare function getListedProviders(chainId: ChainId): ProviderInfo[];
123
+ /** Providers that are current FTSO Management Group members */
124
+ export declare function getManagementGroupProviders(chainId: ChainId): ProviderInfo[];
125
+ /** The provider operating a validator NodeID, or null */
126
+ export declare function findProviderByValidator(
127
+ chainId: ChainId,
128
+ nodeId: string
129
+ ): ProviderInfo | null;
130
+ /** All curated tokens for a chain (throws on unknown chain) */
131
+ export declare function getTokens(chainId: ChainId): TokenInfo[];
132
+ /** A single ERC-20 by address (case-insensitive), or null */
133
+ export declare function getToken(chainId: ChainId, address: string): TokenInfo | null;
134
+ /** Native gas token entry for a chain, or null */
135
+ export declare function getNativeToken(chainId: ChainId): TokenInfo | null;
136
+ /** Curated token blocklist entries */
137
+ export declare function getTokenBlocklist(): TokenBlocklistEntry[];
138
+ /**
139
+ * Joins a relative (or already-absolute) asset path to a base URL.
140
+ * Defaults to the base baked into this package build (ASSET_BASE_URL / GitHub raw).
141
+ */
142
+ export declare function resolveAssetURL(relativePath: string, baseURL?: string): string;
package/index.js ADDED
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ // @bifrostwallet/assets — generated file, do not edit.
3
+
4
+ const providersByChain = {
5
+ "eip155-14": require("./providers/eip155-14.json"),
6
+ "eip155-19": require("./providers/eip155-19.json"),
7
+ };
8
+
9
+ const tokensByChain = {
10
+ "eip155-1": require("./tokens/eip155-1.json"),
11
+ "eip155-10": require("./tokens/eip155-10.json"),
12
+ "eip155-11155111": require("./tokens/eip155-11155111.json"),
13
+ "eip155-114": require("./tokens/eip155-114.json"),
14
+ "eip155-137": require("./tokens/eip155-137.json"),
15
+ "eip155-14": require("./tokens/eip155-14.json"),
16
+ "eip155-16": require("./tokens/eip155-16.json"),
17
+ "eip155-19": require("./tokens/eip155-19.json"),
18
+ "eip155-250": require("./tokens/eip155-250.json"),
19
+ "eip155-4002": require("./tokens/eip155-4002.json"),
20
+ "eip155-420": require("./tokens/eip155-420.json"),
21
+ "eip155-42161": require("./tokens/eip155-42161.json"),
22
+ "eip155-42163": require("./tokens/eip155-42163.json"),
23
+ "eip155-5": require("./tokens/eip155-5.json"),
24
+ "eip155-50": require("./tokens/eip155-50.json"),
25
+ "eip155-51": require("./tokens/eip155-51.json"),
26
+ "eip155-56": require("./tokens/eip155-56.json"),
27
+ "eip155-80001": require("./tokens/eip155-80001.json"),
28
+ "eip155-8453": require("./tokens/eip155-8453.json"),
29
+ "eip155-84532": require("./tokens/eip155-84532.json"),
30
+ "eip155-97": require("./tokens/eip155-97.json"),
31
+ "eip155-998": require("./tokens/eip155-998.json"),
32
+ "eip155-999": require("./tokens/eip155-999.json"),
33
+ };
34
+
35
+ const tokenBlocklist = require("./tokens/blocklist.json");
36
+
37
+ /** Bundled snapshot of section content hashes (same algorithm as CDN manifest.json). */
38
+ const SECTION_HASHES = {
39
+ "providers": {
40
+ "contentHash": "34b17e0206215f8e821e2ee0badb4e5dad9b5aff61e01412703129bdaa4d309d",
41
+ "chains": {
42
+ "eip155-14": "92226cb84bebf225fcbcf4af5c16e18c7935e9e0b549992bcea99dc564384ce2",
43
+ "eip155-19": "8bed4749411b716feedc0861ff2ca6f9d002f257eff05540e49142d4c2b24605"
44
+ }
45
+ },
46
+ "tokens": {
47
+ "contentHash": "1e6da50ba69c9895e1cb1774908f9c56de41956c39b1a2c1d244cd710dd2212b",
48
+ "chains": {
49
+ "eip155-1": "63ff7bf33ea031f7765cf73f981f345e77e5d761824b097fea7971dee7867708",
50
+ "eip155-10": "9d6d559be18b4b2a2516ca66d975f17dc804a50d5c9a8d6bdc466266ec4c5a33",
51
+ "eip155-11155111": "a8682c3da1a11942e413ddb5c7736c34a0a3b77aa5df6a6e9b47e56a567999fc",
52
+ "eip155-114": "5b2e1503b845d5d1a2299f64f72b4786b834b694da36c1c15af5f71371029f43",
53
+ "eip155-137": "e5e5047ddf758dad58cd4f2cd6599c855f731fa5de8c8f6ac56f2fc54644f0eb",
54
+ "eip155-14": "5a8212c8263bbb1a787d4463bf097c29b56fa0e14b685053be9805cd90725d4a",
55
+ "eip155-16": "ee5224b4853d61665fa89cbb9df5feb1d75f15843eaac4dd56254019d9df50a6",
56
+ "eip155-19": "a42bfa17e774af50d15ffcd08f60531fcdc0fbea9882d98f8f721f177f7daa7b",
57
+ "eip155-250": "20abc5f8d9de7210a5318edb7fef7a6812450c69f40ce22becc5c193bed640e1",
58
+ "eip155-4002": "217c1f2f92a1674e802adb1e31e3bee52380da76fe14bafc82397cf08fd5e8c3",
59
+ "eip155-420": "cec0b2a52bc6daa2188e2c25cadd8226f40013421f820cf455e77e3617d6cf59",
60
+ "eip155-42161": "29f5eebb42a85b729b974fc5483ccf28967853618422287e6916d993101b9882",
61
+ "eip155-42163": "c91b6e5ca0c75388ae9326ef26054bb73dd866f6c28379d172a217648a55de1a",
62
+ "eip155-5": "39fa17702137bb2ed634d21028ae7a68599cd5521932e33b08c55f00c272053f",
63
+ "eip155-50": "5415b5d5224d73d0bd80f153a8d121e3315de7964140566d0f9a44aac59e749c",
64
+ "eip155-51": "e6112ca4d68eacc8a7b0f504fe5e8d725f711af320d98f07bdd4d9cb8dc2e06d",
65
+ "eip155-56": "06da2605033adb91b4cf32959b700934395fc34c11401576fc2a0ba9820b4b09",
66
+ "eip155-80001": "408050807491893b08eb9f473f2e5867104c1dadff4671323aaa44509bd04f08",
67
+ "eip155-8453": "390522231623da0edbe330681102656c1bd1bfdf9a58d678c77e7e4c1c22c262",
68
+ "eip155-84532": "455323b32bfe577783c16fe6868a35238c7c8c72d2d554ce2cacd0818ca7a2a8",
69
+ "eip155-97": "564bf279fef4fd9b2001b73dff78922dedc57fee0f243db8f437f9915d717347",
70
+ "eip155-998": "b7c0f4a4ec4fdf4cf98718f7b2f32e1f1955733d9873d20adf231324659ece68",
71
+ "eip155-999": "ce2252709b4f9d7b7ae42c6c1a58bb1262d18b1254bb5f50ed822df61717a90d",
72
+ "blocklist": "295c8643e1bd21d0cb8667765cba410e0b0d8ba2445710fadc729d1d321a7dc1"
73
+ }
74
+ }
75
+ };
76
+
77
+ /**
78
+ * Ed25519 SPKI public key (PEM) used to verify CDN manifest.json signatures.
79
+ * Verify with node:crypto (Node) or Web Crypto Ed25519 (browsers).
80
+ */
81
+ const MANIFEST_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAemcuPT4chJxVl3iBJIarkuLlRxSV7pYlxp8W72hXBUE=\n-----END PUBLIC KEY-----";
82
+
83
+ const DEFAULT_ASSET_BASE_URL = "https://raw.githubusercontent.com/bifrostwallet/assets/main/data/";
84
+
85
+ const PROVIDER_CHAIN_IDS = Object.keys(providersByChain).map(chainPathToCaip2);
86
+ const TOKEN_CHAIN_IDS = Object.keys(tokensByChain).map(chainPathToCaip2);
87
+
88
+ function chainPathToCaip2(chainPath) {
89
+ const i = String(chainPath).indexOf("-");
90
+ return i === -1 ? String(chainPath) : String(chainPath).slice(0, i) + ":" + String(chainPath).slice(i + 1);
91
+ }
92
+
93
+ function normalizeChainId(chainId) {
94
+ // Public API accepts CAIP-2 only (e.g. "eip155:14"). Repo paths use eip155-14.
95
+ if (typeof chainId !== "string" || !chainId.includes(":")) {
96
+ throw new Error(
97
+ 'Use a CAIP-2 chain id (e.g. "eip155:14"). Got: ' + JSON.stringify(chainId)
98
+ );
99
+ }
100
+ return chainId.replace(":", "-");
101
+ }
102
+
103
+ function getProviders(chainId) {
104
+ const providers = providersByChain[normalizeChainId(chainId)];
105
+ if (!providers) {
106
+ throw new Error(
107
+ "Unknown chain " + chainId + ". Available: " + PROVIDER_CHAIN_IDS.join(", ")
108
+ );
109
+ }
110
+ return providers;
111
+ }
112
+
113
+ function getProvider(chainId, identityAddress) {
114
+ const target = String(identityAddress).toLowerCase();
115
+ return (
116
+ getProviders(chainId).find(
117
+ (provider) => provider.identityAddress.toLowerCase() === target
118
+ ) ?? null
119
+ );
120
+ }
121
+
122
+ function getListedProviders(chainId) {
123
+ return getProviders(chainId).filter((provider) => provider.listed);
124
+ }
125
+
126
+ function getManagementGroupProviders(chainId) {
127
+ return getProviders(chainId).filter((provider) => provider.managementGroup);
128
+ }
129
+
130
+ function findProviderByValidator(chainId, nodeId) {
131
+ return (
132
+ getProviders(chainId).find((provider) => provider.validators.includes(nodeId)) ??
133
+ null
134
+ );
135
+ }
136
+
137
+ function getTokens(chainId) {
138
+ const tokens = tokensByChain[normalizeChainId(chainId)];
139
+ if (!tokens) {
140
+ throw new Error(
141
+ "Unknown token chain " + chainId + ". Available: " + TOKEN_CHAIN_IDS.join(", ")
142
+ );
143
+ }
144
+ return tokens;
145
+ }
146
+
147
+ function getToken(chainId, address) {
148
+ const target = String(address).toLowerCase();
149
+ return (
150
+ getTokens(chainId).find(
151
+ (token) => token.address && token.address.toLowerCase() === target
152
+ ) ?? null
153
+ );
154
+ }
155
+
156
+ function getNativeToken(chainId) {
157
+ return getTokens(chainId).find((token) => token.address === null) ?? null;
158
+ }
159
+
160
+ function getTokenBlocklist() {
161
+ return tokenBlocklist.tokens || [];
162
+ }
163
+
164
+ function resolveAssetURL(relativePath, baseURL) {
165
+ const base = baseURL || DEFAULT_ASSET_BASE_URL;
166
+ return base.replace(/\/?$/, "/") + String(relativePath).replace(/^\//, "");
167
+ }
168
+
169
+ function getSectionHashes() {
170
+ return SECTION_HASHES;
171
+ }
172
+
173
+ const SECTION_ORDER = ["providers", "contracts", "dapps", "tokens"];
174
+
175
+ /** Canonical UTF-8 JSON bytes (as string) that the Ed25519 signature covers. */
176
+ function canonicalManifestBody(body) {
177
+ const sections = {};
178
+ for (const name of SECTION_ORDER) {
179
+ const section = body.sections[name];
180
+ if (!section) continue;
181
+ const entry = { contentHash: section.contentHash };
182
+ if (section.chains) {
183
+ const chains = {};
184
+ for (const chain of Object.keys(section.chains).sort()) {
185
+ chains[chain] = section.chains[chain];
186
+ }
187
+ entry.chains = chains;
188
+ }
189
+ sections[name] = entry;
190
+ }
191
+ return JSON.stringify({ generatedAt: body.generatedAt, sections });
192
+ }
193
+
194
+ /**
195
+ * Verify CDN manifest.json with node:crypto Ed25519 (Node / bundlers that polyfill it).
196
+ * Browsers: Web Crypto Ed25519 over Buffer.from(canonicalManifestBody(body), "utf8").
197
+ */
198
+ function verifyManifest(manifest, publicKeyPem) {
199
+ const { createPublicKey, verify } = require("node:crypto");
200
+ const { signature, ...body } = manifest;
201
+ const message = Buffer.from(canonicalManifestBody(body), "utf8");
202
+ return verify(
203
+ null,
204
+ message,
205
+ createPublicKey(publicKeyPem || MANIFEST_PUBLIC_KEY),
206
+ Buffer.from(signature, "base64url")
207
+ );
208
+ }
209
+
210
+ module.exports = {
211
+ DEFAULT_ASSET_BASE_URL,
212
+ PROVIDER_CHAIN_IDS,
213
+ TOKEN_CHAIN_IDS,
214
+ MANIFEST_PUBLIC_KEY,
215
+ getSectionHashes,
216
+ canonicalManifestBody,
217
+ verifyManifest,
218
+ getProviders,
219
+ getProvider,
220
+ getListedProviders,
221
+ getManagementGroupProviders,
222
+ findProviderByValidator,
223
+ getTokens,
224
+ getToken,
225
+ getNativeToken,
226
+ getTokenBlocklist,
227
+ resolveAssetURL,
228
+ };
package/package.json CHANGED
@@ -1,6 +1,11 @@
1
1
  {
2
2
  "name": "@bifrostwallet/assets",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.0.1-beta",
4
+ "description": "Curated assets for Bifrost Wallet.",
5
+ "repository": "https://github.com/bifrostwallet/assets.git",
6
+ "author": "Bifrost Software Ltd",
7
+ "license": "MIT",
8
+ "main": "index.js",
9
+ "types": "index.d.ts",
10
+ "sideEffects": false
6
11
  }