@blu1606/create-walrus-app 0.1.4 → 2.0.0
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/dist/generator/file-ops.d.ts +8 -0
- package/dist/generator/file-ops.js +20 -0
- package/dist/generator/index.js +37 -22
- package/dist/generator/layers.d.ts +15 -2
- package/dist/generator/layers.js +38 -47
- package/dist/generator/types.d.ts +9 -1
- package/dist/index.js +1 -2
- package/dist/post-install/git.d.ts +8 -0
- package/dist/post-install/git.js +2 -0
- package/dist/post-install/index.d.ts +0 -1
- package/dist/post-install/index.js +2 -15
- package/dist/post-install/messages.js +1 -1
- package/package.json +68 -68
- package/{templates/base → presets/react-mysten-gallery}/.env.example +31 -31
- package/presets/react-mysten-gallery/.gitkeep +4 -0
- package/{templates/gallery → presets/react-mysten-gallery}/README.md +25 -22
- package/presets/react-mysten-gallery/package.json +34 -0
- package/presets/react-mysten-gallery/src/App.tsx +23 -0
- package/presets/react-mysten-gallery/src/components/features/file-card.tsx +89 -0
- package/{templates/gallery/src/components/GalleryGrid.tsx → presets/react-mysten-gallery/src/components/features/gallery-grid.tsx} +5 -5
- package/presets/react-mysten-gallery/src/components/features/upload-modal.tsx +69 -0
- package/{templates/react/src/components/WalletConnect.tsx → presets/react-mysten-gallery/src/components/features/wallet-connect.tsx} +1 -1
- package/presets/react-mysten-gallery/src/components/layout/app-layout.tsx +21 -0
- package/{templates/react/src/hooks/useStorage.ts → presets/react-mysten-gallery/src/hooks/use-download.ts} +2 -18
- package/presets/react-mysten-gallery/src/hooks/use-upload.ts +49 -0
- package/{templates/react/src/hooks/useWallet.ts → presets/react-mysten-gallery/src/hooks/use-wallet.ts} +2 -7
- package/presets/react-mysten-gallery/src/index.css +384 -0
- package/presets/react-mysten-gallery/src/index.ts +17 -0
- package/presets/react-mysten-gallery/src/lib/walrus/adapter.ts +197 -0
- package/presets/react-mysten-gallery/src/lib/walrus/client.ts +87 -0
- package/presets/react-mysten-gallery/src/lib/walrus/index.ts +4 -0
- package/presets/react-mysten-gallery/src/lib/walrus/types.ts +101 -0
- package/{templates/react → presets/react-mysten-gallery}/src/main.tsx +0 -1
- package/{templates/react → presets/react-mysten-gallery}/src/providers/WalletProvider.tsx +16 -1
- package/{templates/base → presets/react-mysten-gallery}/src/utils/env.ts +41 -41
- package/{templates/gallery → presets/react-mysten-gallery}/src/utils/index-manager.ts +2 -2
- package/presets/react-mysten-gallery/src/utils/mime-type.ts +97 -0
- package/presets/react-mysten-gallery/src/utils/preview-generator.ts +134 -0
- package/{templates/react → presets/react-mysten-gallery}/tsconfig.json +20 -8
- package/presets/react-mysten-simple-upload/.env.example +31 -0
- package/presets/react-mysten-simple-upload/.gitkeep +4 -0
- package/presets/react-mysten-simple-upload/index.html +13 -0
- package/{templates/react → presets/react-mysten-simple-upload}/package.json +13 -11
- package/presets/react-mysten-simple-upload/src/App.tsx +27 -0
- package/presets/react-mysten-simple-upload/src/components/features/file-preview.tsx +73 -0
- package/{templates/simple-upload/src/components/UploadForm.tsx → presets/react-mysten-simple-upload/src/components/features/upload-form.tsx} +15 -5
- package/presets/react-mysten-simple-upload/src/components/features/wallet-connect.tsx +21 -0
- package/presets/react-mysten-simple-upload/src/components/layout/app-layout.tsx +21 -0
- package/presets/react-mysten-simple-upload/src/hooks/use-download.ts +24 -0
- package/presets/react-mysten-simple-upload/src/hooks/use-upload.ts +49 -0
- package/presets/react-mysten-simple-upload/src/hooks/use-wallet.ts +11 -0
- package/presets/react-mysten-simple-upload/src/index.css +252 -0
- package/presets/react-mysten-simple-upload/src/index.ts +16 -0
- package/presets/react-mysten-simple-upload/src/lib/walrus/adapter.ts +197 -0
- package/presets/react-mysten-simple-upload/src/lib/walrus/client.ts +87 -0
- package/presets/react-mysten-simple-upload/src/lib/walrus/index.ts +4 -0
- package/{templates/base/src/adapters/storage.ts → presets/react-mysten-simple-upload/src/lib/walrus/types.ts} +83 -58
- package/presets/react-mysten-simple-upload/src/main.tsx +16 -0
- package/presets/react-mysten-simple-upload/src/providers/QueryProvider.tsx +18 -0
- package/presets/react-mysten-simple-upload/src/providers/WalletProvider.tsx +52 -0
- package/presets/react-mysten-simple-upload/src/utils/env.ts +41 -0
- package/presets/react-mysten-simple-upload/src/utils/mime-type.ts +97 -0
- package/presets/react-mysten-simple-upload/tsconfig.json +39 -0
- package/presets/react-mysten-simple-upload/tsconfig.node.json +10 -0
- package/presets/react-mysten-simple-upload/vite.config.ts +19 -0
- package/dist/__tests__/helpers/adapter-compliance.d.ts +0 -2
- package/dist/__tests__/helpers/adapter-compliance.js +0 -47
- package/dist/__tests__/helpers/fixtures.d.ts +0 -21
- package/dist/__tests__/helpers/fixtures.js +0 -30
- package/dist/__tests__/helpers/fs-helpers.d.ts +0 -12
- package/dist/__tests__/helpers/fs-helpers.js +0 -35
- package/dist/__tests__/helpers/index.d.ts +0 -4
- package/dist/__tests__/helpers/index.js +0 -4
- package/dist/__tests__/helpers/test-hooks.d.ts +0 -3
- package/dist/__tests__/helpers/test-hooks.js +0 -18
- package/dist/context.test.d.ts +0 -1
- package/dist/context.test.js +0 -98
- package/dist/generator/index.test.d.ts +0 -1
- package/dist/generator/index.test.js +0 -143
- package/dist/generator/layers.test.d.ts +0 -1
- package/dist/generator/layers.test.js +0 -92
- package/dist/generator/merge.test.d.ts +0 -1
- package/dist/generator/merge.test.js +0 -79
- package/dist/generator/transform.test.d.ts +0 -1
- package/dist/generator/transform.test.js +0 -51
- package/dist/matrix.test.d.ts +0 -1
- package/dist/matrix.test.js +0 -70
- package/dist/types.test.d.ts +0 -1
- package/dist/types.test.js +0 -65
- package/dist/utils/detect-pm.test.d.ts +0 -1
- package/dist/utils/detect-pm.test.js +0 -52
- package/dist/validator.test.d.ts +0 -1
- package/dist/validator.test.js +0 -96
- package/templates/base/README.md +0 -54
- package/templates/base/package.json +0 -19
- package/templates/base/src/types/index.ts +0 -9
- package/templates/base/src/types/walrus.ts +0 -22
- package/templates/base/src/utils/format.ts +0 -29
- package/templates/base/tsconfig.json +0 -19
- package/templates/gallery/package.json +0 -6
- package/templates/gallery/src/App.tsx +0 -21
- package/templates/gallery/src/components/FileCard.tsx +0 -27
- package/templates/gallery/src/components/UploadModal.tsx +0 -45
- package/templates/gallery/src/styles.css +0 -58
- package/templates/gallery/src/types/gallery.ts +0 -13
- package/templates/react/.eslintrc.json +0 -26
- package/templates/react/README.md +0 -80
- package/templates/react/src/App.tsx +0 -14
- package/templates/react/src/components/Layout.tsx +0 -21
- package/templates/react/src/dapp-kit.css +0 -1
- package/templates/react/src/index.css +0 -50
- package/templates/react/src/index.ts +0 -10
- package/templates/sdk-mysten/README.md +0 -65
- package/templates/sdk-mysten/package.json +0 -14
- package/templates/sdk-mysten/src/adapter.ts +0 -80
- package/templates/sdk-mysten/src/client.ts +0 -45
- package/templates/sdk-mysten/src/config.ts +0 -33
- package/templates/sdk-mysten/src/index.ts +0 -11
- package/templates/sdk-mysten/src/types.ts +0 -19
- package/templates/sdk-mysten/test/adapter.test.ts +0 -20
- package/templates/simple-upload/package.json +0 -6
- package/templates/simple-upload/src/App.tsx +0 -27
- package/templates/simple-upload/src/components/FilePreview.tsx +0 -40
- package/templates/simple-upload/src/styles.css +0 -33
- /package/{templates/react → presets/react-mysten-gallery}/index.html +0 -0
- /package/{templates/react → presets/react-mysten-gallery}/src/providers/QueryProvider.tsx +0 -0
- /package/{templates/react → presets/react-mysten-gallery}/tsconfig.node.json +0 -0
- /package/{templates/react → presets/react-mysten-gallery}/vite.config.ts +0 -0
- /package/{templates/simple-upload → presets/react-mysten-simple-upload}/README.md +0 -0
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
2
|
-
import { useUpload } from '../hooks/useStorage.js';
|
|
3
|
-
import { addItem } from '../utils/index-manager.js';
|
|
4
|
-
|
|
5
|
-
interface UploadModalProps {
|
|
6
|
-
onSuccess: () => void;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function UploadModal({ onSuccess }: UploadModalProps) {
|
|
10
|
-
const [file, setFile] = useState<File | null>(null);
|
|
11
|
-
const upload = useUpload();
|
|
12
|
-
|
|
13
|
-
const handleUpload = async () => {
|
|
14
|
-
if (!file) return;
|
|
15
|
-
|
|
16
|
-
upload.mutate(
|
|
17
|
-
{ file, options: { epochs: 1 } },
|
|
18
|
-
{
|
|
19
|
-
onSuccess: async (data) => {
|
|
20
|
-
addItem({
|
|
21
|
-
blobId: data.blobId,
|
|
22
|
-
name: file.name,
|
|
23
|
-
size: file.size,
|
|
24
|
-
contentType: file.type,
|
|
25
|
-
uploadedAt: Date.now(),
|
|
26
|
-
});
|
|
27
|
-
setFile(null);
|
|
28
|
-
onSuccess();
|
|
29
|
-
},
|
|
30
|
-
}
|
|
31
|
-
);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<div className="upload-modal">
|
|
36
|
-
<input
|
|
37
|
-
type="file"
|
|
38
|
-
onChange={(e) => setFile(e.target.files?.[0] || null)}
|
|
39
|
-
/>
|
|
40
|
-
<button onClick={handleUpload} disabled={!file || upload.isPending}>
|
|
41
|
-
{upload.isPending ? 'Uploading...' : 'Add to Gallery'}
|
|
42
|
-
</button>
|
|
43
|
-
</div>
|
|
44
|
-
);
|
|
45
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
.gallery-app {
|
|
2
|
-
max-width: 1200px;
|
|
3
|
-
margin: 0 auto;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
.upload-modal {
|
|
7
|
-
margin: 2rem 0;
|
|
8
|
-
padding: 1.5rem;
|
|
9
|
-
border: 1px solid #333;
|
|
10
|
-
border-radius: 8px;
|
|
11
|
-
display: flex;
|
|
12
|
-
gap: 1rem;
|
|
13
|
-
align-items: center;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.gallery-grid {
|
|
17
|
-
display: grid;
|
|
18
|
-
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
19
|
-
gap: 1.5rem;
|
|
20
|
-
margin: 2rem 0;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.file-card {
|
|
24
|
-
padding: 1.5rem;
|
|
25
|
-
border: 1px solid #333;
|
|
26
|
-
border-radius: 8px;
|
|
27
|
-
background: #1a1a1a;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.file-card h4 {
|
|
31
|
-
margin: 0 0 1rem 0;
|
|
32
|
-
color: #fff;
|
|
33
|
-
overflow: hidden;
|
|
34
|
-
text-overflow: ellipsis;
|
|
35
|
-
white-space: nowrap;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.file-card p {
|
|
39
|
-
margin: 0.5rem 0;
|
|
40
|
-
font-size: 0.9rem;
|
|
41
|
-
color: #aaa;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.file-card .blob-id {
|
|
45
|
-
font-family: monospace;
|
|
46
|
-
font-size: 0.8rem;
|
|
47
|
-
color: #888;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.file-card button {
|
|
51
|
-
margin-top: 1rem;
|
|
52
|
-
width: 100%;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
button:disabled {
|
|
56
|
-
opacity: 0.5;
|
|
57
|
-
cursor: not-allowed;
|
|
58
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": [
|
|
3
|
-
"eslint:recommended",
|
|
4
|
-
"plugin:@typescript-eslint/recommended",
|
|
5
|
-
"plugin:react/recommended",
|
|
6
|
-
"plugin:react-hooks/recommended"
|
|
7
|
-
],
|
|
8
|
-
"parser": "@typescript-eslint/parser",
|
|
9
|
-
"parserOptions": {
|
|
10
|
-
"ecmaVersion": 2020,
|
|
11
|
-
"sourceType": "module",
|
|
12
|
-
"ecmaFeatures": {
|
|
13
|
-
"jsx": true
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"plugins": ["@typescript-eslint", "react", "react-hooks"],
|
|
17
|
-
"rules": {
|
|
18
|
-
"no-console": "warn",
|
|
19
|
-
"react/react-in-jsx-scope": "off"
|
|
20
|
-
},
|
|
21
|
-
"settings": {
|
|
22
|
-
"react": {
|
|
23
|
-
"version": "detect"
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# React + Vite Framework Layer
|
|
2
|
-
|
|
3
|
-
Modern React 18 application with Vite build system.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
✅ **React 18** - Hooks, Suspense, Concurrent features
|
|
8
|
-
✅ **Vite 5** - Lightning-fast HMR and builds
|
|
9
|
-
✅ **TanStack Query** - Async state management
|
|
10
|
-
✅ **@mysten/dapp-kit** - Sui wallet integration
|
|
11
|
-
✅ **TypeScript** - Full type safety
|
|
12
|
-
|
|
13
|
-
## Project Structure
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
src/
|
|
17
|
-
├── components/ # Reusable UI components
|
|
18
|
-
├── providers/ # Context providers
|
|
19
|
-
├── hooks/ # Custom React hooks
|
|
20
|
-
├── App.tsx # Root component
|
|
21
|
-
└── main.tsx # Entry point
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Custom Hooks
|
|
25
|
-
|
|
26
|
-
### `useUpload()`
|
|
27
|
-
|
|
28
|
-
Upload files to Walrus:
|
|
29
|
-
|
|
30
|
-
```typescript
|
|
31
|
-
const upload = useUpload();
|
|
32
|
-
|
|
33
|
-
upload.mutate({ file: myFile, options: { epochs: 1 } });
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### `useDownload(blobId)`
|
|
37
|
-
|
|
38
|
-
Download blob data:
|
|
39
|
-
|
|
40
|
-
```typescript
|
|
41
|
-
const { data, isLoading } = useDownload(blobId);
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### `useMetadata(blobId)`
|
|
45
|
-
|
|
46
|
-
Fetch blob metadata:
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
const { data: metadata } = useMetadata(blobId);
|
|
50
|
-
console.log(`Size: ${metadata.size} bytes`);
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### `useWallet()`
|
|
54
|
-
|
|
55
|
-
Access wallet state:
|
|
56
|
-
|
|
57
|
-
```typescript
|
|
58
|
-
const { isConnected, address } = useWallet();
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Development
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
npm run dev # Start dev server (http://localhost:3000)
|
|
65
|
-
npm run build # Build for production
|
|
66
|
-
npm run preview # Preview production build
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Wallet Setup
|
|
70
|
-
|
|
71
|
-
1. Install Sui Wallet browser extension
|
|
72
|
-
2. Get testnet SUI from faucet
|
|
73
|
-
3. Connect wallet in the app
|
|
74
|
-
|
|
75
|
-
## Resources
|
|
76
|
-
|
|
77
|
-
- [React Docs](https://react.dev)
|
|
78
|
-
- [Vite Docs](https://vitejs.dev)
|
|
79
|
-
- [TanStack Query](https://tanstack.com/query)
|
|
80
|
-
- [@mysten/dapp-kit](https://sdk.mystenlabs.com/dapp-kit)
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Layout } from './components/Layout.js';
|
|
2
|
-
|
|
3
|
-
function App() {
|
|
4
|
-
return (
|
|
5
|
-
<Layout>
|
|
6
|
-
<div className="welcome">
|
|
7
|
-
<h2>Welcome to Walrus Starter Kit</h2>
|
|
8
|
-
<p>This app will be customized by the use case layer</p>
|
|
9
|
-
</div>
|
|
10
|
-
</Layout>
|
|
11
|
-
);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default App;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
import { WalletConnect } from './WalletConnect.js';
|
|
3
|
-
|
|
4
|
-
interface LayoutProps {
|
|
5
|
-
children: ReactNode;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function Layout({ children }: LayoutProps) {
|
|
9
|
-
return (
|
|
10
|
-
<div className="app-layout">
|
|
11
|
-
<header className="app-header">
|
|
12
|
-
<h1>🌊 Walrus App</h1>
|
|
13
|
-
<WalletConnect />
|
|
14
|
-
</header>
|
|
15
|
-
<main className="app-main">{children}</main>
|
|
16
|
-
<footer className="app-footer">
|
|
17
|
-
<p>Powered by Walrus & Sui</p>
|
|
18
|
-
</footer>
|
|
19
|
-
</div>
|
|
20
|
-
);
|
|
21
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@import '@mysten/dapp-kit/dist/index.css';
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
-
line-height: 1.5;
|
|
4
|
-
font-weight: 400;
|
|
5
|
-
|
|
6
|
-
color-scheme: light dark;
|
|
7
|
-
color: rgba(255, 255, 255, 0.87);
|
|
8
|
-
background-color: #242424;
|
|
9
|
-
|
|
10
|
-
font-synthesis: none;
|
|
11
|
-
text-rendering: optimizeLegibility;
|
|
12
|
-
-webkit-font-smoothing: antialiased;
|
|
13
|
-
-moz-osx-font-smoothing: grayscale;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
body {
|
|
17
|
-
margin: 0;
|
|
18
|
-
display: flex;
|
|
19
|
-
place-items: center;
|
|
20
|
-
min-width: 320px;
|
|
21
|
-
min-height: 100vh;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
#root {
|
|
25
|
-
max-width: 1280px;
|
|
26
|
-
margin: 0 auto;
|
|
27
|
-
padding: 2rem;
|
|
28
|
-
text-align: center;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
button {
|
|
32
|
-
border-radius: 8px;
|
|
33
|
-
border: 1px solid transparent;
|
|
34
|
-
padding: 0.6em 1.2em;
|
|
35
|
-
font-size: 1em;
|
|
36
|
-
font-weight: 500;
|
|
37
|
-
font-family: inherit;
|
|
38
|
-
background-color: #1a1a1a;
|
|
39
|
-
cursor: pointer;
|
|
40
|
-
transition: border-color 0.25s;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
button:hover {
|
|
44
|
-
border-color: #646cff;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
button:focus,
|
|
48
|
-
button:focus-visible {
|
|
49
|
-
outline: 4px auto -webkit-focus-ring-color;
|
|
50
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// Re-export storage adapter from SDK layer for use case templates
|
|
2
|
-
export { storageAdapter } from './adapters/storage.js';
|
|
3
|
-
|
|
4
|
-
// Re-export base adapter types
|
|
5
|
-
export type {
|
|
6
|
-
StorageAdapter,
|
|
7
|
-
BlobMetadata,
|
|
8
|
-
UploadOptions,
|
|
9
|
-
DownloadOptions,
|
|
10
|
-
} from './adapters/storage.js';
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# Mysten Walrus SDK Layer
|
|
2
|
-
|
|
3
|
-
Official [Mysten Labs](https://mystenlabs.com/) SDK implementation for Walrus storage.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
✅ **Relay Upload** - Browser-optimized uploads via relay nodes
|
|
8
|
-
✅ **Direct Download** - Fast blob retrieval
|
|
9
|
-
✅ **Metadata Queries** - Size, type, creation date
|
|
10
|
-
✅ **Network Support** - Testnet, Mainnet, Devnet
|
|
11
|
-
✅ **Type Safety** - Full TypeScript support
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
import { storageAdapter } from './sdk-mysten';
|
|
17
|
-
|
|
18
|
-
// Upload file
|
|
19
|
-
const blobId = await storageAdapter.upload(fileData, { epochs: 1 });
|
|
20
|
-
|
|
21
|
-
// Download file
|
|
22
|
-
const data = await storageAdapter.download(blobId);
|
|
23
|
-
|
|
24
|
-
// Get metadata
|
|
25
|
-
const metadata = await storageAdapter.getMetadata(blobId);
|
|
26
|
-
console.log(`Blob size: ${metadata.size} bytes`);
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Configuration
|
|
30
|
-
|
|
31
|
-
Set environment variables:
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
VITE_WALRUS_NETWORK=testnet
|
|
35
|
-
VITE_WALRUS_PUBLISHER=https://publisher.walrus-testnet.walrus.space
|
|
36
|
-
VITE_WALRUS_AGGREGATOR=https://aggregator.walrus-testnet.walrus.space
|
|
37
|
-
VITE_SUI_RPC=https://fullnode.testnet.sui.io:443
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## API Reference
|
|
41
|
-
|
|
42
|
-
### `storageAdapter`
|
|
43
|
-
|
|
44
|
-
Singleton instance implementing `StorageAdapter` interface.
|
|
45
|
-
|
|
46
|
-
### `getWalrusClient()`
|
|
47
|
-
|
|
48
|
-
Get WalrusClient singleton (lazy initialization).
|
|
49
|
-
|
|
50
|
-
### `getNetworkConfig(network)`
|
|
51
|
-
|
|
52
|
-
Get network-specific configuration.
|
|
53
|
-
|
|
54
|
-
## Network Defaults
|
|
55
|
-
|
|
56
|
-
| Network | Publisher | Aggregator |
|
|
57
|
-
| ------- | ----------------------------------------------- | ------------------------------------------------ |
|
|
58
|
-
| testnet | `https://publisher.walrus-testnet.walrus.space` | `https://aggregator.walrus-testnet.walrus.space` |
|
|
59
|
-
| mainnet | `https://publisher.walrus.space` | `https://aggregator.walrus.space` |
|
|
60
|
-
|
|
61
|
-
## Resources
|
|
62
|
-
|
|
63
|
-
- [Walrus SDK Docs](https://sdk.mystenlabs.com/walrus)
|
|
64
|
-
- [Walrus Documentation](https://docs.walrus.site)
|
|
65
|
-
- [npm: @mysten/walrus](https://www.npmjs.com/package/@mysten/walrus)
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{projectName}}",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"private": true,
|
|
5
|
-
"type": "module",
|
|
6
|
-
"description": "Mysten Walrus SDK layer for walrus-starter-kit",
|
|
7
|
-
"dependencies": {
|
|
8
|
-
"@mysten/walrus": "^0.9.0",
|
|
9
|
-
"@mysten/sui": "^1.10.0"
|
|
10
|
-
},
|
|
11
|
-
"peerDependencies": {
|
|
12
|
-
"typescript": "^5.3.0"
|
|
13
|
-
}
|
|
14
|
-
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
StorageAdapter,
|
|
3
|
-
BlobMetadata,
|
|
4
|
-
UploadOptions,
|
|
5
|
-
DownloadOptions,
|
|
6
|
-
} from '../adapters/storage.js';
|
|
7
|
-
import { getWalrusClient } from './client.js';
|
|
8
|
-
|
|
9
|
-
export class MystenStorageAdapter implements StorageAdapter {
|
|
10
|
-
async upload(
|
|
11
|
-
data: File | Uint8Array,
|
|
12
|
-
options?: UploadOptions
|
|
13
|
-
): Promise<string> {
|
|
14
|
-
const client = getWalrusClient();
|
|
15
|
-
|
|
16
|
-
const bytes =
|
|
17
|
-
data instanceof File ? new Uint8Array(await data.arrayBuffer()) : data;
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
const result = await client.writeBlobToUploadRelay(bytes, {
|
|
21
|
-
nEpochs: options?.epochs || 1,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const blobId = result.newlyCreated.blobObject.blobId;
|
|
25
|
-
|
|
26
|
-
return blobId;
|
|
27
|
-
} catch (error) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
`Upload failed: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async download(
|
|
35
|
-
blobId: string,
|
|
36
|
-
options?: DownloadOptions
|
|
37
|
-
): Promise<Uint8Array> {
|
|
38
|
-
const client = getWalrusClient();
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
const data = await client.readBlob(blobId);
|
|
42
|
-
|
|
43
|
-
return data;
|
|
44
|
-
} catch (error) {
|
|
45
|
-
throw new Error(
|
|
46
|
-
`Download failed for blob ${blobId}: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async getMetadata(blobId: string): Promise<BlobMetadata> {
|
|
52
|
-
const client = getWalrusClient();
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
const metadata = await client.getBlobMetadata(blobId);
|
|
56
|
-
|
|
57
|
-
return {
|
|
58
|
-
blobId,
|
|
59
|
-
size: metadata.size,
|
|
60
|
-
contentType: metadata.contentType,
|
|
61
|
-
createdAt: metadata.createdAt || Date.now(),
|
|
62
|
-
};
|
|
63
|
-
} catch (error) {
|
|
64
|
-
throw new Error(
|
|
65
|
-
`Failed to get metadata for blob ${blobId}: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async exists(blobId: string): Promise<boolean> {
|
|
71
|
-
try {
|
|
72
|
-
await this.getMetadata(blobId);
|
|
73
|
-
return true;
|
|
74
|
-
} catch {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export const storageAdapter = new MystenStorageAdapter();
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { WalrusClient } from '@mysten/walrus';
|
|
2
|
-
import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';
|
|
3
|
-
import { loadEnv } from '../utils/env.js';
|
|
4
|
-
import { getNetworkConfig } from './config.js';
|
|
5
|
-
import type { WalrusNetwork } from '../types/walrus.js';
|
|
6
|
-
|
|
7
|
-
let walrusClient: WalrusClient | null = null;
|
|
8
|
-
|
|
9
|
-
export function getWalrusClient(): WalrusClient {
|
|
10
|
-
if (walrusClient) {
|
|
11
|
-
return walrusClient;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const env = loadEnv();
|
|
15
|
-
|
|
16
|
-
// Validate network value before casting
|
|
17
|
-
const allowedNetworks: WalrusNetwork[] = ['testnet', 'mainnet', 'devnet'];
|
|
18
|
-
if (!allowedNetworks.includes(env.walrusNetwork as WalrusNetwork)) {
|
|
19
|
-
throw new Error(
|
|
20
|
-
`Invalid WALRUS_NETWORK: ${env.walrusNetwork}. Must be one of: ${allowedNetworks.join(', ')}`
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
const network = env.walrusNetwork as WalrusNetwork;
|
|
24
|
-
const config = getNetworkConfig(network);
|
|
25
|
-
|
|
26
|
-
const suiClient = new SuiClient({
|
|
27
|
-
url:
|
|
28
|
-
env.suiRpc ||
|
|
29
|
-
config.suiRpcUrl ||
|
|
30
|
-
getFullnodeUrl(network === 'testnet' ? 'testnet' : 'mainnet'),
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
walrusClient = new WalrusClient({
|
|
34
|
-
network,
|
|
35
|
-
suiClient,
|
|
36
|
-
...(env.walrusPublisher && { publisherUrl: env.walrusPublisher }),
|
|
37
|
-
...(env.walrusAggregator && { aggregatorUrl: env.walrusAggregator }),
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
return walrusClient;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function resetWalrusClient(): void {
|
|
44
|
-
walrusClient = null;
|
|
45
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { WalrusNetwork } from '../types/walrus.js';
|
|
2
|
-
|
|
3
|
-
export interface MystenWalrusConfig {
|
|
4
|
-
network: WalrusNetwork;
|
|
5
|
-
publisherUrl?: string;
|
|
6
|
-
aggregatorUrl?: string;
|
|
7
|
-
suiRpcUrl?: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const NETWORK_CONFIGS: Record<WalrusNetwork, MystenWalrusConfig> = {
|
|
11
|
-
testnet: {
|
|
12
|
-
network: 'testnet',
|
|
13
|
-
publisherUrl: 'https://publisher.walrus-testnet.walrus.space',
|
|
14
|
-
aggregatorUrl: 'https://aggregator.walrus-testnet.walrus.space',
|
|
15
|
-
suiRpcUrl: 'https://fullnode.testnet.sui.io:443',
|
|
16
|
-
},
|
|
17
|
-
mainnet: {
|
|
18
|
-
network: 'mainnet',
|
|
19
|
-
publisherUrl: 'https://publisher.walrus.space',
|
|
20
|
-
aggregatorUrl: 'https://aggregator.walrus.space',
|
|
21
|
-
suiRpcUrl: 'https://fullnode.mainnet.sui.io:443',
|
|
22
|
-
},
|
|
23
|
-
devnet: {
|
|
24
|
-
network: 'devnet',
|
|
25
|
-
publisherUrl: 'http://localhost:8080',
|
|
26
|
-
aggregatorUrl: 'http://localhost:8081',
|
|
27
|
-
suiRpcUrl: 'http://localhost:9000',
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export function getNetworkConfig(network: WalrusNetwork): MystenWalrusConfig {
|
|
32
|
-
return NETWORK_CONFIGS[network];
|
|
33
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export { getWalrusClient, resetWalrusClient } from './client.js';
|
|
2
|
-
export { MystenStorageAdapter, storageAdapter } from './adapter.js';
|
|
3
|
-
export { getNetworkConfig, NETWORK_CONFIGS } from './config.js';
|
|
4
|
-
export type { MystenUploadResult, MystenBlobMetadata } from './types.js';
|
|
5
|
-
|
|
6
|
-
export type {
|
|
7
|
-
StorageAdapter,
|
|
8
|
-
BlobMetadata,
|
|
9
|
-
UploadOptions,
|
|
10
|
-
DownloadOptions,
|
|
11
|
-
} from '../adapters/storage.js';
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mysten-specific type extensions
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export interface MystenUploadResult {
|
|
6
|
-
newlyCreated: {
|
|
7
|
-
blobObject: {
|
|
8
|
-
blobId: string;
|
|
9
|
-
size: number;
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface MystenBlobMetadata {
|
|
15
|
-
size: number;
|
|
16
|
-
encodingType: string;
|
|
17
|
-
contentType?: string;
|
|
18
|
-
createdAt?: number;
|
|
19
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { MystenStorageAdapter } from '../src/adapter.js';
|
|
3
|
-
|
|
4
|
-
describe('MystenStorageAdapter', () => {
|
|
5
|
-
it('should implement StorageAdapter interface', () => {
|
|
6
|
-
const adapter = new MystenStorageAdapter();
|
|
7
|
-
|
|
8
|
-
expect(adapter).toHaveProperty('upload');
|
|
9
|
-
expect(adapter).toHaveProperty('download');
|
|
10
|
-
expect(adapter).toHaveProperty('getMetadata');
|
|
11
|
-
expect(adapter).toHaveProperty('exists');
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('should handle upload errors gracefully', async () => {
|
|
15
|
-
const adapter = new MystenStorageAdapter();
|
|
16
|
-
const invalidData = new Uint8Array(0);
|
|
17
|
-
|
|
18
|
-
await expect(adapter.upload(invalidData)).rejects.toThrow('Upload failed');
|
|
19
|
-
});
|
|
20
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { Layout } from './components/Layout.js';
|
|
2
|
-
import { UploadForm } from './components/UploadForm.js';
|
|
3
|
-
import { FilePreview } from './components/FilePreview.js';
|
|
4
|
-
import './styles.css';
|
|
5
|
-
|
|
6
|
-
function App() {
|
|
7
|
-
return (
|
|
8
|
-
<Layout>
|
|
9
|
-
<div className="simple-upload-app">
|
|
10
|
-
<h2>📤 Simple Upload</h2>
|
|
11
|
-
<p>Upload a file to Walrus and download it by Blob ID</p>
|
|
12
|
-
|
|
13
|
-
<section className="upload-section">
|
|
14
|
-
<h3>Upload File</h3>
|
|
15
|
-
<UploadForm />
|
|
16
|
-
</section>
|
|
17
|
-
|
|
18
|
-
<section className="download-section">
|
|
19
|
-
<h3>Download File</h3>
|
|
20
|
-
<FilePreview />
|
|
21
|
-
</section>
|
|
22
|
-
</div>
|
|
23
|
-
</Layout>
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export default App;
|