Skip to content

Commit 7fd80e2

Browse files
authored
feat(metadata): add NFD avatar and banner image resolution (#16)
* feat(metadata): add NFD metadata module for avatar and banner images Add comprehensive metadata functionality to resolve NFD avatar and banner images with automatic IPFS to HTTPS conversion. The new `MetadataModule` provides both direct resolution from NFD names/IDs and optimized parsing from existing NFD data objects. Key features include: - Avatar images with automatic fallback to default NFD avatar - Banner image resolution (returns null if none set) - IPFS URL conversion with smart fallback logic (images.nf.domains -> IPFS gateway) - Verification status detection for NFT-based images - ASA ID extraction for verified images - Method overloads for performance optimization - Comprehensive error handling and type safety Add IPFS utility functions for URL validation and availability checking with support for JSON metadata parsing. Include complete test coverage for both metadata module and IPFS utilities. Update documentation with usage examples and integrate new methods into `NfdClient` public interface. Export new types and utility functions for external use. * feat(examples): add NFD metadata example demonstrating avatar/banner resolution Add comprehensive example project showcasing the new metadata module functionality. The example provides an interactive React application for testing avatar and banner image resolution with real-time display of metadata results. Features demonstrated include: - Avatar image resolution with automatic fallback to default NFD avatar - Banner image resolution (null when not configured) - IPFS to HTTPS conversion with smart URL truncation for display - Verification status and ASA ID display for NFT-based images - Performance optimization with parallel image resolution - Interactive examples with pre-populated test NFD names Update examples documentation to include the new metadata example in the available examples list. Configure standard React + TypeScript + Vite setup with proper ESLint configuration and Node.js polyfills for blockchain operations. * chore: add onlyBuiltDependencies for esbuild * chore(examples): remove unused vite.config.d.ts file * chore(tests): move tests for PurchasingModule to modules folder
1 parent 935a723 commit 7fd80e2

26 files changed

Lines changed: 1710 additions & 5 deletions

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,29 @@ const nfdData = await nfd.resolve('alice.algo', { view: 'brief' })
6969
const nfdDataById = await nfd.resolve('123456789')
7070
```
7171

72+
### Getting NFD Images (Avatar & Banner)
73+
74+
```typescript
75+
import { NfdClient } from '@txnlab/nfd-sdk'
76+
77+
const nfd = NfdClient.testNet()
78+
79+
// Get avatar image with automatic fallback
80+
const avatarResult = await nfd.getAvatarImage('alice.algo')
81+
console.log(avatarResult.url) // Always returns a URL (fallback if needed)
82+
console.log(avatarResult.verified) // true if from verified NFT properties
83+
console.log(avatarResult.asaId) // ASA ID if verified image
84+
85+
// Get banner image (may be null)
86+
const bannerResult = await nfd.getBannerImage('alice.algo')
87+
console.log(bannerResult.url) // May be null if no banner set
88+
89+
// Fast path: If you already have NFD data
90+
const nfdData = await nfd.resolve('alice.algo', { view: 'full' })
91+
const avatar = await nfd.getAvatarImage(nfdData) // No additional resolve needed
92+
const banner = await nfd.getBannerImage(nfdData) // No additional resolve needed
93+
```
94+
7295
### Searching for NFDs
7396

7497
```typescript
@@ -192,6 +215,7 @@ const customNfd = new NfdClient({
192215
Check out the [examples directory](./examples) for complete working examples of various SDK features:
193216

194217
- [Resolve](./examples/resolve/): Demonstrates how to resolve NFD names and application IDs
218+
- [NFD Metadata](./examples/nfd-metadata/): Demonstrates how to resolve avatar and banner images with IPFS support
195219
- [API Search](./examples/api-search/): Demonstrates how to use the API client to search for NFDs
196220
- [Reverse Lookup](./examples/reverse-lookup/): Demonstrates how to look up NFDs by wallet address
197221
- [Mint](./examples/mint/): Demonstrates how to mint NFDs

examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ This directory contains example applications demonstrating various features of t
55
## Available Examples
66

77
- [Resolve](./resolve/): Demonstrates how to resolve NFD names and application IDs
8+
- [NFD Metadata](./nfd-metadata/): Demonstrates how to resolve avatar and banner images with IPFS support
89
- [API Search](./api-search/): Demonstrates how to use the API client to search for NFDs
910
- [Reverse Lookup](./reverse-lookup/): Demonstrates how to look up NFDs by wallet address
1011
- [Mint](./mint/): Demonstrates how to mint NFDs

examples/nfd-metadata/.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

examples/nfd-metadata/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# NFD Metadata Example
2+
3+
This example demonstrates how to use the NFD SDK's metadata functionality to resolve avatar and banner images for NFDs.
4+
5+
## Features Demonstrated
6+
7+
- **Avatar Image Resolution**: Get avatar images with automatic fallback to default NFD avatar
8+
- **Banner Image Resolution**: Get banner images (returns null if not set)
9+
- **IPFS to HTTPS Conversion**: Automatic conversion of IPFS URLs to accessible HTTPS URLs
10+
- **Verified vs User-Defined**: Shows verification status and ASA ID for NFT-based images
11+
- **Optimization Paths**: Demonstrates both slow path (resolve then parse) and fast path (direct parsing)
12+
13+
## What You'll See
14+
15+
- Input field to enter any NFD name or app ID
16+
- Real-time avatar and banner image display
17+
- Metadata details including:
18+
- Raw on-chain values
19+
- Resolved HTTPS URLs
20+
- Verification status
21+
- ASA ID for verified NFT images
22+
- Whether avatar is using fallback default image
23+
24+
## Running the Example
25+
26+
```bash
27+
# Install dependencies
28+
pnpm install
29+
30+
# Start the development server
31+
pnpm dev
32+
```
33+
34+
Visit `http://localhost:5173` in your browser to try the example.
35+
36+
## Try These NFDs
37+
38+
Some NFDs with interesting metadata to test:
39+
40+
- `nfdomains.algo` - User-defined avatar and banner
41+
- `doug.algo` - Verified avatar and banner
42+
- Any NFD name to see the avatar fallback in action
43+
44+
## About the NFD SDK
45+
46+
The NFD SDK provides various methods for interacting with Non-Fungible Domains on the Algorand blockchain. This example is part of a series of examples showcasing different features of the NFD SDK. Check out the other examples in this repository to learn more about the full capabilities of the SDK.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import reactHooks from 'eslint-plugin-react-hooks'
2+
import reactRefresh from 'eslint-plugin-react-refresh'
3+
import globals from 'globals'
4+
import tseslint from 'typescript-eslint'
5+
import baseConfig from '../../eslint.config.js'
6+
7+
export default tseslint.config(
8+
...baseConfig,
9+
{
10+
files: ['src/**/*.{ts,tsx}'],
11+
languageOptions: {
12+
ecmaVersion: 2020,
13+
globals: globals.browser,
14+
parserOptions: {
15+
project: './tsconfig.json',
16+
},
17+
},
18+
plugins: {
19+
'@typescript-eslint': tseslint.plugin,
20+
'react-hooks': reactHooks,
21+
'react-refresh': reactRefresh,
22+
},
23+
rules: {
24+
...reactHooks.configs.recommended.rules,
25+
'react-refresh/only-export-components': [
26+
'warn',
27+
{ allowConstantExport: true },
28+
],
29+
},
30+
},
31+
{
32+
files: ['*.config.{js,ts}'],
33+
languageOptions: {
34+
parserOptions: {
35+
project: './tsconfig.node.json',
36+
},
37+
},
38+
plugins: {
39+
'@typescript-eslint': tseslint.plugin,
40+
},
41+
},
42+
)

examples/nfd-metadata/index.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>NFD Metadata Example</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/index.tsx"></script>
12+
</body>
13+
</html>

examples/nfd-metadata/package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "@txnlab/nfd-sdk-metadata-example",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"dev": "vite",
7+
"build": "tsc && vite build",
8+
"lint": "eslint \"**/*.{js,jsx,ts,tsx}\"",
9+
"preview": "vite preview"
10+
},
11+
"dependencies": {
12+
"@txnlab/nfd-sdk": "workspace:*",
13+
"react": "^18.2.0",
14+
"react-dom": "^18.2.0"
15+
},
16+
"devDependencies": {
17+
"@types/react": "^18.2.64",
18+
"@types/react-dom": "^18.2.21",
19+
"@vitejs/plugin-react": "^4.2.1",
20+
"vite": "^4.5.2",
21+
"vite-plugin-node-polyfills": "^0.23.0"
22+
}
23+
}
Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)