WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 4c305e3

Browse files
Added blob download example
1 parent 6eca0dd commit 4c305e3

File tree

6 files changed

+294
-0
lines changed

6 files changed

+294
-0
lines changed

apps/download-blob/.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SHELBY_ACCOUNT_ADDRESS=0x0ab30174c5f0d720e1471bd22579e8d654e02609f753cc246552dc62e6c93d85
2+
SHELBY_API_KEY=AG-MR5SFEFY8BSVMEMVG9YETVQBZJJ2QYEPF

apps/download-blob/README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Shelby Download Blob Example
2+
3+
An example application demonstrating how to download blobs from the Shelby protocol using the Shelby SDK. This app downloads the specified blob from a Shelby account and saves it to the local filesystem.
4+
5+
## Prerequisites
6+
7+
- Node.js >= 22
8+
- npm, yarn, or pnpm package manager
9+
- A Shelby account with uploaded blobs
10+
- Shelby API key
11+
12+
## Installation
13+
14+
1. Clone the repository and navigate to the download-blob directory:
15+
```bash
16+
cd apps/download-blob
17+
```
18+
19+
2. Install dependencies:
20+
```bash
21+
npm install
22+
# or
23+
yarn install
24+
# or
25+
pnpm install
26+
```
27+
28+
## Environment Variables
29+
30+
Create a `.env` file in the root of this project directory with the following required environment variables. You can copy the `.env.example` file as a starting point:
31+
32+
```bash
33+
cp .env.example .env
34+
```
35+
36+
Then update the values in your `.env` file:
37+
38+
```env
39+
SHELBY_ACCOUNT_ADDRESS=your_account_address_here
40+
SHELBY_API_KEY=your_api_key_here
41+
```
42+
43+
More information on obtaining an API key on the [Shelby docs site](https://docs.shelby.xyz/sdks/typescript/acquire-api-keys).
44+
45+
## Configuration
46+
47+
The example is currently configured to download a blob named `whitepaper.pdf`. You can modify this by changing the `BLOB_NAME` constant in `src/index.ts`:
48+
49+
```typescript
50+
const BLOB_NAME = "your-blob-name.ext" // Change this to your desired blob name
51+
```
52+
53+
## Usage
54+
55+
### Development Mode
56+
57+
Run the example in development mode with automatic rebuilding:
58+
59+
```bash
60+
npm run dev
61+
```
62+
63+
### Production Mode
64+
65+
1. Build the app:
66+
```bash
67+
npm run build
68+
```
69+
70+
2. Run the built app:
71+
```bash
72+
npm start
73+
```
74+
75+
### Direct Execution
76+
77+
You can also run the TypeScript file directly using tsx:
78+
79+
```bash
80+
npx tsx src/index.ts
81+
```
82+
83+
## How It Works
84+
85+
1. **Environment Validation**: The app first validates that all required environment variables are set
86+
2. **Client Initialization**: Creates a Shelby client instance connected to the Shelbynet network
87+
3. **Account Setup**: Uses the account address from the environment variable
88+
4. **Blob Download**: Downloads the specified blob from the Shelby account
89+
5. **File Saving**: Saves the downloaded blob to the `downloads/` directory in the current working directory
90+
91+
## Output
92+
93+
When successful, this example will:
94+
- Create a `downloads/` directory if it doesn't exist
95+
- Download the blob from Shelby
96+
- Save the file as `downloads/whitepaper.pdf` (or whatever `BLOB_NAME` you specified)
97+
- Print progress messages to the console
98+
99+
## Troubleshooting
100+
101+
### Common Issues
102+
103+
1. **SHELBY_ACCOUNT_ADDRESS is not set in .env**
104+
- Ensure you have created a `.env` file with the required variables
105+
- Check that the variable name is spelled correctly
106+
107+
2. **SHELBY_API_KEY is not set in .env**
108+
- Verify your API key is correctly set in the `.env` file
109+
- Ensure there are no extra spaces or quotes around the API key
110+
111+
3. **Blob not found (404)**
112+
- Verify that the blob name specified in `BLOB_NAME` exists in your Shelby account
113+
- Check that the blob name matches exactly
114+
- Ensure you're using the correct account address that contains the blob
115+
116+
4. **Rate limit exceeded (429)**
117+
- Wait a moment before retrying
118+
- Consider implementing exponential backoff for production use
119+
120+
5. **Server errors (500)**
121+
- This indicates an issue with the Shelby service
122+
- Contact Shelby support if this occurs repeatedly

apps/download-blob/package.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"name": "shelby-download-example",
3+
"version": "1.0.0",
4+
"description": "An example app to demonstrate downloading blobs using the Shelby SDK",
5+
"main": "dist/index.js",
6+
"type": "module",
7+
"exports": {
8+
".": {
9+
"types": "./dist/index.d.ts",
10+
"import": "./dist/index.js"
11+
}
12+
},
13+
"scripts": {
14+
"build": "tsup",
15+
"start": "node dist/index.js",
16+
"dev": "tsup --watch",
17+
"clean": "rimraf dist",
18+
"type-check": "tsc --noEmit"
19+
},
20+
"keywords": [
21+
"shelby",
22+
"sdk",
23+
"blob",
24+
"storage"
25+
],
26+
"os": [
27+
"darwin",
28+
"linux"
29+
],
30+
"author": "Akasha <[email protected]>",
31+
"license": "MIT",
32+
"dependencies": {
33+
"@aptos-labs/ts-sdk": "^5.1.1",
34+
"@shelby-protocol/sdk": "^0.0.4"
35+
},
36+
"devDependencies": {
37+
"@biomejs/biome": "2.2.4",
38+
"@types/node": "^24.3.1",
39+
"dotenv": "^17.2.2",
40+
"rimraf": "^6.0.1",
41+
"tsup": "^8.5.0",
42+
"tsx": "^4.20.5",
43+
"typescript": "^5.9.2",
44+
"vitest": "^3.2.4"
45+
},
46+
"engines": {
47+
"node": ">=22"
48+
}
49+
}

apps/download-blob/src/index.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import "dotenv/config"
2+
import { createWriteStream, mkdirSync } from "node:fs"
3+
import { dirname, join } from "node:path"
4+
import { Readable } from "node:stream"
5+
import { pipeline } from "node:stream/promises"
6+
import type { ReadableStream } from "node:stream/web"
7+
import {
8+
AccountAddress,
9+
Network,
10+
} from "@aptos-labs/ts-sdk"
11+
import { ShelbyNodeClient } from "@shelby-protocol/sdk/node"
12+
13+
const BLOB_NAME = "whitepaper.pdf" // Name to assign the blob in Shelby
14+
15+
/**
16+
* Load & validate env vars from the .env file (see README)
17+
*/
18+
const SHELBY_ACCOUNT_ADDRESS = process.env.SHELBY_ACCOUNT_ADDRESS as string
19+
const SHELBY_API_KEY = process.env.SHELBY_API_KEY
20+
21+
if (!SHELBY_ACCOUNT_ADDRESS) {
22+
console.error("SHELBY_ACCOUNT_ADDRESS is not set in .env")
23+
process.exit(1)
24+
}
25+
if (!SHELBY_API_KEY) {
26+
console.error("SHELBY_API_KEY is not set in .env")
27+
process.exit(1)
28+
}
29+
30+
/**
31+
* For now, Shelby only supports the shelbynet network
32+
* In the future, you can specify which network to use
33+
*/
34+
const client = new ShelbyNodeClient({
35+
network: Network.SHELBYNET,
36+
apiKey: SHELBY_API_KEY,
37+
})
38+
const account = AccountAddress.fromString(SHELBY_ACCOUNT_ADDRESS)
39+
40+
// Away we go!
41+
async function main() {
42+
try {
43+
/**
44+
* Download the blob from Shelby
45+
*/
46+
console.log("*** Downloading blob from Shelby...")
47+
const download = await client.download({ account, blobName: BLOB_NAME })
48+
console.log("*** Downloaded", BLOB_NAME, "successfully.")
49+
const outPath = join(process.cwd(), "downloads", BLOB_NAME)
50+
/**
51+
* Save the blob to the local filesystem
52+
*/
53+
mkdirSync(dirname(outPath), { recursive: true })
54+
const webStream = download.readable as ReadableStream<Uint8Array>
55+
await pipeline(Readable.fromWeb(webStream), createWriteStream(outPath))
56+
console.log("*** Saved the blob to", outPath)
57+
} catch (e: unknown) {
58+
if (e instanceof Error && e.message.includes("429")) {
59+
console.error("*** Rate limit exceeded (429).")
60+
return
61+
}
62+
const msg = e instanceof Error ? e.message : String(e)
63+
if (/not\s*found|404/i.test(msg)) {
64+
console.error(
65+
`*** Blob "${BLOB_NAME}" not found for account ${SHELBY_ACCOUNT_ADDRESS}`
66+
)
67+
process.exit(1)
68+
}
69+
/**
70+
* If this occurs repeatedly, please contact Shelby support!
71+
*/
72+
if (/500|internal server error/i.test(msg)) {
73+
console.error("*** Server error occurred.")
74+
process.exit(1)
75+
}
76+
console.error("Unexpected error:\n", msg)
77+
process.exit(1)
78+
}
79+
}
80+
81+
main()

apps/download-blob/tsconfig.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2022",
4+
"module": "ESNext",
5+
"moduleResolution": "bundler",
6+
"allowSyntheticDefaultImports": true,
7+
"esModuleInterop": true,
8+
"allowJs": true,
9+
"strict": true,
10+
"skipLibCheck": true,
11+
"forceConsistentCasingInFileNames": true,
12+
"declaration": true,
13+
"declarationMap": true,
14+
"sourceMap": true,
15+
"outDir": "./dist",
16+
"rootDir": "./src",
17+
"resolveJsonModule": true,
18+
"isolatedModules": true,
19+
"noEmit": false,
20+
"lib": ["ES2022", "DOM"],
21+
"types": ["node", "vitest/globals"]
22+
},
23+
"include": ["src/**/*"],
24+
"exclude": ["node_modules", "dist", "**/*.test.ts"]
25+
}

apps/download-blob/tsup.config.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { defineConfig } from "tsup"
2+
3+
export default defineConfig({
4+
entry: ["src/**/*.ts"],
5+
platform: "node",
6+
format: ["esm"],
7+
dts: true,
8+
sourcemap: true,
9+
clean: true,
10+
bundle: true,
11+
splitting: false,
12+
outDir: "dist",
13+
minify: false,
14+
external: ["dotenv"],
15+
})

0 commit comments

Comments
 (0)