@pioneer-platform/pioneer-discovery 8.11.21 → 8.11.22
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/.turbo/turbo-build.log +2 -1
- package/CHANGELOG.md +13 -0
- package/docs/COINGECKO-MIGRATION-COMPLETE.md +182 -0
- package/docs/ICON-FIX-COMPLETE.md +194 -0
- package/docs/ICON-FIX-REPORT.md +151 -0
- package/docs/critical-icon-results.json +155 -0
- package/docs/icon-sources-analysis.json +14161 -0
- package/docs/keepkey-com-fixes.json +1122 -0
- package/lib/generatedAssetData.json +176 -176
- package/package.json +1 -1
- package/scripts/analyze-icon-sources.ts +130 -0
- package/scripts/apply-icon-migration.ts +95 -0
- package/scripts/check-critical-icons.ts +142 -0
- package/scripts/check-icons.ts +147 -0
- package/scripts/fix-icons.ts +61 -0
- package/scripts/fix-keepkey-com-urls.ts +68 -0
- package/scripts/icon-updates.json +138 -0
- package/scripts/migrate-coingecko-icons.ts +167 -0
- package/scripts/test-new-icons.ts +46 -0
- package/scripts/upload-icons.sh +103 -0
- package/scripts/verify-fixes.ts +83 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
{
|
|
2
|
+
"timestamp": "2025-11-06T21:27:44.783Z",
|
|
3
|
+
"totalUpdates": 13,
|
|
4
|
+
"updates": {
|
|
5
|
+
"bip122:000000000019d6689c085ae165831e93/slip44:0": "https://api.keepkey.info/coins/YmlwMTIyOjAwMDAwMDAwMDAxOWQ2Njg5YzA4NWFlMTY1ODMxZTkzL3NsaXA0NDow.png",
|
|
6
|
+
"eip155:1/slip44:60": "https://api.keepkey.info/coins/ZWlwMTU1OjEvc2xpcDQ0OjYw.png",
|
|
7
|
+
"cosmos:osmosis-1/slip44:118": "https://api.keepkey.info/coins/Y29zbW9zOm9zbW9zaXMtMS9zbGlwNDQ6MTE4.png",
|
|
8
|
+
"cosmos:thorchain-mainnet-v1/slip44:931": "https://api.keepkey.info/coins/Y29zbW9zOnRob3JjaGFpbi1tYWlubmV0LXYxL3NsaXA0NDo5MzE=.png",
|
|
9
|
+
"bip122:000000000000000000651ef99cb9fcbe/slip44:145": "https://api.keepkey.info/coins/YmlwMTIyOjAwMDAwMDAwMDAwMDAwMDAwMDY1MWVmOTljYjlmY2JlL3NsaXA0NDoxNDU=.png",
|
|
10
|
+
"bip122:00000000001a91e3dace36e2be3bf030/slip44:3": "https://api.keepkey.info/coins/YmlwMTIyOjAwMDAwMDAwMDAxYTkxZTNkYWNlMzZlMmJlM2JmMDMwL3NsaXA0NDoz.png",
|
|
11
|
+
"bip122:000007d91d1254d60e2dd1ae58038307/slip44:5": "https://api.keepkey.info/coins/YmlwMTIyOjAwMDAwN2Q5MWQxMjU0ZDYwZTJkZDFhZTU4MDM4MzA3L3NsaXA0NDo1.png",
|
|
12
|
+
"binance:bnb-beacon-chain/slip44:714": "https://api.keepkey.info/coins/YmluYW5jZTpibmItYmVhY29uLWNoYWluL3NsaXA0NDo3MTQ=.png",
|
|
13
|
+
"eip155:43114/slip44:60": "https://api.keepkey.info/coins/ZWlwMTU1OjQzMTE0L3NsaXA0NDo2MA==.png",
|
|
14
|
+
"eip155:137/slip44:60": "https://api.keepkey.info/coins/ZWlwMTU1OjEzNy9zbGlwNDQ6NjA=.png",
|
|
15
|
+
"eip155:42161/slip44:60": "https://api.keepkey.info/coins/ZWlwMTU1OjQyMTYxL3NsaXA0NDo2MA==.png",
|
|
16
|
+
"eip155:10/slip44:60": "https://api.keepkey.info/coins/ZWlwMTU1OjEwL3NsaXA0NDo2MA==.png",
|
|
17
|
+
"eip155:8453/slip44:60": "https://api.keepkey.info/coins/ZWlwMTU1Ojg0NTMvc2xpcDQ0OjYw.png"
|
|
18
|
+
},
|
|
19
|
+
"migrationTasks": [
|
|
20
|
+
{
|
|
21
|
+
"assetId": "bip122:000000000019d6689c085ae165831e93/slip44:0",
|
|
22
|
+
"symbol": "BTC",
|
|
23
|
+
"name": "Bitcoin",
|
|
24
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/1/small/bitcoin.png?1547033579",
|
|
25
|
+
"newUrl": "https://api.keepkey.info/coins/YmlwMTIyOjAwMDAwMDAwMDAxOWQ2Njg5YzA4NWFlMTY1ODMxZTkzL3NsaXA0NDow.png",
|
|
26
|
+
"base64Filename": "YmlwMTIyOjAwMDAwMDAwMDAxOWQ2Njg5YzA4NWFlMTY1ODMxZTkzL3NsaXA0NDow.png",
|
|
27
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/YmlwMTIyOjAwMDAwMDAwMDAxOWQ2Njg5YzA4NWFlMTY1ODMxZTkzL3NsaXA0NDow.png"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"assetId": "eip155:1/slip44:60",
|
|
31
|
+
"symbol": "ETH",
|
|
32
|
+
"name": "Ethereum",
|
|
33
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/279/large/ethereum.png?1595348880",
|
|
34
|
+
"newUrl": "https://api.keepkey.info/coins/ZWlwMTU1OjEvc2xpcDQ0OjYw.png",
|
|
35
|
+
"base64Filename": "ZWlwMTU1OjEvc2xpcDQ0OjYw.png",
|
|
36
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/ZWlwMTU1OjEvc2xpcDQ0OjYw.png"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"assetId": "cosmos:osmosis-1/slip44:118",
|
|
40
|
+
"symbol": "OSMO",
|
|
41
|
+
"name": "Osmosis",
|
|
42
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/16724/thumb/osmo.png",
|
|
43
|
+
"newUrl": "https://api.keepkey.info/coins/Y29zbW9zOm9zbW9zaXMtMS9zbGlwNDQ6MTE4.png",
|
|
44
|
+
"base64Filename": "Y29zbW9zOm9zbW9zaXMtMS9zbGlwNDQ6MTE4.png",
|
|
45
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/Y29zbW9zOm9zbW9zaXMtMS9zbGlwNDQ6MTE4.png"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"assetId": "cosmos:thorchain-mainnet-v1/slip44:931",
|
|
49
|
+
"symbol": "RUNE",
|
|
50
|
+
"name": "THORChain",
|
|
51
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/6595/thumb/RUNE.png",
|
|
52
|
+
"newUrl": "https://api.keepkey.info/coins/Y29zbW9zOnRob3JjaGFpbi1tYWlubmV0LXYxL3NsaXA0NDo5MzE=.png",
|
|
53
|
+
"base64Filename": "Y29zbW9zOnRob3JjaGFpbi1tYWlubmV0LXYxL3NsaXA0NDo5MzE=.png",
|
|
54
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/Y29zbW9zOnRob3JjaGFpbi1tYWlubmV0LXYxL3NsaXA0NDo5MzE=.png"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"assetId": "bip122:000000000000000000651ef99cb9fcbe/slip44:145",
|
|
58
|
+
"symbol": "BCH",
|
|
59
|
+
"name": "Bitcoin Cash",
|
|
60
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/780/thumb/bitcoin-cash-circle.png?1594689492",
|
|
61
|
+
"newUrl": "https://api.keepkey.info/coins/YmlwMTIyOjAwMDAwMDAwMDAwMDAwMDAwMDY1MWVmOTljYjlmY2JlL3NsaXA0NDoxNDU=.png",
|
|
62
|
+
"base64Filename": "YmlwMTIyOjAwMDAwMDAwMDAwMDAwMDAwMDY1MWVmOTljYjlmY2JlL3NsaXA0NDoxNDU=.png",
|
|
63
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/YmlwMTIyOjAwMDAwMDAwMDAwMDAwMDAwMDY1MWVmOTljYjlmY2JlL3NsaXA0NDoxNDU=.png"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"assetId": "bip122:00000000001a91e3dace36e2be3bf030/slip44:3",
|
|
67
|
+
"symbol": "DOGE",
|
|
68
|
+
"name": "Dogecoin",
|
|
69
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/5/small/dogecoin.png?1547792256",
|
|
70
|
+
"newUrl": "https://api.keepkey.info/coins/YmlwMTIyOjAwMDAwMDAwMDAxYTkxZTNkYWNlMzZlMmJlM2JmMDMwL3NsaXA0NDoz.png",
|
|
71
|
+
"base64Filename": "YmlwMTIyOjAwMDAwMDAwMDAxYTkxZTNkYWNlMzZlMmJlM2JmMDMwL3NsaXA0NDoz.png",
|
|
72
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/YmlwMTIyOjAwMDAwMDAwMDAxYTkxZTNkYWNlMzZlMmJlM2JmMDMwL3NsaXA0NDoz.png"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"assetId": "bip122:000007d91d1254d60e2dd1ae58038307/slip44:5",
|
|
76
|
+
"symbol": "DASH",
|
|
77
|
+
"name": "Dash",
|
|
78
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/19/small/dash-logo.png?1548385930",
|
|
79
|
+
"newUrl": "https://api.keepkey.info/coins/YmlwMTIyOjAwMDAwN2Q5MWQxMjU0ZDYwZTJkZDFhZTU4MDM4MzA3L3NsaXA0NDo1.png",
|
|
80
|
+
"base64Filename": "YmlwMTIyOjAwMDAwN2Q5MWQxMjU0ZDYwZTJkZDFhZTU4MDM4MzA3L3NsaXA0NDo1.png",
|
|
81
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/YmlwMTIyOjAwMDAwN2Q5MWQxMjU0ZDYwZTJkZDFhZTU4MDM4MzA3L3NsaXA0NDo1.png"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"assetId": "binance:bnb-beacon-chain/slip44:714",
|
|
85
|
+
"symbol": "BNB",
|
|
86
|
+
"name": "BNB",
|
|
87
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/825/thumb/binance-coin-logo.png?1547034615",
|
|
88
|
+
"newUrl": "https://api.keepkey.info/coins/YmluYW5jZTpibmItYmVhY29uLWNoYWluL3NsaXA0NDo3MTQ=.png",
|
|
89
|
+
"base64Filename": "YmluYW5jZTpibmItYmVhY29uLWNoYWluL3NsaXA0NDo3MTQ=.png",
|
|
90
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/YmluYW5jZTpibmItYmVhY29uLWNoYWluL3NsaXA0NDo3MTQ=.png"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"assetId": "eip155:43114/slip44:60",
|
|
94
|
+
"symbol": "AVAX",
|
|
95
|
+
"name": "Avalanche",
|
|
96
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/12559/small/coin-round-red.png?1604021818",
|
|
97
|
+
"newUrl": "https://api.keepkey.info/coins/ZWlwMTU1OjQzMTE0L3NsaXA0NDo2MA==.png",
|
|
98
|
+
"base64Filename": "ZWlwMTU1OjQzMTE0L3NsaXA0NDo2MA==.png",
|
|
99
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/ZWlwMTU1OjQzMTE0L3NsaXA0NDo2MA==.png"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"assetId": "eip155:137/slip44:60",
|
|
103
|
+
"symbol": "MATIC",
|
|
104
|
+
"name": "Polygon",
|
|
105
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/4713/small/matic-token-icon.png?1624446912",
|
|
106
|
+
"newUrl": "https://api.keepkey.info/coins/ZWlwMTU1OjEzNy9zbGlwNDQ6NjA=.png",
|
|
107
|
+
"base64Filename": "ZWlwMTU1OjEzNy9zbGlwNDQ6NjA=.png",
|
|
108
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/ZWlwMTU1OjEzNy9zbGlwNDQ6NjA=.png"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"assetId": "eip155:42161/slip44:60",
|
|
112
|
+
"symbol": "ARB",
|
|
113
|
+
"name": "Arbitrum",
|
|
114
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/16547/small/photo_2023-03-29_21.47.00.jpeg?1680097630",
|
|
115
|
+
"newUrl": "https://api.keepkey.info/coins/ZWlwMTU1OjQyMTYxL3NsaXA0NDo2MA==.png",
|
|
116
|
+
"base64Filename": "ZWlwMTU1OjQyMTYxL3NsaXA0NDo2MA==.png",
|
|
117
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/ZWlwMTU1OjQyMTYxL3NsaXA0NDo2MA==.png"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"assetId": "eip155:10/slip44:60",
|
|
121
|
+
"symbol": "OP",
|
|
122
|
+
"name": "Optimism",
|
|
123
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/25244/small/Optimism.png?1660904599",
|
|
124
|
+
"newUrl": "https://api.keepkey.info/coins/ZWlwMTU1OjEwL3NsaXA0NDo2MA==.png",
|
|
125
|
+
"base64Filename": "ZWlwMTU1OjEwL3NsaXA0NDo2MA==.png",
|
|
126
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/ZWlwMTU1OjEwL3NsaXA0NDo2MA==.png"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"assetId": "eip155:8453/slip44:60",
|
|
130
|
+
"symbol": "BASE",
|
|
131
|
+
"name": "Base",
|
|
132
|
+
"oldUrl": "https://assets.coingecko.com/coins/images/279/large/ethereum.png?1595348880",
|
|
133
|
+
"newUrl": "https://api.keepkey.info/coins/ZWlwMTU1Ojg0NTMvc2xpcDQ0OjYw.png",
|
|
134
|
+
"base64Filename": "ZWlwMTU1Ojg0NTMvc2xpcDQ0OjYw.png",
|
|
135
|
+
"localPath": "/Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/ZWlwMTU1Ojg0NTMvc2xpcDQ0OjYw.png"
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/*
|
|
3
|
+
* Migrate CoinGecko Icons to KeepKey Infrastructure
|
|
4
|
+
* Downloads CoinGecko icons and prepares them for DigitalOcean CDN upload
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import assetData from '../src/generatedAssetData.json';
|
|
8
|
+
import { writeFileSync } from 'fs';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
|
|
11
|
+
interface Asset {
|
|
12
|
+
symbol: string;
|
|
13
|
+
name: string;
|
|
14
|
+
chainId: string;
|
|
15
|
+
icon?: string;
|
|
16
|
+
assetId: string;
|
|
17
|
+
decimals: number;
|
|
18
|
+
isNative?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface MigrationTask {
|
|
22
|
+
assetId: string;
|
|
23
|
+
symbol: string;
|
|
24
|
+
name: string;
|
|
25
|
+
oldUrl: string;
|
|
26
|
+
newUrl: string;
|
|
27
|
+
base64Filename: string;
|
|
28
|
+
localPath: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function downloadIcon(url: string, outputPath: string): Promise<boolean> {
|
|
32
|
+
try {
|
|
33
|
+
const response = await fetch(url);
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
console.error(`Failed to download: ${response.status} ${response.statusText}`);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const buffer = await response.arrayBuffer();
|
|
40
|
+
const uint8Array = new Uint8Array(buffer);
|
|
41
|
+
await Bun.write(outputPath, uint8Array);
|
|
42
|
+
console.log(`✅ Downloaded: ${outputPath}`);
|
|
43
|
+
return true;
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.error(`❌ Error downloading: ${error}`);
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function main() {
|
|
51
|
+
console.log('=== CoinGecko Icon Migration Tool ===\n');
|
|
52
|
+
|
|
53
|
+
// Find all assets with CoinGecko icons
|
|
54
|
+
const entries = Object.entries(assetData as Record<string, Asset>);
|
|
55
|
+
const coingeckoAssets = entries.filter(([_, asset]) =>
|
|
56
|
+
asset.icon?.includes('coingecko')
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
console.log(`Found ${coingeckoAssets.length} assets using CoinGecko icons\n`);
|
|
60
|
+
|
|
61
|
+
// Prepare download directory
|
|
62
|
+
const downloadDir = join(import.meta.dir, 'temp-icons');
|
|
63
|
+
|
|
64
|
+
const migrationTasks: MigrationTask[] = [];
|
|
65
|
+
const downloadPromises: Promise<boolean>[] = [];
|
|
66
|
+
|
|
67
|
+
// Prepare migration tasks
|
|
68
|
+
for (const [assetId, asset] of coingeckoAssets) {
|
|
69
|
+
if (!asset.icon) continue;
|
|
70
|
+
|
|
71
|
+
// Encode assetId to base64
|
|
72
|
+
const base64Id = Buffer.from(assetId).toString('base64');
|
|
73
|
+
const filename = `${base64Id}.png`;
|
|
74
|
+
const localPath = join(downloadDir, filename);
|
|
75
|
+
const newUrl = `https://api.keepkey.info/coins/${filename}`;
|
|
76
|
+
|
|
77
|
+
const task: MigrationTask = {
|
|
78
|
+
assetId,
|
|
79
|
+
symbol: asset.symbol,
|
|
80
|
+
name: asset.name,
|
|
81
|
+
oldUrl: asset.icon,
|
|
82
|
+
newUrl,
|
|
83
|
+
base64Filename: filename,
|
|
84
|
+
localPath,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
migrationTasks.push(task);
|
|
88
|
+
|
|
89
|
+
console.log(`Preparing: ${asset.symbol} (${asset.name})`);
|
|
90
|
+
console.log(` Asset ID: ${assetId}`);
|
|
91
|
+
console.log(` Filename: ${filename}`);
|
|
92
|
+
console.log(` Old URL: ${asset.icon}`);
|
|
93
|
+
console.log(` New URL: ${newUrl}`);
|
|
94
|
+
console.log('');
|
|
95
|
+
|
|
96
|
+
// Queue download
|
|
97
|
+
downloadPromises.push(downloadIcon(asset.icon, localPath));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Execute downloads in parallel
|
|
101
|
+
console.log('\n=== Downloading Icons ===\n');
|
|
102
|
+
const results = await Promise.all(downloadPromises);
|
|
103
|
+
const successCount = results.filter(r => r).length;
|
|
104
|
+
console.log(`\n✅ Downloaded ${successCount}/${migrationTasks.length} icons\n`);
|
|
105
|
+
|
|
106
|
+
// Generate upload script
|
|
107
|
+
const uploadScript = migrationTasks.map(task => {
|
|
108
|
+
return `# ${task.symbol} (${task.name})
|
|
109
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \\
|
|
110
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \\
|
|
111
|
+
aws s3 cp ${task.localPath} s3://keepkey/coins/${task.base64Filename} \\
|
|
112
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \\
|
|
113
|
+
--acl public-read
|
|
114
|
+
`;
|
|
115
|
+
}).join('\n');
|
|
116
|
+
|
|
117
|
+
const uploadScriptPath = join(import.meta.dir, 'upload-icons.sh');
|
|
118
|
+
writeFileSync(uploadScriptPath, `#!/bin/bash
|
|
119
|
+
# Upload Icons to DigitalOcean CDN
|
|
120
|
+
# Generated: ${new Date().toISOString()}
|
|
121
|
+
|
|
122
|
+
set -e
|
|
123
|
+
|
|
124
|
+
echo "=== Uploading ${migrationTasks.length} icons to DigitalOcean CDN ==="
|
|
125
|
+
echo ""
|
|
126
|
+
|
|
127
|
+
${uploadScript}
|
|
128
|
+
|
|
129
|
+
echo ""
|
|
130
|
+
echo "✅ Upload complete!"
|
|
131
|
+
`);
|
|
132
|
+
|
|
133
|
+
console.log(`Upload script created: ${uploadScriptPath}`);
|
|
134
|
+
console.log('Make executable with: chmod +x scripts/upload-icons.sh\n');
|
|
135
|
+
|
|
136
|
+
// Generate data update
|
|
137
|
+
const updates: Record<string, any> = {};
|
|
138
|
+
for (const task of migrationTasks) {
|
|
139
|
+
updates[task.assetId] = task.newUrl;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const updateDataPath = join(import.meta.dir, 'icon-updates.json');
|
|
143
|
+
await Bun.write(updateDataPath, JSON.stringify({
|
|
144
|
+
timestamp: new Date().toISOString(),
|
|
145
|
+
totalUpdates: migrationTasks.length,
|
|
146
|
+
updates,
|
|
147
|
+
migrationTasks,
|
|
148
|
+
}, null, 2));
|
|
149
|
+
|
|
150
|
+
console.log(`Migration data saved: ${updateDataPath}\n`);
|
|
151
|
+
|
|
152
|
+
// Generate summary
|
|
153
|
+
console.log('=== Summary ===');
|
|
154
|
+
console.log(`Total assets to migrate: ${migrationTasks.length}`);
|
|
155
|
+
console.log(`Icons downloaded: ${successCount}`);
|
|
156
|
+
console.log(`Download directory: ${downloadDir}`);
|
|
157
|
+
console.log('');
|
|
158
|
+
console.log('=== Next Steps ===');
|
|
159
|
+
console.log('1. Verify icons downloaded correctly');
|
|
160
|
+
console.log('2. Make upload script executable: chmod +x scripts/upload-icons.sh');
|
|
161
|
+
console.log('3. Run upload script: ./scripts/upload-icons.sh');
|
|
162
|
+
console.log('4. Run apply script to update asset data: bun run scripts/apply-icon-migration.ts');
|
|
163
|
+
console.log('5. Verify icons: bun run scripts/check-critical-icons.ts');
|
|
164
|
+
console.log('6. Rebuild package: bun run build');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
// Test the new icon URLs
|
|
4
|
+
const assets = [
|
|
5
|
+
{
|
|
6
|
+
name: 'Cosmos (ATOM)',
|
|
7
|
+
assetId: 'cosmos:cosmoshub-4/slip44:118',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
name: 'Mayachain (CACAO)',
|
|
11
|
+
assetId: 'cosmos:mayachain-mainnet-v1/slip44:931',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: 'Litecoin (LTC)',
|
|
15
|
+
assetId: 'bip122:12a765e31ffd4059bada1e25190f6e98/slip44:2',
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
async function testUrl(url: string) {
|
|
20
|
+
try {
|
|
21
|
+
const response = await fetch(url, { method: 'HEAD' });
|
|
22
|
+
return { ok: response.ok, status: response.status };
|
|
23
|
+
} catch (error) {
|
|
24
|
+
return { ok: false, status: 'error', error };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function main() {
|
|
29
|
+
console.log('Testing new icon URLs from DigitalOcean Spaces...\n');
|
|
30
|
+
|
|
31
|
+
for (const asset of assets) {
|
|
32
|
+
const encoded = Buffer.from(asset.assetId).toString('base64');
|
|
33
|
+
const url = `https://keepkey.sfo3.cdn.digitaloceanspaces.com/coins/${encoded}.png`;
|
|
34
|
+
|
|
35
|
+
console.log(`${asset.name}`);
|
|
36
|
+
console.log(` Asset ID: ${asset.assetId}`);
|
|
37
|
+
console.log(` Encoded: ${encoded}`);
|
|
38
|
+
console.log(` URL: ${url}`);
|
|
39
|
+
|
|
40
|
+
const result = await testUrl(url);
|
|
41
|
+
console.log(` Status: ${result.ok ? '✅ OK' : '❌ FAILED'} (${result.status})`);
|
|
42
|
+
console.log('');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
main();
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Upload Icons to DigitalOcean CDN
|
|
3
|
+
# Generated: 2025-11-06T21:27:44.782Z
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
echo "=== Uploading 13 icons to DigitalOcean CDN ==="
|
|
8
|
+
echo ""
|
|
9
|
+
|
|
10
|
+
# BTC (Bitcoin)
|
|
11
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
12
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
13
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/YmlwMTIyOjAwMDAwMDAwMDAxOWQ2Njg5YzA4NWFlMTY1ODMxZTkzL3NsaXA0NDow.png s3://keepkey/coins/YmlwMTIyOjAwMDAwMDAwMDAxOWQ2Njg5YzA4NWFlMTY1ODMxZTkzL3NsaXA0NDow.png \
|
|
14
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
15
|
+
--acl public-read
|
|
16
|
+
|
|
17
|
+
# ETH (Ethereum)
|
|
18
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
19
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
20
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/ZWlwMTU1OjEvc2xpcDQ0OjYw.png s3://keepkey/coins/ZWlwMTU1OjEvc2xpcDQ0OjYw.png \
|
|
21
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
22
|
+
--acl public-read
|
|
23
|
+
|
|
24
|
+
# OSMO (Osmosis)
|
|
25
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
26
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
27
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/Y29zbW9zOm9zbW9zaXMtMS9zbGlwNDQ6MTE4.png s3://keepkey/coins/Y29zbW9zOm9zbW9zaXMtMS9zbGlwNDQ6MTE4.png \
|
|
28
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
29
|
+
--acl public-read
|
|
30
|
+
|
|
31
|
+
# RUNE (THORChain)
|
|
32
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
33
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
34
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/Y29zbW9zOnRob3JjaGFpbi1tYWlubmV0LXYxL3NsaXA0NDo5MzE=.png s3://keepkey/coins/Y29zbW9zOnRob3JjaGFpbi1tYWlubmV0LXYxL3NsaXA0NDo5MzE=.png \
|
|
35
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
36
|
+
--acl public-read
|
|
37
|
+
|
|
38
|
+
# BCH (Bitcoin Cash)
|
|
39
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
40
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
41
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/YmlwMTIyOjAwMDAwMDAwMDAwMDAwMDAwMDY1MWVmOTljYjlmY2JlL3NsaXA0NDoxNDU=.png s3://keepkey/coins/YmlwMTIyOjAwMDAwMDAwMDAwMDAwMDAwMDY1MWVmOTljYjlmY2JlL3NsaXA0NDoxNDU=.png \
|
|
42
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
43
|
+
--acl public-read
|
|
44
|
+
|
|
45
|
+
# DOGE (Dogecoin)
|
|
46
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
47
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
48
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/YmlwMTIyOjAwMDAwMDAwMDAxYTkxZTNkYWNlMzZlMmJlM2JmMDMwL3NsaXA0NDoz.png s3://keepkey/coins/YmlwMTIyOjAwMDAwMDAwMDAxYTkxZTNkYWNlMzZlMmJlM2JmMDMwL3NsaXA0NDoz.png \
|
|
49
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
50
|
+
--acl public-read
|
|
51
|
+
|
|
52
|
+
# DASH (Dash)
|
|
53
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
54
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
55
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/YmlwMTIyOjAwMDAwN2Q5MWQxMjU0ZDYwZTJkZDFhZTU4MDM4MzA3L3NsaXA0NDo1.png s3://keepkey/coins/YmlwMTIyOjAwMDAwN2Q5MWQxMjU0ZDYwZTJkZDFhZTU4MDM4MzA3L3NsaXA0NDo1.png \
|
|
56
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
57
|
+
--acl public-read
|
|
58
|
+
|
|
59
|
+
# BNB (BNB)
|
|
60
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
61
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
62
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/YmluYW5jZTpibmItYmVhY29uLWNoYWluL3NsaXA0NDo3MTQ=.png s3://keepkey/coins/YmluYW5jZTpibmItYmVhY29uLWNoYWluL3NsaXA0NDo3MTQ=.png \
|
|
63
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
64
|
+
--acl public-read
|
|
65
|
+
|
|
66
|
+
# AVAX (Avalanche)
|
|
67
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
68
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
69
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/ZWlwMTU1OjQzMTE0L3NsaXA0NDo2MA==.png s3://keepkey/coins/ZWlwMTU1OjQzMTE0L3NsaXA0NDo2MA==.png \
|
|
70
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
71
|
+
--acl public-read
|
|
72
|
+
|
|
73
|
+
# MATIC (Polygon)
|
|
74
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
75
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
76
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/ZWlwMTU1OjEzNy9zbGlwNDQ6NjA=.png s3://keepkey/coins/ZWlwMTU1OjEzNy9zbGlwNDQ6NjA=.png \
|
|
77
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
78
|
+
--acl public-read
|
|
79
|
+
|
|
80
|
+
# ARB (Arbitrum)
|
|
81
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
82
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
83
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/ZWlwMTU1OjQyMTYxL3NsaXA0NDo2MA==.png s3://keepkey/coins/ZWlwMTU1OjQyMTYxL3NsaXA0NDo2MA==.png \
|
|
84
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
85
|
+
--acl public-read
|
|
86
|
+
|
|
87
|
+
# OP (Optimism)
|
|
88
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
89
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
90
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/ZWlwMTU1OjEwL3NsaXA0NDo2MA==.png s3://keepkey/coins/ZWlwMTU1OjEwL3NsaXA0NDo2MA==.png \
|
|
91
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
92
|
+
--acl public-read
|
|
93
|
+
|
|
94
|
+
# BASE (Base)
|
|
95
|
+
AWS_ACCESS_KEY_ID=DO00FXP8KK64LCXYAEZP \
|
|
96
|
+
AWS_SECRET_ACCESS_KEY=Uyw/cq63rrQmFV9yy1HbovTSMNhLkEwImqPa88N/E/s \
|
|
97
|
+
aws s3 cp /Users/highlander/WebstormProjects/keepkey-stack/projects/pioneer/modules/pioneer/pioneer-discovery/scripts/temp-icons/ZWlwMTU1Ojg0NTMvc2xpcDQ0OjYw.png s3://keepkey/coins/ZWlwMTU1Ojg0NTMvc2xpcDQ0OjYw.png \
|
|
98
|
+
--endpoint-url=https://sfo3.digitaloceanspaces.com \
|
|
99
|
+
--acl public-read
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
echo ""
|
|
103
|
+
echo "✅ Upload complete!"
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/*
|
|
3
|
+
* Verify Icon Fixes
|
|
4
|
+
* Test that the fixed URLs now work
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import assetData from '../src/generatedAssetData.json';
|
|
8
|
+
|
|
9
|
+
interface Asset {
|
|
10
|
+
symbol: string;
|
|
11
|
+
name: string;
|
|
12
|
+
icon?: string;
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function checkIcon(url: string): Promise<boolean> {
|
|
17
|
+
try {
|
|
18
|
+
const response = await fetch(url, { method: 'HEAD' });
|
|
19
|
+
return response.ok;
|
|
20
|
+
} catch (error) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function main() {
|
|
26
|
+
console.log('Verifying icon fixes...\n');
|
|
27
|
+
|
|
28
|
+
const keepkeyComAssets: Array<[string, Asset]> = [];
|
|
29
|
+
const keepkeyInfoAssets: Array<[string, Asset]> = [];
|
|
30
|
+
|
|
31
|
+
for (const [assetId, asset] of Object.entries(assetData) as Array<[string, Asset]>) {
|
|
32
|
+
if (asset.icon?.includes('api.keepkey.com')) {
|
|
33
|
+
keepkeyComAssets.push([assetId, asset]);
|
|
34
|
+
} else if (asset.icon?.includes('api.keepkey.info')) {
|
|
35
|
+
keepkeyInfoAssets.push([assetId, asset]);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
console.log('=== Verification Summary ===');
|
|
40
|
+
console.log(`api.keepkey.com URLs remaining: ${keepkeyComAssets.length}`);
|
|
41
|
+
console.log(`api.keepkey.info URLs: ${keepkeyInfoAssets.length}`);
|
|
42
|
+
console.log('');
|
|
43
|
+
|
|
44
|
+
if (keepkeyComAssets.length > 0) {
|
|
45
|
+
console.log('⚠️ WARNING: Still found api.keepkey.com URLs:');
|
|
46
|
+
for (const [assetId, asset] of keepkeyComAssets.slice(0, 5)) {
|
|
47
|
+
console.log(` - ${asset.symbol}: ${asset.icon}`);
|
|
48
|
+
}
|
|
49
|
+
console.log('');
|
|
50
|
+
} else {
|
|
51
|
+
console.log('✅ No api.keepkey.com URLs remaining!\n');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Test a sample of the .info URLs
|
|
55
|
+
console.log('=== Testing Sample of Fixed URLs ===');
|
|
56
|
+
const sample = keepkeyInfoAssets.slice(0, 10);
|
|
57
|
+
|
|
58
|
+
let working = 0;
|
|
59
|
+
let broken = 0;
|
|
60
|
+
|
|
61
|
+
for (const [assetId, asset] of sample) {
|
|
62
|
+
const works = await checkIcon(asset.icon!);
|
|
63
|
+
if (works) {
|
|
64
|
+
working++;
|
|
65
|
+
console.log(`✅ ${asset.symbol.padEnd(10)} ${asset.name}`);
|
|
66
|
+
} else {
|
|
67
|
+
broken++;
|
|
68
|
+
console.log(`❌ ${asset.symbol.padEnd(10)} ${asset.name}`);
|
|
69
|
+
console.log(` URL: ${asset.icon}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
console.log('');
|
|
74
|
+
console.log('=== Test Results ===');
|
|
75
|
+
console.log(`Working: ${working}/${sample.length}`);
|
|
76
|
+
console.log(`Broken: ${broken}/${sample.length}`);
|
|
77
|
+
|
|
78
|
+
if (broken === 0) {
|
|
79
|
+
console.log('\n🎉 All tested URLs are working!');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
main().catch(console.error);
|