Skip to content

Commit e5e9cc1

Browse files
authored
Merge branch 'main' into feat/p-ops
2 parents d33cbab + d865a9c commit e5e9cc1

16 files changed

+206
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"validate:json": "tsx scripts/validateJSON.ts",
1010
"validate:data": "tsx scripts/validateOnChainData/main.ts",
1111
"validate": "pnpm run validate:json && pnpm run validate:images && pnpm run validate:data",
12+
"metadata:missing": "tsx scripts/manageVaultsFromApi.ts add",
1213
"lint": "biome lint .",
1314
"check": "biome check ."
1415
},

scripts/addVaultLogo.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/**
2+
* One-off script: download a vault logo, process to 1024x1024 non-transparent,
3+
* save to src/assets/vaults, and upload to Cloudflare Images.
4+
*
5+
* Usage: tsx scripts/addVaultLogo.ts <logo_url> <vault_address>
6+
* Example: tsx scripts/addVaultLogo.ts "https://i.ibb.co/956Qvz0/snr-USD-Logo-1.png" 0x18e310dd4a6179d9600e95d18926ab7819b2a071
7+
*/
8+
9+
import fs from "node:fs";
10+
import path from "node:path";
11+
import { config } from "dotenv";
12+
import sharp from "sharp";
13+
14+
config();
15+
16+
const LOGO_URL = process.argv[2];
17+
const VAULT_ADDRESS = process.argv[3]?.toLowerCase();
18+
19+
if (!LOGO_URL || !VAULT_ADDRESS || !VAULT_ADDRESS.match(/^0x[0-9a-f]{40}$/)) {
20+
console.error(
21+
"Usage: tsx scripts/addVaultLogo.ts <logo_url> <vault_address>",
22+
);
23+
process.exit(1);
24+
}
25+
26+
const ASSETS_VAULTS = path.join(process.cwd(), "src", "assets", "vaults");
27+
const OUTPUT_PATH = path.join(ASSETS_VAULTS, `${VAULT_ADDRESS}.png`);
28+
29+
const CLOUDFLARE_ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID;
30+
const CLOUDFLARE_IMAGES_API_TOKEN = process.env.CLOUDFLARE_IMAGES_API_TOKEN;
31+
32+
async function main() {
33+
console.log("Downloading logo from", LOGO_URL);
34+
const response = await fetch(LOGO_URL);
35+
if (!response.ok) {
36+
throw new Error(
37+
`Download failed: ${response.status} ${response.statusText}`,
38+
);
39+
}
40+
const buffer = Buffer.from(await response.arrayBuffer());
41+
42+
console.log("Processing: resize 1024x1024, flatten (non-transparent)");
43+
const processed = await sharp(buffer)
44+
.resize(1024, 1024, {
45+
fit: "contain",
46+
background: { r: 255, g: 255, b: 255, alpha: 1 },
47+
})
48+
.flatten({ background: { r: 255, g: 255, b: 255 } })
49+
.png()
50+
.toBuffer();
51+
52+
if (!fs.existsSync(ASSETS_VAULTS)) {
53+
fs.mkdirSync(ASSETS_VAULTS, { recursive: true });
54+
}
55+
fs.writeFileSync(OUTPUT_PATH, processed);
56+
console.log("Saved to", OUTPUT_PATH);
57+
58+
if (!CLOUDFLARE_ACCOUNT_ID || !CLOUDFLARE_IMAGES_API_TOKEN) {
59+
console.warn(
60+
"Missing CLOUDFLARE_ACCOUNT_ID or CLOUDFLARE_IMAGES_API_TOKEN. Skipping upload.",
61+
);
62+
console.log(
63+
"Logo URI (after you upload manually): https://imagedelivery.net/qNj7Q3MCke89zoKzav7eDQ/vaults/" +
64+
VAULT_ADDRESS +
65+
".png/public",
66+
);
67+
return;
68+
}
69+
70+
const formData = new FormData();
71+
formData.append("file", new Blob([processed]), `${VAULT_ADDRESS}.png`);
72+
formData.append("id", `vaults/${VAULT_ADDRESS}.png`);
73+
74+
const uploadUrl = `https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/images/v1`;
75+
const uploadResponse = await fetch(uploadUrl, {
76+
method: "POST",
77+
headers: {
78+
Authorization: `Bearer ${CLOUDFLARE_IMAGES_API_TOKEN}`,
79+
},
80+
body: formData,
81+
});
82+
83+
const result = (await uploadResponse.json()) as {
84+
success?: boolean;
85+
errors?: { code?: number; message?: string }[];
86+
result?: { id?: string; filename?: string; variants?: string[] };
87+
};
88+
const alreadyExists = result.errors?.some((e) => e.code === 5409);
89+
if (alreadyExists) {
90+
console.log(
91+
"Image already exists on Cloudflare Images (id: vaults/" +
92+
VAULT_ADDRESS +
93+
").",
94+
);
95+
} else {
96+
console.log("Cloudflare API response:", JSON.stringify(result, null, 2));
97+
if (!uploadResponse.ok || !result.success) {
98+
throw new Error(`Cloudflare upload failed: ${JSON.stringify(result)}`);
99+
}
100+
console.log("Uploaded to Cloudflare Images.");
101+
}
102+
const logoUri =
103+
"https://imagedelivery.net/qNj7Q3MCke89zoKzav7eDQ/vaults/" +
104+
VAULT_ADDRESS +
105+
".png/public";
106+
console.log("Logo URI:", logoUri);
107+
}
108+
109+
main().catch((err) => {
110+
console.error(err);
111+
process.exit(1);
112+
});
45 KB
Loading
83.2 KB
Loading
112 KB
Loading
154 KB
Loading
181 KB
Loading
253 KB
Loading
230 KB
Loading
48 KB
Loading

0 commit comments

Comments
 (0)