@cmdoss/walrus-site-builder 2.2.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/README.md +121 -0
- package/dist/index.d.ts +593 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Site Builder SDK
|
|
2
|
+
|
|
3
|
+
A TypeScript SDK for building and deploying decentralized websites on Walrus + Sui, with integrated file operations using zenfs.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ๐ **Site Management**: Create, update, and manage decentralized websites
|
|
8
|
+
- ๐ **File Operations**: Advanced file handling with zenfs integration
|
|
9
|
+
- ๐ง **Type Safety**: Full TypeScript support with comprehensive type definitions
|
|
10
|
+
- ๐งช **Testing**: Complete test suite with Node.js test runner
|
|
11
|
+
- ๐ **Web Compatible**: Works in both Node.js and browser environments
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @cmdoss/walrus-site-builder
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { WalrusSiteBuilderSdk } from '@cmdoss/walrus-site-builder'
|
|
23
|
+
import { ZenFsFileManager } from '@cmdoss/file-manager'
|
|
24
|
+
import { SuiClient } from '@mysten/sui/client'
|
|
25
|
+
import { WalrusClient } from '@mysten/walrus'
|
|
26
|
+
|
|
27
|
+
const suiClient = new SuiClient({ url: 'https://fullnode.example.com' })
|
|
28
|
+
const walrusClient = new WalrusClient({ suiClient })
|
|
29
|
+
const fileManager = new ZenFsFileManager()
|
|
30
|
+
|
|
31
|
+
const sdk = new WalrusSiteBuilderSdk({
|
|
32
|
+
suiClient,
|
|
33
|
+
walrusClient,
|
|
34
|
+
fileManager,
|
|
35
|
+
signAndExecuteTransaction: async (tx) => {
|
|
36
|
+
// Your wallet signing implementation
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
// Deploy a site
|
|
41
|
+
await sdk.publishSite({
|
|
42
|
+
siteDataPath: '/path/to/site',
|
|
43
|
+
numEpochs: 100
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## File System Integration
|
|
48
|
+
|
|
49
|
+
This SDK uses [zenfs](https://github.com/zen-fs/core) for file operations, providing:
|
|
50
|
+
|
|
51
|
+
- **Cross-platform compatibility**: Works in Node.js and browsers
|
|
52
|
+
- **Memory-efficient**: Handles large files without blocking
|
|
53
|
+
- **Type-safe**: Full TypeScript integration
|
|
54
|
+
- **Feature-rich**: Advanced file operations and metadata
|
|
55
|
+
|
|
56
|
+
## Architecture
|
|
57
|
+
|
|
58
|
+
The SDK follows a modular architecture:
|
|
59
|
+
|
|
60
|
+
```mermaid
|
|
61
|
+
graph TD
|
|
62
|
+
A["๐ WalrusSiteBuilderSdk<br/>Entry Point"] --> B["๐ UpdateWalrusSiteFlow<br/>Deployment Orchestrator"]
|
|
63
|
+
B --> C["๐ prepareResources<br/>Compute Diff & Hashes"]
|
|
64
|
+
C --> D["๐ค writeResources<br/>Upload to Walrus"]
|
|
65
|
+
D --> E["โ
certifyResources<br/>Associate Certificates"]
|
|
66
|
+
E --> F["โ๏ธ writeSite<br/>Create Site on Sui"]
|
|
67
|
+
A --> G["๐ IFileManager<br/>File Operations"]
|
|
68
|
+
G --> H["๐ Node.js & Browser<br/>Cross-platform"]
|
|
69
|
+
|
|
70
|
+
style A fill:#4F46E5,stroke:#312E81,color:#fff,stroke-width:3px
|
|
71
|
+
style B fill:#7C3AED,stroke:#5B21B6,color:#fff,stroke-width:3px
|
|
72
|
+
style C fill:#EC4899,stroke:#BE185D,color:#fff,stroke-width:2px
|
|
73
|
+
style D fill:#F97316,stroke:#C2410C,color:#fff,stroke-width:2px
|
|
74
|
+
style E fill:#06B6D4,stroke:#0E7490,color:#fff,stroke-width:2px
|
|
75
|
+
style F fill:#10B981,stroke:#065F46,color:#fff,stroke-width:2px
|
|
76
|
+
style G fill:#8B5CF6,stroke:#6D28D9,color:#fff,stroke-width:3px
|
|
77
|
+
style H fill:#6366F1,stroke:#3730A3,color:#fff,stroke-width:2px
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Key Components:**
|
|
81
|
+
|
|
82
|
+
- **WalrusSiteBuilderSdk**: Main entry point for site deployment
|
|
83
|
+
- **UpdateWalrusSiteFlow**: Orchestrates the deployment lifecycle
|
|
84
|
+
- `prepareResources()`: Computes file diff and generates hashes
|
|
85
|
+
- `writeResources()`: Uploads blobs to Walrus storage
|
|
86
|
+
- `certifyResources()`: Associates certificates with on-chain data
|
|
87
|
+
- `writeSite()`: Creates/updates Site object on Sui blockchain
|
|
88
|
+
- **IFileManager**: Abstraction for file operations (supports both Node.js and browser)
|
|
89
|
+
|
|
90
|
+
For more details, see [AGENTS.md](../../AGENTS.md) in the root repository.
|
|
91
|
+
|
|
92
|
+
## Examples
|
|
93
|
+
|
|
94
|
+
See the [playground app](../../apps/playground) for comprehensive examples showcasing:
|
|
95
|
+
|
|
96
|
+
- Site creation and deployment
|
|
97
|
+
- File management
|
|
98
|
+
- Wallet integration
|
|
99
|
+
- Resource management
|
|
100
|
+
- Site updates and publishing
|
|
101
|
+
|
|
102
|
+
Refer to the package source in [src/](src/) for detailed API documentation.
|
|
103
|
+
|
|
104
|
+
## Contributing
|
|
105
|
+
|
|
106
|
+
1. Fork the repository
|
|
107
|
+
2. Create a feature branch
|
|
108
|
+
3. Add tests for new functionality
|
|
109
|
+
4. Ensure all tests pass
|
|
110
|
+
5. Submit a pull request
|
|
111
|
+
|
|
112
|
+
## License
|
|
113
|
+
|
|
114
|
+
MIT
|
|
115
|
+
|
|
116
|
+
## Acknowledgments
|
|
117
|
+
|
|
118
|
+
- Built on [Sui](https://sui.io/) blockchain infrastructure
|
|
119
|
+
- Uses [Walrus](https://walrus.xyz/) for decentralized storage
|
|
120
|
+
- File operations powered by [zenfs](https://github.com/zen-fs/core)
|
|
121
|
+
- Inspired by the original [Rust implementation](https://github.com/MystenLabs/walrus-sites)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,593 @@
|
|
|
1
|
+
import { WalrusClient } from "@mysten/walrus";
|
|
2
|
+
import { Transaction } from "@mysten/sui/transactions";
|
|
3
|
+
import { SuiClient, SuiTransactionBlockResponse } from "@mysten/sui/client";
|
|
4
|
+
import { SignedTransaction, SuiSignAndExecuteTransactionInput, SuiSignTransactionInput } from "@mysten/wallet-standard";
|
|
5
|
+
|
|
6
|
+
//#region src/content.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Content types for content of a page.
|
|
9
|
+
*
|
|
10
|
+
* The list is generated starting from
|
|
11
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
|
12
|
+
*/
|
|
13
|
+
declare enum ContentType {
|
|
14
|
+
ApplicationEpubzip = "application/epub+zip",
|
|
15
|
+
ApplicationGzip = "application/gzip",
|
|
16
|
+
ApplicationJavaarchive = "application/java-archive",
|
|
17
|
+
ApplicationJson = "application/json",
|
|
18
|
+
ApplicationLdjson = "application/ld+json",
|
|
19
|
+
ApplicationManifestJson = "application/manifest+json",
|
|
20
|
+
ApplicationMsword = "application/msword",
|
|
21
|
+
ApplicationOctetStream = "application/octet-stream",
|
|
22
|
+
ApplicationOgg = "application/ogg",
|
|
23
|
+
ApplicationPdf = "application/pdf",
|
|
24
|
+
ApplicationRtf = "application/rtf",
|
|
25
|
+
ApplicationVndamazonebook = "application/vnd.amazon.ebook",
|
|
26
|
+
ApplicationVndappleinstallerxml = "application/vnd.apple.installer+xml",
|
|
27
|
+
ApplicationVndmsexcel = "application/vnd.ms-excel",
|
|
28
|
+
ApplicationVndmsfontobject = "application/vnd.ms-fontobject",
|
|
29
|
+
ApplicationVndmspowerpoint = "application/vnd.ms-powerpoint",
|
|
30
|
+
ApplicationVndmozillaxulxml = "application/vnd.mozilla.xul+xml",
|
|
31
|
+
ApplicationVndoasisopendocumentpresentation = "application/vnd.oasis.opendocument.presentation",
|
|
32
|
+
ApplicationVndoasisopendocumentspreadsheet = "application/vnd.oasis.opendocument.spreadsheet",
|
|
33
|
+
ApplicationVndoasisopendocumenttext = "application/vnd.oasis.opendocument.text",
|
|
34
|
+
ApplicationVndopenxmlformatsofficedocumentpresentationmlpresentation = "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
35
|
+
ApplicationVndopenxmlformatsofficedocumentspreadsheetmlsheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
36
|
+
ApplicationVndopenxmlformatsofficedocumentwordprocessingmldocument = "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
37
|
+
ApplicationX7zcompressed = "application/x-7z-compressed",
|
|
38
|
+
ApplicationXabiword = "application/x-abiword",
|
|
39
|
+
ApplicationXcdf = "application/x-cdf",
|
|
40
|
+
ApplicationXcsh = "application/x-csh",
|
|
41
|
+
ApplicationXfreearc = "application/x-freearc",
|
|
42
|
+
ApplicationXhttpdphp = "application/x-httpd-php",
|
|
43
|
+
ApplicationXbzip = "application/x-bzip",
|
|
44
|
+
ApplicationXbzip2 = "application/x-bzip2",
|
|
45
|
+
ApplicationXsh = "application/x-sh",
|
|
46
|
+
ApplicationXtar = "application/x-tar",
|
|
47
|
+
ApplicationXhtmlxml = "application/xhtml+xml",
|
|
48
|
+
ApplicationXml = "application/xml",
|
|
49
|
+
ApplicationZip = "application/zip",
|
|
50
|
+
Audio3gpp = "audio/3gpp",
|
|
51
|
+
Audio3gpp2 = "audio/3gpp2",
|
|
52
|
+
AudioAac = "audio/aac",
|
|
53
|
+
AudioMidi = "audio/midi",
|
|
54
|
+
AudioMpeg = "audio/mpeg",
|
|
55
|
+
AudioOgg = "audio/ogg",
|
|
56
|
+
AudioOpus = "audio/ogg",
|
|
57
|
+
AudioWav = "audio/wav",
|
|
58
|
+
AudioWebm = "audio/webm",
|
|
59
|
+
FontOtf = "font/otf",
|
|
60
|
+
FontTtf = "font/ttf",
|
|
61
|
+
FontWoff = "font/woff",
|
|
62
|
+
FontWoff2 = "font/woff2",
|
|
63
|
+
ImageApng = "image/apng",
|
|
64
|
+
ImageAvif = "image/avif",
|
|
65
|
+
ImageBmp = "image/bmp",
|
|
66
|
+
ImageGif = "image/gif",
|
|
67
|
+
ImageJpeg = "image/jpeg",
|
|
68
|
+
ImagePng = "image/png",
|
|
69
|
+
ImageSvgxml = "image/svg+xml",
|
|
70
|
+
ImageVndmicrosofticon = "image/vnd.microsoft.icon",
|
|
71
|
+
ImageWebp = "image/webp",
|
|
72
|
+
Markdown = "text/markdown",
|
|
73
|
+
TextCalendar = "text/calendar",
|
|
74
|
+
TextCss = "text/css",
|
|
75
|
+
TextCsv = "text/csv",
|
|
76
|
+
TextHtml = "text/html",
|
|
77
|
+
TextJavascript = "text/javascript",
|
|
78
|
+
TextPlain = "text/plain",
|
|
79
|
+
Video3gpp = "video/3gpp",
|
|
80
|
+
Video3gpp2 = "video/3gpp2",
|
|
81
|
+
VideoMp2t = "video/mp2t",
|
|
82
|
+
VideoMp4 = "video/mp4",
|
|
83
|
+
VideoMpeg = "video/mpeg",
|
|
84
|
+
VideoOgg = "video/ogg",
|
|
85
|
+
VideoWebm = "video/webm",
|
|
86
|
+
VideoXmsvideo = "video/x-msvideo",
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get ContentType from file extension
|
|
90
|
+
*/
|
|
91
|
+
declare function contentTypeFromExtension(ext: string): ContentType;
|
|
92
|
+
/**
|
|
93
|
+
* Get ContentType from file path
|
|
94
|
+
*/
|
|
95
|
+
declare function contentTypeFromFilePath(path: string): ContentType;
|
|
96
|
+
/**
|
|
97
|
+
* Convert string to ContentType enum
|
|
98
|
+
*/
|
|
99
|
+
declare function contentTypeFromString(value: string): ContentType;
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/lib/constants.d.ts
|
|
102
|
+
declare const mainPackage: {
|
|
103
|
+
mainnet: {
|
|
104
|
+
packageId: string;
|
|
105
|
+
aggregator: string;
|
|
106
|
+
walrusCoinType: string;
|
|
107
|
+
walrusPackageId: string;
|
|
108
|
+
};
|
|
109
|
+
testnet: {
|
|
110
|
+
packageId: string;
|
|
111
|
+
aggregator: string;
|
|
112
|
+
walrusCoinType: string;
|
|
113
|
+
walrusPackageId: string;
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/lib/hash.d.ts
|
|
118
|
+
/**
|
|
119
|
+
* Calculates SHA-256 hash of input message.
|
|
120
|
+
* @param message Uint8Array to hash
|
|
121
|
+
* @returns Promise<Uint8Array> Resulting hash as Uint8Array
|
|
122
|
+
*/
|
|
123
|
+
declare function getSHA256Hash(message: Uint8Array): Promise<Uint8Array>;
|
|
124
|
+
/**
|
|
125
|
+
* Converts a SHA-256 hash (32-byte Uint8Array) to a little-endian bigint (U256).
|
|
126
|
+
* This matches the Rust U256::from_le_bytes behavior.
|
|
127
|
+
*/
|
|
128
|
+
declare function sha256ToU256(hash: Uint8Array): bigint;
|
|
129
|
+
//#endregion
|
|
130
|
+
//#region src/lib/objectIdToWalrusSiteUrl.d.ts
|
|
131
|
+
/**
|
|
132
|
+
* Converts a Sui object ID (hex string) to a Walrus Site URL for the given portal.
|
|
133
|
+
* @param objectId - The Sui object ID (hex string, with or without 0x prefix)
|
|
134
|
+
* @param portalDomain - The portal domain, e.g., "portal.example.com"
|
|
135
|
+
* @param https - Whether to use HTTPS
|
|
136
|
+
* @returns The Walrus Site URL for the portal
|
|
137
|
+
*/
|
|
138
|
+
declare function objectIdToWalrusSiteUrl(objectId: string, portalDomain?: string, https?: boolean): string;
|
|
139
|
+
/**
|
|
140
|
+
* Converts a SuiNS domain to a Walrus Site URL for the given portal.
|
|
141
|
+
* @param suinsDomain - The SuiNS domain, e.g., "wal-0"
|
|
142
|
+
* @param portalDomain - The portal domain, e.g., "portal.example.com"
|
|
143
|
+
* @param https - Whether to use HTTPS
|
|
144
|
+
* @returns The Walrus Site URL for the portal
|
|
145
|
+
*/
|
|
146
|
+
declare function suinsDomainToWalrusSiteUrl(suinsDomain: string, portalDomain?: string, https?: boolean): string;
|
|
147
|
+
//#endregion
|
|
148
|
+
//#region src/lib/utils.d.ts
|
|
149
|
+
/**
|
|
150
|
+
* Converts a blob ID (base64url) to a U256 bigint.
|
|
151
|
+
*
|
|
152
|
+
* @param blobIdBase64 - The blob ID to convert.
|
|
153
|
+
* @returns The corresponding U256 bigint.
|
|
154
|
+
*/
|
|
155
|
+
declare function blobIdBase64ToU256(blobIdBase64: string): bigint;
|
|
156
|
+
/**
|
|
157
|
+
* Checks if the given network is supported.
|
|
158
|
+
*
|
|
159
|
+
* @param network - The network to check.
|
|
160
|
+
* @returns True if the network is supported, false otherwise.
|
|
161
|
+
*/
|
|
162
|
+
declare function isSupportedNetwork(network: string): network is 'mainnet' | 'testnet';
|
|
163
|
+
/**
|
|
164
|
+
* Converts a U256 bigint to a blob ID (base64url) assuming little-endian byte order.
|
|
165
|
+
*
|
|
166
|
+
* @param value - The bigint value to convert.
|
|
167
|
+
* @returns The corresponding base64url-encoded blob ID (without padding).
|
|
168
|
+
*/
|
|
169
|
+
declare function u256ToBlobIdBase64(value: bigint): string;
|
|
170
|
+
declare function fromBase64(base64String: string): Uint8Array<ArrayBuffer>;
|
|
171
|
+
declare function toBase64(bytes: Uint8Array): string;
|
|
172
|
+
//#endregion
|
|
173
|
+
//#region src/types.d.ts
|
|
174
|
+
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<T>;
|
|
175
|
+
type UseSignAndExecuteTransactionArgs = PartialBy<Omit<SuiSignAndExecuteTransactionInput, 'transaction'>, 'account' | 'chain'> & {
|
|
176
|
+
transaction: Transaction | string;
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* The function used to sign transactions.
|
|
180
|
+
*
|
|
181
|
+
* Get by calling `useSignTransaction` hook in `'@mysten/dapp-kit'`.
|
|
182
|
+
*/
|
|
183
|
+
type UseSignTransactionArgs = PartialBy<Omit<SuiSignTransactionInput, 'transaction'>, 'account' | 'chain'> & {
|
|
184
|
+
transaction: Transaction | string;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* The function used to sign and execute transactions.
|
|
188
|
+
*
|
|
189
|
+
* Get by calling `useSignAndExecuteTransaction` hook in `'@mysten/dapp-kit'`.
|
|
190
|
+
*/
|
|
191
|
+
type ISignAndExecuteTransaction = (variables: UseSignAndExecuteTransactionArgs) => Promise<SuiTransactionBlockResponse>;
|
|
192
|
+
/**
|
|
193
|
+
* The function used to sign transactions.
|
|
194
|
+
*/
|
|
195
|
+
type ISignTransaction = (variables: UseSignTransactionArgs) => Promise<SignedTransaction>;
|
|
196
|
+
/**
|
|
197
|
+
* The function used to sponsor transactions.
|
|
198
|
+
*/
|
|
199
|
+
interface ISponsorConfig {
|
|
200
|
+
/**
|
|
201
|
+
* The API client used to sponsor transactions.
|
|
202
|
+
*/
|
|
203
|
+
apiClient: ISponsorApiClient;
|
|
204
|
+
/**
|
|
205
|
+
* The function used to sign transactions.
|
|
206
|
+
*/
|
|
207
|
+
signTransaction: ISignTransaction;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* The API client used to sponsor transactions.
|
|
211
|
+
*/
|
|
212
|
+
interface ISponsorApiClient {
|
|
213
|
+
sponsorTransaction: ({
|
|
214
|
+
txBytes,
|
|
215
|
+
sender
|
|
216
|
+
}: {
|
|
217
|
+
txBytes: string;
|
|
218
|
+
sender: string;
|
|
219
|
+
}) => Promise<{
|
|
220
|
+
bytes: string;
|
|
221
|
+
digest: string;
|
|
222
|
+
}>;
|
|
223
|
+
executeTransaction: ({
|
|
224
|
+
digest,
|
|
225
|
+
signature
|
|
226
|
+
}: {
|
|
227
|
+
digest: string;
|
|
228
|
+
signature: string;
|
|
229
|
+
}) => Promise<{
|
|
230
|
+
digest: string;
|
|
231
|
+
}>;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Information about a transaction executed during the deploy flow.
|
|
235
|
+
*/
|
|
236
|
+
interface ITransaction {
|
|
237
|
+
digest: string;
|
|
238
|
+
description: string;
|
|
239
|
+
timestamp: number;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Information about a certified blob.
|
|
243
|
+
*
|
|
244
|
+
* This struct mirrors the information that is stored on chain.
|
|
245
|
+
*/
|
|
246
|
+
interface ICertifiedBlob {
|
|
247
|
+
blobId: string;
|
|
248
|
+
suiObjectId: string;
|
|
249
|
+
endEpoch: number;
|
|
250
|
+
patchId: string;
|
|
251
|
+
identifier: string;
|
|
252
|
+
blobHash: string;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* The routes for a site
|
|
256
|
+
*/
|
|
257
|
+
type Routes = Array<[string, string]>;
|
|
258
|
+
/**
|
|
259
|
+
* Metadata associated with a site.
|
|
260
|
+
*/
|
|
261
|
+
interface Metadata {
|
|
262
|
+
link?: string;
|
|
263
|
+
image_url?: string;
|
|
264
|
+
description?: string;
|
|
265
|
+
project_url?: string;
|
|
266
|
+
creator?: string;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Walrus Site Resources & Metadata
|
|
270
|
+
*
|
|
271
|
+
* _(Deserialized object of the file's `ws-resource.json` contents from Walrus Site Builder Rust SDK.)_
|
|
272
|
+
*/
|
|
273
|
+
interface WSResources {
|
|
274
|
+
/** The HTTP headers to be set for the resources. */
|
|
275
|
+
headers?: {
|
|
276
|
+
key: string;
|
|
277
|
+
value: string;
|
|
278
|
+
}[];
|
|
279
|
+
/** The routes for a site. */
|
|
280
|
+
routes?: Routes;
|
|
281
|
+
/** The attributes used inside the Display object. */
|
|
282
|
+
metadata?: Metadata;
|
|
283
|
+
/** The name of the site. */
|
|
284
|
+
site_name?: string;
|
|
285
|
+
/**
|
|
286
|
+
* The object ID of the published site.
|
|
287
|
+
*
|
|
288
|
+
* This parameter is automatically set by the `deploy` command to store
|
|
289
|
+
* the information about the Site object being used, so there is no need
|
|
290
|
+
* to manually keep track of it.
|
|
291
|
+
* On subsequent calls to the `deploy` command, this parameter is used
|
|
292
|
+
* to update the site.
|
|
293
|
+
*/
|
|
294
|
+
object_id?: string;
|
|
295
|
+
/**
|
|
296
|
+
* The paths to ignore when publishing/updating.
|
|
297
|
+
*
|
|
298
|
+
* **NOTE**: Currently not supported by the Walrus Site Builder TS SDK.
|
|
299
|
+
*/
|
|
300
|
+
ignore?: string[];
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Information about a resource.
|
|
304
|
+
*
|
|
305
|
+
* This struct mirrors the information that is stored on chain.
|
|
306
|
+
*/
|
|
307
|
+
interface SuiResource {
|
|
308
|
+
/** The relative path the resource will have on Sui. */
|
|
309
|
+
path: string;
|
|
310
|
+
/** Response, Representation and Payload headers. */
|
|
311
|
+
headers: Array<{
|
|
312
|
+
key: string;
|
|
313
|
+
value: string;
|
|
314
|
+
}>;
|
|
315
|
+
/** The blob ID of the resource as a U256 (U256 from 32 little endian bytes). */
|
|
316
|
+
blob_id: string;
|
|
317
|
+
/** The hash of the blob contents as a U256 (U256 from 32 little endian bytes). */
|
|
318
|
+
blob_hash: string;
|
|
319
|
+
/** Byte ranges for the resource. */
|
|
320
|
+
range?: {
|
|
321
|
+
start?: number;
|
|
322
|
+
end?: number;
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Walrus Site Data. Used for fetching existing site data and computing diffs.
|
|
327
|
+
*/
|
|
328
|
+
interface SiteData {
|
|
329
|
+
resources: SuiResource[];
|
|
330
|
+
routes?: Routes;
|
|
331
|
+
metadata?: Metadata;
|
|
332
|
+
site_name?: string;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Walrus Site Display Data structure. Used in the on-chain display data for Walrus sites.
|
|
336
|
+
*/
|
|
337
|
+
interface WalrusSiteDisplayData {
|
|
338
|
+
creator: string;
|
|
339
|
+
description: string;
|
|
340
|
+
image_url: string;
|
|
341
|
+
link: string;
|
|
342
|
+
project_url: string;
|
|
343
|
+
name: string;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Resource Chain Value structure. Used when fetching resource objects from chain.
|
|
347
|
+
*/
|
|
348
|
+
interface ResourceChainValue {
|
|
349
|
+
type: string;
|
|
350
|
+
fields: {
|
|
351
|
+
blob_hash: string;
|
|
352
|
+
blob_id: string;
|
|
353
|
+
headers: {
|
|
354
|
+
type: string;
|
|
355
|
+
fields: {
|
|
356
|
+
contents: Array<{
|
|
357
|
+
type: string;
|
|
358
|
+
fields: {
|
|
359
|
+
key: string;
|
|
360
|
+
value: string;
|
|
361
|
+
};
|
|
362
|
+
}>;
|
|
363
|
+
};
|
|
364
|
+
};
|
|
365
|
+
path: string;
|
|
366
|
+
range: null | unknown;
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Calculated Walrus Site Data Diff. Used for building transactions and updates operations.
|
|
371
|
+
*/
|
|
372
|
+
interface SiteDataDiff {
|
|
373
|
+
resources: {
|
|
374
|
+
op: 'created' | 'deleted' | 'unchanged' | 'removedRoutes' | 'burnedSite';
|
|
375
|
+
data: SuiResource;
|
|
376
|
+
}[];
|
|
377
|
+
routes: {
|
|
378
|
+
op: 'noop';
|
|
379
|
+
} | {
|
|
380
|
+
op: 'update';
|
|
381
|
+
data: Routes;
|
|
382
|
+
};
|
|
383
|
+
metadata: {
|
|
384
|
+
op: 'noop';
|
|
385
|
+
} | {
|
|
386
|
+
op: 'update';
|
|
387
|
+
data: Metadata;
|
|
388
|
+
};
|
|
389
|
+
site_name: {
|
|
390
|
+
op: 'noop';
|
|
391
|
+
} | {
|
|
392
|
+
op: 'update';
|
|
393
|
+
data: string;
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Asset to be deployed.
|
|
398
|
+
*/
|
|
399
|
+
interface IAsset {
|
|
400
|
+
path: string;
|
|
401
|
+
content: Uint8Array;
|
|
402
|
+
/** SHA-256 hash of the file content */
|
|
403
|
+
/** SHA-256 hash of the file content as U256 little-endian */
|
|
404
|
+
hashU256: bigint;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Represents the deployment flow for a Walrus site.
|
|
408
|
+
*
|
|
409
|
+
* When the transactions to upload a blob are signed by a wallet in a browser,
|
|
410
|
+
* some wallets will use popups to prompt the user for a signature. If the
|
|
411
|
+
* popups are not opened in direct response to a user interaction,
|
|
412
|
+
* they may be blocked by the browser.
|
|
413
|
+
*
|
|
414
|
+
* To avoid this, we need to ensure that we execute the transactions that
|
|
415
|
+
* register and certify the blob in separate events handlers by creating
|
|
416
|
+
* separate buttons for the user to click for each step.
|
|
417
|
+
*/
|
|
418
|
+
interface IUpdateWalrusSiteFlow {
|
|
419
|
+
/**
|
|
420
|
+
* Prepares the site's resources for deployment.
|
|
421
|
+
*/
|
|
422
|
+
prepareResources(): Promise<SiteDataDiff>;
|
|
423
|
+
/**
|
|
424
|
+
* Writes the site's resources to Walrus.
|
|
425
|
+
* @param epochs The number of epochs to store the blobs for.
|
|
426
|
+
* @param permanent Make the stored resources permanent.
|
|
427
|
+
*/
|
|
428
|
+
writeResources(epochs: number | 'max', permanent?: boolean): Promise<void>;
|
|
429
|
+
/**
|
|
430
|
+
* Certifies the written resources.
|
|
431
|
+
*/
|
|
432
|
+
certifyResources(): Promise<void>;
|
|
433
|
+
/**
|
|
434
|
+
* Update the Walrus Site on-chain with the certified resources and metadata.
|
|
435
|
+
* @return The site ID after the update.
|
|
436
|
+
*/
|
|
437
|
+
writeSite(): Promise<{
|
|
438
|
+
siteId: string;
|
|
439
|
+
}>;
|
|
440
|
+
/** Get the list of transactions executed during the flow */
|
|
441
|
+
getTransactions(): ITransaction[];
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Walrus Site Builder SDK interface.
|
|
445
|
+
*/
|
|
446
|
+
interface IWalrusSiteBuilderSdk {
|
|
447
|
+
/**
|
|
448
|
+
* Start a deploy flow for deploying a Walrus Site.
|
|
449
|
+
*/
|
|
450
|
+
executeSiteUpdateFlow(assets: IAsset[], wsResource?: WSResources): IUpdateWalrusSiteFlow;
|
|
451
|
+
}
|
|
452
|
+
//#endregion
|
|
453
|
+
//#region src/sdk.d.ts
|
|
454
|
+
/**
|
|
455
|
+
* SDK for publishing Walrus Sites.
|
|
456
|
+
*/
|
|
457
|
+
declare class WalrusSiteBuilderSdk implements IWalrusSiteBuilderSdk {
|
|
458
|
+
/**
|
|
459
|
+
* The Walrus client used for interacting with the Walrus API.
|
|
460
|
+
*/
|
|
461
|
+
walrus: WalrusClient;
|
|
462
|
+
/**
|
|
463
|
+
* The Sui client used for interacting with the Sui API.
|
|
464
|
+
*/
|
|
465
|
+
suiClient: SuiClient;
|
|
466
|
+
/**
|
|
467
|
+
* The active wallet account.
|
|
468
|
+
*/
|
|
469
|
+
walletAddr: string;
|
|
470
|
+
/**
|
|
471
|
+
* The function used to sign and execute transactions.
|
|
472
|
+
*
|
|
473
|
+
* Get by calling `useSignAndExecuteTransaction` hook in `'@mysten/dapp-kit'`.
|
|
474
|
+
*
|
|
475
|
+
* ```ts
|
|
476
|
+
* const { mutateAsync: signAndExecuteTransaction } =
|
|
477
|
+
* useSignAndExecuteTransaction({
|
|
478
|
+
* execute: async ({ bytes, signature }) =>
|
|
479
|
+
* await suiClient.executeTransactionBlock({
|
|
480
|
+
* transactionBlock: bytes,
|
|
481
|
+
* signature,
|
|
482
|
+
* options: {
|
|
483
|
+
* // Raw effects are required so the effects can be reported back to the wallet
|
|
484
|
+
* showRawEffects: true,
|
|
485
|
+
* // Select additional data to return
|
|
486
|
+
* showObjectChanges: true
|
|
487
|
+
* }
|
|
488
|
+
* })
|
|
489
|
+
* })
|
|
490
|
+
* ```
|
|
491
|
+
*/
|
|
492
|
+
signAndExecuteTransaction: ISignAndExecuteTransaction;
|
|
493
|
+
/**
|
|
494
|
+
* The function used to sign transactions.
|
|
495
|
+
*/
|
|
496
|
+
sponsorConfig?: ISponsorConfig | undefined;
|
|
497
|
+
private txExecutor;
|
|
498
|
+
constructor(
|
|
499
|
+
/**
|
|
500
|
+
* The Walrus client used for interacting with the Walrus API.
|
|
501
|
+
*/
|
|
502
|
+
walrus: WalrusClient,
|
|
503
|
+
/**
|
|
504
|
+
* The Sui client used for interacting with the Sui API.
|
|
505
|
+
*/
|
|
506
|
+
suiClient: SuiClient,
|
|
507
|
+
/**
|
|
508
|
+
* The active wallet account.
|
|
509
|
+
*/
|
|
510
|
+
walletAddr: string,
|
|
511
|
+
/**
|
|
512
|
+
* The function used to sign and execute transactions.
|
|
513
|
+
*
|
|
514
|
+
* Get by calling `useSignAndExecuteTransaction` hook in `'@mysten/dapp-kit'`.
|
|
515
|
+
*
|
|
516
|
+
* ```ts
|
|
517
|
+
* const { mutateAsync: signAndExecuteTransaction } =
|
|
518
|
+
* useSignAndExecuteTransaction({
|
|
519
|
+
* execute: async ({ bytes, signature }) =>
|
|
520
|
+
* await suiClient.executeTransactionBlock({
|
|
521
|
+
* transactionBlock: bytes,
|
|
522
|
+
* signature,
|
|
523
|
+
* options: {
|
|
524
|
+
* // Raw effects are required so the effects can be reported back to the wallet
|
|
525
|
+
* showRawEffects: true,
|
|
526
|
+
* // Select additional data to return
|
|
527
|
+
* showObjectChanges: true
|
|
528
|
+
* }
|
|
529
|
+
* })
|
|
530
|
+
* })
|
|
531
|
+
* ```
|
|
532
|
+
*/
|
|
533
|
+
signAndExecuteTransaction: ISignAndExecuteTransaction,
|
|
534
|
+
/**
|
|
535
|
+
* The function used to sign transactions.
|
|
536
|
+
*/
|
|
537
|
+
sponsorConfig?: ISponsorConfig | undefined);
|
|
538
|
+
/**
|
|
539
|
+
* Create a deploy flow for deploying a Walrus Site.
|
|
540
|
+
*/
|
|
541
|
+
executeSiteUpdateFlow(assets: IAsset[], wsResource: WSResources): IUpdateWalrusSiteFlow;
|
|
542
|
+
updateSiteMetadata(siteId: string, siteName: string, metadata: WSResources['metadata']): Promise<string>;
|
|
543
|
+
}
|
|
544
|
+
//#endregion
|
|
545
|
+
//#region src/services/transaction-executor.service.d.ts
|
|
546
|
+
interface TransactionExecutorOptions {
|
|
547
|
+
suiClient: SuiClient;
|
|
548
|
+
walletAddress: string;
|
|
549
|
+
signAndExecuteTransaction: ISignAndExecuteTransaction;
|
|
550
|
+
sponsorConfig?: ISponsorConfig;
|
|
551
|
+
}
|
|
552
|
+
interface ExecuteTransactionOptions {
|
|
553
|
+
transaction: Transaction;
|
|
554
|
+
description: string;
|
|
555
|
+
/**
|
|
556
|
+
* Callback to record transaction history
|
|
557
|
+
*/
|
|
558
|
+
onTransactionRecorded?: (transaction: ITransaction) => void;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Service for executing transactions with optional sponsor support.
|
|
562
|
+
* Centralizes transaction execution logic to avoid code duplication.
|
|
563
|
+
*/
|
|
564
|
+
declare class TransactionExecutorService {
|
|
565
|
+
#private;
|
|
566
|
+
private options;
|
|
567
|
+
constructor(options: TransactionExecutorOptions);
|
|
568
|
+
/**
|
|
569
|
+
* Execute a transaction with automatic sponsor detection.
|
|
570
|
+
* Returns the transaction digest.
|
|
571
|
+
*/
|
|
572
|
+
execute({
|
|
573
|
+
transaction,
|
|
574
|
+
description,
|
|
575
|
+
onTransactionRecorded
|
|
576
|
+
}: ExecuteTransactionOptions): Promise<string>;
|
|
577
|
+
/**
|
|
578
|
+
* Execute a transaction and return the full response.
|
|
579
|
+
* Useful when you need to extract data from the response.
|
|
580
|
+
*/
|
|
581
|
+
executeWithResponse({
|
|
582
|
+
transaction,
|
|
583
|
+
description,
|
|
584
|
+
onTransactionRecorded
|
|
585
|
+
}: ExecuteTransactionOptions): Promise<SuiTransactionBlockResponse>;
|
|
586
|
+
/**
|
|
587
|
+
* Check if sponsor is enabled
|
|
588
|
+
*/
|
|
589
|
+
get isSponsorEnabled(): boolean;
|
|
590
|
+
}
|
|
591
|
+
//#endregion
|
|
592
|
+
export { ContentType, ExecuteTransactionOptions, IAsset, ICertifiedBlob, ISignAndExecuteTransaction, ISignTransaction, ISponsorApiClient, ISponsorConfig, ITransaction, IUpdateWalrusSiteFlow, IWalrusSiteBuilderSdk, Metadata, ResourceChainValue, Routes, SiteData, SiteDataDiff, SuiResource, TransactionExecutorOptions, TransactionExecutorService, WSResources, WalrusSiteBuilderSdk, WalrusSiteDisplayData, blobIdBase64ToU256, contentTypeFromExtension, contentTypeFromFilePath, contentTypeFromString, fromBase64, getSHA256Hash, isSupportedNetwork, mainPackage, objectIdToWalrusSiteUrl, sha256ToU256, suinsDomainToWalrusSiteUrl, toBase64, u256ToBlobIdBase64 };
|
|
593
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/content.ts","../src/lib/constants.ts","../src/lib/hash.ts","../src/lib/objectIdToWalrusSiteUrl.ts","../src/lib/utils.ts","../src/types.ts","../src/sdk.ts","../src/services/transaction-executor.service.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import e from"debug";import{WalrusFile as t}from"@mysten/walrus";import{Transaction as n}from"@mysten/sui/transactions";import{bcs as r}from"@mysten/sui/bcs";import{deriveDynamicFieldID as i,fromBase64 as a,toBase64 as o}from"@mysten/sui/utils";let s=function(e){return e.ApplicationEpubzip=`application/epub+zip`,e.ApplicationGzip=`application/gzip`,e.ApplicationJavaarchive=`application/java-archive`,e.ApplicationJson=`application/json`,e.ApplicationLdjson=`application/ld+json`,e.ApplicationManifestJson=`application/manifest+json`,e.ApplicationMsword=`application/msword`,e.ApplicationOctetStream=`application/octet-stream`,e.ApplicationOgg=`application/ogg`,e.ApplicationPdf=`application/pdf`,e.ApplicationRtf=`application/rtf`,e.ApplicationVndamazonebook=`application/vnd.amazon.ebook`,e.ApplicationVndappleinstallerxml=`application/vnd.apple.installer+xml`,e.ApplicationVndmsexcel=`application/vnd.ms-excel`,e.ApplicationVndmsfontobject=`application/vnd.ms-fontobject`,e.ApplicationVndmspowerpoint=`application/vnd.ms-powerpoint`,e.ApplicationVndmozillaxulxml=`application/vnd.mozilla.xul+xml`,e.ApplicationVndoasisopendocumentpresentation=`application/vnd.oasis.opendocument.presentation`,e.ApplicationVndoasisopendocumentspreadsheet=`application/vnd.oasis.opendocument.spreadsheet`,e.ApplicationVndoasisopendocumenttext=`application/vnd.oasis.opendocument.text`,e.ApplicationVndopenxmlformatsofficedocumentpresentationmlpresentation=`application/vnd.openxmlformats-officedocument.presentationml.presentation`,e.ApplicationVndopenxmlformatsofficedocumentspreadsheetmlsheet=`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`,e.ApplicationVndopenxmlformatsofficedocumentwordprocessingmldocument=`application/vnd.openxmlformats-officedocument.wordprocessingml.document`,e.ApplicationX7zcompressed=`application/x-7z-compressed`,e.ApplicationXabiword=`application/x-abiword`,e.ApplicationXcdf=`application/x-cdf`,e.ApplicationXcsh=`application/x-csh`,e.ApplicationXfreearc=`application/x-freearc`,e.ApplicationXhttpdphp=`application/x-httpd-php`,e.ApplicationXbzip=`application/x-bzip`,e.ApplicationXbzip2=`application/x-bzip2`,e.ApplicationXsh=`application/x-sh`,e.ApplicationXtar=`application/x-tar`,e.ApplicationXhtmlxml=`application/xhtml+xml`,e.ApplicationXml=`application/xml`,e.ApplicationZip=`application/zip`,e.Audio3gpp=`audio/3gpp`,e.Audio3gpp2=`audio/3gpp2`,e.AudioAac=`audio/aac`,e.AudioMidi=`audio/midi`,e.AudioMpeg=`audio/mpeg`,e.AudioOgg=`audio/ogg`,e.AudioOpus=`audio/ogg`,e.AudioWav=`audio/wav`,e.AudioWebm=`audio/webm`,e.FontOtf=`font/otf`,e.FontTtf=`font/ttf`,e.FontWoff=`font/woff`,e.FontWoff2=`font/woff2`,e.ImageApng=`image/apng`,e.ImageAvif=`image/avif`,e.ImageBmp=`image/bmp`,e.ImageGif=`image/gif`,e.ImageJpeg=`image/jpeg`,e.ImagePng=`image/png`,e.ImageSvgxml=`image/svg+xml`,e.ImageVndmicrosofticon=`image/vnd.microsoft.icon`,e.ImageWebp=`image/webp`,e.Markdown=`text/markdown`,e.TextCalendar=`text/calendar`,e.TextCss=`text/css`,e.TextCsv=`text/csv`,e.TextHtml=`text/html`,e.TextJavascript=`text/javascript`,e.TextPlain=`text/plain`,e.Video3gpp=`video/3gpp`,e.Video3gpp2=`video/3gpp2`,e.VideoMp2t=`video/mp2t`,e.VideoMp4=`video/mp4`,e.VideoMpeg=`video/mpeg`,e.VideoOgg=`video/ogg`,e.VideoWebm=`video/webm`,e.VideoXmsvideo=`video/x-msvideo`,e}({});function c(e){switch(e){case`aac`:return s.AudioAac;case`abw`:return s.ApplicationXabiword;case`apng`:return s.ImageApng;case`arc`:return s.ApplicationXfreearc;case`avif`:return s.ImageAvif;case`avi`:return s.VideoXmsvideo;case`azw`:return s.ApplicationVndamazonebook;case`bin`:return s.ApplicationOctetStream;case`bmp`:return s.ImageBmp;case`bz`:return s.ApplicationXbzip;case`bz2`:return s.ApplicationXbzip2;case`cda`:return s.ApplicationXcdf;case`csh`:return s.ApplicationXcsh;case`css`:return s.TextCss;case`csv`:return s.TextCsv;case`doc`:return s.ApplicationMsword;case`docx`:return s.ApplicationVndopenxmlformatsofficedocumentwordprocessingmldocument;case`eot`:return s.ApplicationVndmsfontobject;case`epub`:return s.ApplicationEpubzip;case`gz`:return s.ApplicationGzip;case`gif`:return s.ImageGif;case`htm`:case`html`:return s.TextHtml;case`ico`:return s.ImageVndmicrosofticon;case`ics`:return s.TextCalendar;case`jar`:return s.ApplicationJavaarchive;case`jpeg`:case`jpg`:return s.ImageJpeg;case`js`:case`mjs`:return s.TextJavascript;case`json`:return s.ApplicationJson;case`jsonld`:return s.ApplicationLdjson;case`mid`:case`midi`:return s.AudioMidi;case`mp3`:return s.AudioMpeg;case`mp4`:return s.VideoMp4;case`mpeg`:return s.VideoMpeg;case`mpkg`:return s.ApplicationVndappleinstallerxml;case`odp`:return s.ApplicationVndoasisopendocumentpresentation;case`ods`:return s.ApplicationVndoasisopendocumentspreadsheet;case`odt`:return s.ApplicationVndoasisopendocumenttext;case`oga`:return s.AudioOgg;case`ogv`:case`ogg`:return s.VideoOgg;case`ogx`:return s.ApplicationOgg;case`opus`:return s.AudioOpus;case`otf`:return s.FontOtf;case`png`:return s.ImagePng;case`pdf`:return s.ApplicationPdf;case`php`:return s.ApplicationXhttpdphp;case`ppt`:return s.ApplicationVndmspowerpoint;case`pptx`:return s.ApplicationVndopenxmlformatsofficedocumentpresentationmlpresentation;case`rar`:return s.ApplicationXtar;case`rtf`:return s.ApplicationRtf;case`sh`:return s.ApplicationXsh;case`svg`:return s.ImageSvgxml;case`tar`:return s.ApplicationXtar;case`tif`:case`tiff`:return s.ImageSvgxml;case`ts`:return s.VideoMp2t;case`ttf`:return s.FontTtf;case`txt`:return s.TextPlain;case`vsd`:return s.ApplicationOctetStream;case`wav`:return s.AudioWav;case`weba`:return s.AudioWebm;case`webm`:return s.VideoWebm;case`webp`:return s.ImageWebp;case`woff`:return s.FontWoff;case`woff2`:return s.FontWoff2;case`xhtml`:return s.ApplicationXhtmlxml;case`xls`:return s.ApplicationVndmsexcel;case`xlsx`:return s.ApplicationVndopenxmlformatsofficedocumentspreadsheetmlsheet;case`xml`:return s.ApplicationXml;case`xul`:return s.ApplicationVndmozillaxulxml;case`zip`:return s.ApplicationZip;case`7z`:return s.ApplicationX7zcompressed;default:return s.ApplicationOctetStream}}function l(e){return c(e.toLowerCase().split(`.`).pop()||``)}function u(e){switch(e){case`audio/aac`:return s.AudioAac;case`application/x-abiword`:return s.ApplicationXabiword;case`image/apng`:return s.ImageApng;case`application/x-freearc`:return s.ApplicationXfreearc;case`image/avif`:return s.ImageAvif;case`video/x-msvideo`:return s.VideoXmsvideo;case`application/vnd.amazon.ebook`:return s.ApplicationVndamazonebook;case`application/octet-stream`:return s.ApplicationOctetStream;case`image/bmp`:return s.ImageBmp;case`application/x-bzip`:return s.ApplicationXbzip;case`application/x-bzip2`:return s.ApplicationXbzip2;case`application/x-cdf`:return s.ApplicationXcdf;case`application/x-csh`:return s.ApplicationXcsh;case`text/css`:return s.TextCss;case`text/csv`:return s.TextCsv;case`application/msword`:return s.ApplicationMsword;case`application/vnd.openxmlformats-officedocument.wordprocessingml.document`:return s.ApplicationVndopenxmlformatsofficedocumentwordprocessingmldocument;case`application/vnd.ms-fontobject`:return s.ApplicationVndmsfontobject;case`application/epub+zip`:return s.ApplicationEpubzip;case`application/gzip`:return s.ApplicationGzip;case`image/gif`:return s.ImageGif;case`text/html`:return s.TextHtml;case`image/vnd.microsoft.icon`:return s.ImageVndmicrosofticon;case`text/calendar`:return s.TextCalendar;case`application/java-archive`:return s.ApplicationJavaarchive;case`image/jpeg`:return s.ImageJpeg;case`text/javascript`:return s.TextJavascript;case`application/json`:return s.ApplicationJson;case`application/ld+json`:return s.ApplicationLdjson;case`audio/midi`:return s.AudioMidi;case`audio/mpeg`:return s.AudioMpeg;case`video/mp4`:return s.VideoMp4;case`video/mpeg`:return s.VideoMpeg;case`application/vnd.apple.installer+xml`:return s.ApplicationVndappleinstallerxml;case`application/vnd.oasis.opendocument.presentation`:return s.ApplicationVndoasisopendocumentpresentation;case`application/vnd.oasis.opendocument.spreadsheet`:return s.ApplicationVndoasisopendocumentspreadsheet;case`application/vnd.oasis.opendocument.text`:return s.ApplicationVndoasisopendocumenttext;case`audio/ogg`:return s.AudioOgg;case`video/ogg`:return s.VideoOgg;case`application/ogg`:return s.ApplicationOgg;case`audio/opus`:return s.AudioOpus;case`font/otf`:return s.FontOtf;case`image/png`:return s.ImagePng;case`application/pdf`:return s.ApplicationPdf;case`application/x-httpd-php`:return s.ApplicationXhttpdphp;case`application/vnd.ms-powerpoint`:return s.ApplicationVndmspowerpoint;case`application/vnd.openxmlformats-officedocument.presentationml.presentation`:return s.ApplicationVndopenxmlformatsofficedocumentpresentationmlpresentation;case`application/vnd.rar`:return s.ApplicationXtar;case`application/rtf`:return s.ApplicationRtf;case`application/x-sh`:return s.ApplicationXsh;case`image/svg+xml`:return s.ImageSvgxml;case`application/x-tar`:return s.ApplicationXtar;case`image/tiff`:return s.ImageSvgxml;case`video/mp2t`:return s.VideoMp2t;case`font/ttf`:return s.FontTtf;case`text/plain`:return s.TextPlain;case`application/vnd.visio`:return s.ApplicationOctetStream;case`audio/wav`:return s.AudioWav;case`audio/webm`:return s.AudioWebm;case`video/webm`:return s.VideoWebm;case`image/webp`:return s.ImageWebp;case`font/woff`:return s.FontWoff;case`font/woff2`:return s.FontWoff2;case`application/xhtml+xml`:return s.ApplicationXhtmlxml;case`application/vnd.ms-excel`:return s.ApplicationVndmsexcel;case`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`:return s.ApplicationVndopenxmlformatsofficedocumentspreadsheetmlsheet;case`application/xml`:return s.ApplicationXml;case`application/vnd.mozilla.xul+xml`:return s.ApplicationVndmozillaxulxml;case`application/zip`:return s.ApplicationZip;case`application/x-7z-compressed`:return s.ApplicationX7zcompressed;default:throw Error(`Invalid conversion to content type`)}}const d={mainnet:{packageId:`0x26eb7ee8688da02c5f671679524e379f0b837a12f1d1d799f255b7eea260ad27`,aggregator:`https://aggregator.walrus-mainnet.walrus.space`,walrusCoinType:`0x356a26eb9e012a68958082340d4c4116e7f55615cf27affcff209cf0ae544f59::wal::WAL`,walrusPackageId:`0xfa65cb2d62f4d39e60346fb7d501c12538ca2bbc646eaa37ece2aec5f897814e`},testnet:{packageId:`0xf99aee9f21493e1590e7e5a9aea6f343a1f381031a04a732724871fc294be799`,aggregator:`https://aggregator.walrus-testnet.walrus.space`,walrusCoinType:`0x8270feb7375eee355e64fdb69c50abb6b5f9393a722883c1cf45f8e26048810a::wal::WAL`,walrusPackageId:`0xa998b8719ca1c0a6dc4e24a859bbb39f5477417f71885fbf2967a6510f699144`}};async function f(e){try{let t=await crypto.subtle.digest(`SHA-256`,new Uint8Array(e));return new Uint8Array(t)}catch(e){throw Error(`Failed to compute SHA-256 hash: ${e.message}`)}}function p(e){if(e.length!==32)throw Error(`Hash must be 32 bytes`);let t=0n;for(let n=0;n<32;n++)t|=BigInt(e[n])<<8n*BigInt(n);return t}function m(e,t=`localhost:3000`,n=!1){let r=e.startsWith(`0x`)?e.slice(2):e,i=BigInt(`0x${r}`).toString(36);return`http${n?`s`:``}://${i}.${t}`}function h(e,t=`localhost:3000`,n=!1){return`http${n?`s`:``}://${e}.${t}`}function g(e){let t=e+`=`.repeat((4-e.length%4)%4),n=Uint8Array.from(atob(t.replace(/-/g,`+`).replace(/_/g,`/`)),e=>e.charCodeAt(0)),r=0n;for(let e=0;e<n.length;e++)r+=BigInt(n[e])<<8n*BigInt(e);return r}function _(e){return e===`mainnet`||e===`testnet`}function v(e){if(e<0n)throw Error(`Value must be a non-negative bigint`);let t=[],n=e;for(;n>0n;)t.push(Number(n&255n)),n>>=8n;t.length===0&&t.push(0);let r=String.fromCharCode(...t);return btoa(r).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function y(e){return Uint8Array.from(atob(e),e=>e.charCodeAt(0))}const b=8192;function x(e){if(e.length<b)return btoa(String.fromCharCode(...e));let t=``;for(let n=0;n<e.length;n+=b){let r=e.slice(n,n+b);t+=String.fromCharCode(...r)}return btoa(t)}function S(e,t){return t?.effects?.created?.find(t=>C(t.owner)===e)?.reference.objectId}function C(e){if(typeof e==`object`){if(`AddressOwner`in e)return e.AddressOwner;if(`ObjectOwner`in e)return e.ObjectOwner;if(`ConsensusAddressOwner`in e)return e.ConsensusAddressOwner.owner}}function w(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=t.padEnd(t.length+(4-t.length%4)%4,`=`),r=atob(n),i=new Uint8Array(r.length);for(let e=0;e<r.length;e++)i[e]=r.charCodeAt(e);return i}function T(e){return Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``)}function E(e){let t=w(e);if(t.length!==37)throw Error(`Expected 37 bytes when decoding quilt-patch-id version 1, got ${t.length}`);let n=t.slice(32,37),r=n[0];if(r!==1)throw Error(`Quilt patch version ${r} is not implemented`);return`0x${T(n)}`}const D=e(`site-builder:site-data-utils`);function O(e){return e?!!(e.resources.some(e=>e.op!==`unchanged`)||e.site_name.op!==`noop`||e.metadata.op!==`noop`||e.routes?.op!==`noop`):!1}function k(e,t){D(`๐งฎ Compute site data diff...`),D(`ยป Current site data:`,t),D(`ยป Next site data:`,e);let n={resources:j(t,e),routes:A(t,e),metadata:M(t,e),site_name:t.site_name===e.site_name?{op:`noop`}:{op:`update`,data:e.site_name??``}};return D(`โ
Computed site data diff:`,n),n}function A(e,t){let n=new Map(e.routes||[]),r=new Map(t.routes||[]),i=!1;for(let[e,t]of r)if(!n.has(e)||n.get(e)!==t){i=!0;break}if(!i){for(let e of n.keys())if(!r.has(e)){i=!0;break}}return i?{op:`update`,data:t.routes??[]}:{op:`noop`}}function j(e,t){let n=[],r=new Map(e.resources.map(e=>[e.path,e])),i=new Map(t.resources.map(e=>[e.path,e]));for(let[e,t]of r){let r=i.get(e);(!r||r.blob_hash!==t.blob_hash)&&n.push({op:`deleted`,data:t})}for(let[e,t]of i){let i=r.get(e);(!i||t.blob_hash!==i.blob_hash)&&n.push({op:`created`,data:t})}for(let[e,t]of i){let i=r.get(e);i&&t.blob_hash===i.blob_hash&&n.push({op:`unchanged`,data:i})}return n}function M(e,t){return!e.metadata&&!t.metadata?{op:`noop`}:!e.metadata||!t.metadata?{op:`update`,data:t.metadata??{}}:e.metadata.link!==t.metadata.link||e.metadata.image_url!==t.metadata.image_url||e.metadata.description!==t.metadata.description||e.metadata.project_url!==t.metadata.project_url||e.metadata.creator!==t.metadata.creator?{op:`update`,data:t.metadata}:{op:`noop`}}var N=class extends n{constructor(e){super(),this.packageId=e}site_newRangeOption(e){return this.moveCall({target:`${this.packageId}::site::new_range_option`,arguments:[this.pure.option(`u64`,e?.start),this.pure.option(`u64`,e?.end)]})}site_newResource(e,t){return this.moveCall({target:`${this.packageId}::site::new_resource`,arguments:[this.pure.string(e.path),this.pure.u256(e.blob_id),this.pure.u256(e.blob_hash),...t?[t]:[]]})}site_newMetadata(e){return this.moveCall({target:`${this.packageId}::metadata::new_metadata`,arguments:[this.pure.option(`string`,e.link),this.pure.option(`string`,e.image_url),this.pure.option(`string`,e.description),this.pure.option(`string`,e.project_url),this.pure.option(`string`,e.creator)]})}site_newSite(e,t){return this.moveCall({target:`${this.packageId}::site::new_site`,arguments:[this.pure.string(e),t]})}site_updateName(e,t){return this.moveCall({target:`${this.packageId}::site::update_name`,arguments:[e,this.pure.string(t)]})}site_addHeader(e,t,n){return this.moveCall({target:`${this.packageId}::site::add_header`,arguments:[e,this.pure.string(t),this.pure.string(n)]})}site_addResource(e,t){return this.moveCall({target:`${this.packageId}::site::add_resource`,arguments:[e,t]})}site_createRoutes(e){return this.moveCall({target:`${this.packageId}::site::create_routes`,arguments:[e]})}site_insertRoute(e,t,n){return this.moveCall({target:`${this.packageId}::site::insert_route`,arguments:[e,this.pure.string(t),this.pure.string(n)]})}site_remoteRoutes(e){return this.moveCall({target:`${this.packageId}::site::remove_all_routes_if_exist`,arguments:[e]})}site_removeAllRoutesIfExist(e){return this.moveCall({target:`${this.packageId}::site::remove_all_routes_if_exist`,arguments:[e]})}site_updateMetadata(e,t){return this.moveCall({target:`${this.packageId}::site::update_metadata`,arguments:[e,t]})}site_removeResourceIfExists(e,t){return this.moveCall({target:`${this.packageId}::site::remove_resource_if_exists`,arguments:[e,this.pure.string(t)]})}site_burn(e){return this.moveCall({target:`${this.packageId}::site::burn`,arguments:[e]})}};const P=e(`site-builder:tx-builder`);function F(e,t,n,r){let i=new N(n),a=0,o;if(e){if(P(`Updating existing site...`),o=i.object(e),t.metadata.op!==`noop`){P(`Updating site metadata`,t.metadata.data),P(`[${++a}] Creating new metadata object`);let e=i.site_newMetadata(t.metadata.data);P(`[${++a}] Updating site metadata`),i.site_updateMetadata(o,e)}t.site_name.op!==`noop`&&(P(`[${++a}] Updating site name`,t.site_name.data),i.site_updateName(o,t.site_name.data))}else{if(P(`Creating new site...`),t.metadata.op===`noop`)throw Error(`Creating site requires metadata`);if(t.site_name.op===`noop`)throw Error(`Creating site requires site name`);P(`New site metadata`,t.metadata.data);let e=i.site_newMetadata(t.metadata.data);P(`New site name`,t.site_name.data),o=i.site_newSite(t.site_name.data,e)}for(let{op:e,data:n}of t.resources)switch(e){case`unchanged`:continue;case`deleted`:P(`[${++a}] Removing resource`,n.path),i.site_removeResourceIfExists(o,n.path);continue;case`created`:{P(`Creating new resource`,n.path),P(`[${++a}] Creating new range`,n.range);let e=i.site_newRangeOption(n.range);P(`[${++a}] Creating new resource object`);let t=i.site_newResource(n,e);for(let{key:e,value:r}of n.headers)P(`ยป [${++a}] Adding header`,[e,r]),i.site_addHeader(t,e,r);P(`[${++a}] Adding resource to site`),i.site_addResource(o,t);break}case`removedRoutes`:P(`Removing all routes as part of resource update...`),P(`[${++a}] Removing existing routes...`),i.site_remoteRoutes(o);break;case`burnedSite`:P(`Burning site as part of resource update...`),P(`[${++a}] Burning site object...`),i.site_burn(o);break;default:throw Error(`Unhandled resource operation: ${e}`)}if(t.routes.op!==`noop`&&(P(`Updating site routes...`),P(`[${++a}] Removing existing routes...`),i.site_remoteRoutes(o),t.routes.data.length)){P(`[${++a}] Creating new Routes object...`),i.site_createRoutes(o);for(let[e,n]of t.routes.data)P(`[${++a}] Inserting route`,e,`->`,n),i.site_insertRoute(o,e,n)}return e||(P(`[${++a}] Transferring site ownership to`,r),i.transferObjects([o],i.pure.address(r))),i}async function I(e,t){if(!_(t))throw Error(`Unsupported network`);let{aggregator:n}=d[t],r=[];for(let t of e){let e=await(await fetch(`${n}/v1/quilts/${t}/patches`)).json();r.push(...e.filter(e=>!r.some(t=>t.patch_id===e.patch_id)))}return r}function L(e){switch(e.code){case`deleted`:throw Error(`Walrus site has been deleted`);case`notExists`:throw Error(`Walrus site does not exist`);case`displayError`:throw Error(`Failed to fetch Walrus site display data`);case`dynamicFieldNotFound`:throw Error(`Walrus site dynamic field not found`);default:throw Error(`Unknown error when fetching Walrus site!`)}}var R=class{#e;constructor(e){this.#e=e}async fetchSiteDynamicFields(e){let t=[],n=null;for(;;){let r=await this.#e.getDynamicFields({parentId:e,cursor:n});if(n=r.nextCursor,t.push(...r.data),!r.hasNextPage)break}return t}};const z=e(`site-builder:site-service`),B=r.bytes(32),V=r.struct(`Routes`,{routes_list:r.map(r.string(),r.string())}),H=r.struct(`DynamicField`,{parentId:B,name:r.vector(r.u8()),value:V}),U=new TextEncoder().encode(`routes`);var W=class{#e;#t;constructor(e){this.#e=e,this.#t=new R(e)}async calculateSiteDiff(e,t){z(`๐ Calculating site diff...`);let n=await this.#n(e,t);if(z(`๐ Built next site data with`,n.resources.length,`resources`,n),!t.object_id)return z(`๐ No existing site ID, treating all resources as new`),k(n,{resources:[]});z(`๐ Fetching existing site data for:`,t.object_id);let r=await this.getSiteDataFromChain(t.object_id);return z(`๐ฅ Fetched existing site with`,r.resources.length,`resources:`,r),k(n,r)}async getSiteDataFromChain(e){let t=await this.#e.getObject({id:e,options:{showDisplay:!0}}),n=t.data?.display?.error??t.error;n&&L(n);let r=t.data?.display?.data;if(!r)throw Error(`No data returned for Walrus site`);let i=r,[a,o]=await Promise.all([this.#a(e),this.#i(e)]);return{site_name:i.name,metadata:i,resources:a,routes:o}}async#n(e,t){let n=[];for(let r of e){let{path:e,hashU256:i}=r,a={path:e,blob_id:`<pending>`,blob_hash:i.toString(),headers:t.headers??[{key:`content-encoding`,value:`identity`},{key:`content-type`,value:l(e)}]};n.push(a)}let r=new Set(n.map(e=>e.path));return{resources:n,routes:this.#r(t.routes,r),site_name:t.site_name,metadata:t.metadata}}#r(e,t){if(e&&e.length>0){let n=[];for(let[r,i]of e)t.has(i)||n.push({route:r,target:i});if(n.length>0){let e=n.map(e=>` - Route "${e.route}" -> "${e.target}" (resource not found)`).join(`
|
|
2
|
+
`);throw Error(`Invalid routes: the following routes point to non-existent resources:\n${e}\nAvailable resource paths: ${Array.from(t).join(`, `)}`)}return z(`โ
Validated`,e.length,`routes`),e}}async#i(e){z(`๐ค๏ธ Fetching routes for site:`,e);let t=i(e,`vector<u8>`,r.vector(r.u8()).serialize(U).toBytes());z(`๐ Routes dynamic field ID:`,t);let n=(await this.#e.getObject({id:t,options:{showBcs:!0}})).data;if(!n||!n.bcs||n.bcs.dataType!==`moveObject`){z(`โน๏ธ No routes dynamic field found for site`);return}let o=H.parse(a(n.bcs.bcsBytes)).value.routes_list,s=Array.from(o.entries());return z(`โ
Fetched`,s.length,`routes from chain`),s.length>0?s:void 0}async#a(e){let t=this.#e.network;if(!_(t))throw Error(`Unsupported network: ${t}`);let n=d[t].packageId,r=(await this.#t.fetchSiteDynamicFields(e)).filter(e=>e.objectType===`${n}::site::Resource`).filter(e=>e.name.type===`${n}::site::ResourcePath`),i=[];for(let e of r){let t=await this.#e.getObject({id:e.objectId,options:{showContent:!0}}).then(e=>e.data?.content);if(!t||t?.dataType!==`moveObject`)throw Error(`Invalid resource object data type`);let n=t.fields;if(Array.isArray(n))throw Error(`Invalid resource object fields`);if(!(`value`in n))throw Error(`Invalid resource object fields value`);let{fields:r}=n.value,a={blob_hash:r.blob_hash,blob_id:r.blob_id,headers:r.headers.fields.contents.map(e=>e.fields),path:r.path};i.push(a)}return i}};const G=e(`site-builder:transaction-executor`);var K=class{constructor(e){this.options=e}async execute({transaction:e,description:t,onTransactionRecorded:n}){let r=this.options.sponsorConfig?await this.#e(e,t):await this.#t(e,t);return n?.({digest:r,description:t,timestamp:Date.now()}),r}async executeWithResponse({transaction:e,description:t,onTransactionRecorded:n}){let r;if(this.options.sponsorConfig){let n=await this.#e(e,t);r=await this.options.suiClient.waitForTransaction({digest:n,options:{showEffects:!0,showObjectChanges:!0}})}else r=await this.options.signAndExecuteTransaction({transaction:e});return n?.({digest:r.digest,description:t,timestamp:Date.now()}),r}get isSponsorEnabled(){return!!this.options.sponsorConfig}async#e(e,t){let{sponsorConfig:n,walletAddress:r,suiClient:i}=this.options;if(!n?.apiClient)throw Error(`Sponsor config not available`);G(`๐ซ Executing sponsored transaction: ${t}`),e.setSenderIfNotSet(r);let a=await e.build({client:i,onlyTransactionKind:!0}),{bytes:s,digest:c}=await n.apiClient.sponsorTransaction({txBytes:o(a),sender:r});G(`โ
Transaction sponsored with digest: ${c}`);let{signature:l}=await n.signTransaction({transaction:s});if(!l)throw Error(`Failed to sign sponsored transaction: No signature returned`);let{digest:u}=await n.apiClient.executeTransaction({digest:c,signature:l});return G(`โ
Sponsored transaction executed: ${u}`),u}async#t(e,t){G(`๐ Executing regular transaction: ${t}`);let{digest:n}=await this.options.signAndExecuteTransaction({transaction:e});return G(`โ
Regular transaction executed: ${n}`),n}};const q=e(`site-builder:deploy-flow`);var J=class{state={transactions:[]};siteSvc;txExecutor;constructor(e,t,n,r,i,a,o){this.walrus=e,this.suiClient=t,this.assets=n,this.wsResource=r,this.signAndExecuteTransaction=i,this.sponsorConfig=a,this.walletAddr=o,this.siteSvc=new W(this.suiClient),this.txExecutor=new K({suiClient:this.suiClient,walletAddress:this.walletAddr,signAndExecuteTransaction:this.signAndExecuteTransaction,sponsorConfig:this.sponsorConfig});for(let e of[`prepareResources`,`writeResources`,`certifyResources`,`writeSite`])this[e]=this[e].bind(this)}async prepareResources(){q(`๐ Calculating site diff...`);let e=await this.siteSvc.calculateSiteDiff(this.assets,this.wsResource);if(q(`โ
Site diff calculated:`,e),this.state.siteUpdates=e,!e.resources.some(e=>e.op===`created`))return q(`โญ๏ธ No new resources detected, skipping upload entirely...`),e;let n=this.walrus.writeFilesFlow({files:this.assets.map(e=>t.from({identifier:e.path,contents:e.content}))});return this.state.writeFilesFlow=n,q(`๐ฆ Getting`,this.assets.length,`files ready for upload...`),await this.state.writeFilesFlow.encode(),q(`โ
Files prepared successfully`),e}async writeResources(e,t=!1){q(`๐ Starting asset upload...`);let{writeFilesFlow:n}=this.state;if(!n)throw Error(`Must prepare resources first`);q(`๐ Registering blob on chain...`,{epochs:e,permanent:t});let r=n.register({deletable:!t,epochs:e===`max`?57:e,owner:this.walletAddr}),i=await this.txExecutor.execute({transaction:r,description:`Register blob on Walrus network`,onTransactionRecorded:this.#t.bind(this)});q(`โ๏ธ Uploading data to storage nodes...`),await n.upload({digest:i}),q(`โ
Data uploaded successfully`)}async certifyResources(){q(`๐ Starting asset certification...`);let{writeFilesFlow:e}=this.state;if(!e)throw Error(`Write files flow not initialized`);let t=e.certify();await this.txExecutor.execute({transaction:t,description:`Certify blob storage`,onTransactionRecorded:this.#t.bind(this)}),q(`โ
Assets certified successfully`),await this.#e()}async#e(){let e=await this.state.writeFilesFlow?.listFiles();if(!e?.length)throw Error(`No certified files found`);q(`๐ Certified files:`,e);let t=Array.from(new Set(e.map(e=>e.blobId)));q(`๐ Fetching patches for blob IDs:`,t);let n=await I(t,this.suiClient.network);q(`๐งฉ Fetched patches:`,n);let r=new Map(n.map(e=>[e.patch_id,e.identifier])),i=new Map(this.state.siteUpdates?.resources.filter(e=>e.op===`created`).map(e=>[e.data.path,e.data.blob_hash])||[]),a=e.map(e=>({patchId:e.id,blobId:e.blobId,suiObjectId:e.blobObject.id.id,endEpoch:e.blobObject.storage.end_epoch,identifier:r.get(e.id)||`unknown`,blobHash:i.get(r.get(e.id)||``)??``}));q(`โ
Certified blobs:`,a),q(`๐ Updating site data with certified files...`);let o=new Map(a.map(e=>[e.identifier,e.patchId])),s=new Map(a.map(e=>[e.identifier,e.blobId]));this.state.siteUpdates?.resources.forEach(e=>{if(e.op!==`created`)return;let t=o.get(e.data.path),n=s.get(e.data.path);if(!t){q(`Blob ID for ${e.data.path} not found`);return}if(!n){q(`Blob ID for ${e.data.path} not found`);return}e.data.blob_id=g(n).toString(),e.data.headers.push({key:`x-wal-quilt-patch-internal-id`,value:E(t)})}),q(`โ
Updated state SiteData with certified files`,this.state.siteUpdates)}async writeSite(){let{siteUpdates:e}=this.state;if(!O(e)){if(!this.wsResource.object_id)throw Error(`No data to create site`);return q(`โญ๏ธ No site updates to apply`),{siteId:this.wsResource.object_id}}q(`๐ Starting site update...`);let t=this.#n({siteId:this.wsResource.object_id,siteUpdates:e,ownerAddr:this.walletAddr}),n=await this.txExecutor.executeWithResponse({transaction:t,description:`Update Walrus site metadata`,onTransactionRecorded:this.#t.bind(this)});if(console.log(`๐ Transaction response:`,n),this.wsResource.object_id)return q(`โ
Site updated successfully`,n),{siteId:this.wsResource.object_id};let r=S(this.walletAddr,n);if(!r)throw Error(`Could not find site ID from response`);return q(`โ
Created new Walrus site with ID:`,r),this.wsResource.object_id=r,{siteId:r}}getTransactions(){return this.state.transactions}#t(e){this.state.transactions||(this.state.transactions=[]),this.state.transactions.push(e)}#n({ownerAddr:e,siteUpdates:t,siteId:n}){q(`โก๏ธ Creating site update transaction`);let r=this.suiClient.network;if(!_(r))throw Error(`Unsupported network: ${r}`);let i=d[r].packageId;return F(n,t,i,e)}};const Y=e(`site-builder:sdk`);var X=class{txExecutor;constructor(e,t,n,r,i){this.walrus=e,this.suiClient=t,this.walletAddr=n,this.signAndExecuteTransaction=r,this.sponsorConfig=i,this.txExecutor=new K({suiClient:t,walletAddress:this.walletAddr,signAndExecuteTransaction:r,sponsorConfig:i})}executeSiteUpdateFlow(e,t){return new J(this.walrus,this.suiClient,e,t,this.signAndExecuteTransaction,this.sponsorConfig,this.walletAddr)}async updateSiteMetadata(e,t,n){let r=await new W(this.suiClient).calculateSiteDiff([],{object_id:e,site_name:t,metadata:n});Y(`๐ Starting site update...`);let i=this.suiClient.network;if(!_(i))throw Error(`Unsupported network: ${i}`);let a=d[i].packageId,o=F(e,r,a,this.walletAddr),s=await this.txExecutor.executeWithResponse({transaction:o,description:`Update Walrus site metadata`});return console.log(`๐ Transaction response:`,s),s.digest}};export{s as ContentType,K as TransactionExecutorService,X as WalrusSiteBuilderSdk,g as blobIdBase64ToU256,c as contentTypeFromExtension,l as contentTypeFromFilePath,u as contentTypeFromString,y as fromBase64,f as getSHA256Hash,_ as isSupportedNetwork,d as mainPackage,m as objectIdToWalrusSiteUrl,p as sha256ToU256,h as suinsDomainToWalrusSiteUrl,x as toBase64,v as u256ToBlobIdBase64};
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["bytes: number[]","log","result: SiteDataDiff","resource_ops: SiteDataDiff['resources']","packageId: string","log","site: TransactionArgument","patches: Array<QuiltPatchItem>","#suiClient","dynamicFields: DynamicFieldInfo[]","cursor: string | null","log","#suiClient","#chainSrv","#buildSiteDataFromFiles","#fetchSiteResources","#fetchSiteRoutes","resources: SuiResource[]","resource: SuiResource","#processRoutes","invalidRoutes: Array<{ route: string; target: string }>","fromBase64","routes: Routes","result: SuiResource","log","options: TransactionExecutorOptions","#executeSponsoredTransaction","#executeRegularTransaction","response: SuiTransactionBlockResponse","toBase64","log","walrus: WalrusClient","suiClient: SuiClient","assets: IAsset[]","wsResource: WSResources","signAndExecuteTransaction: ISignAndExecuteTransaction","sponsorConfig: ISponsorConfig | undefined","walletAddr: string","#recordTransaction","#fetchAndUpdateBlobPatches","blobs: Array<ICertifiedBlob>","#createSiteUpdateTransaction","walrus: WalrusClient","suiClient: SuiClient","walletAddr: string","signAndExecuteTransaction: ISignAndExecuteTransaction","sponsorConfig?: ISponsorConfig"],"sources":["../src/content.ts","../src/lib/constants.ts","../src/lib/hash.ts","../src/lib/objectIdToWalrusSiteUrl.ts","../src/lib/utils.ts","../src/lib/internal-constants.ts","../src/lib/onchain-data-helpers.ts","../src/lib/path-id.ts","../src/lib/site-data.utils.ts","../src/lib/walrus-site-transaction.ts","../src/lib/tx-builder.ts","../src/queries/blobs-patches.query.ts","../src/lib/handleSuiClientError.ts","../src/services/chain.service.ts","../src/services/site.service.ts","../src/services/transaction-executor.service.ts","../src/deploy-flow.ts","../src/sdk.ts"],"sourcesContent":["/**\n * Content types for content of a page.\n *\n * The list is generated starting from\n * https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types\n */\nexport enum ContentType {\n ApplicationEpubzip = 'application/epub+zip',\n ApplicationGzip = 'application/gzip',\n ApplicationJavaarchive = 'application/java-archive',\n ApplicationJson = 'application/json',\n ApplicationLdjson = 'application/ld+json',\n ApplicationManifestJson = 'application/manifest+json',\n ApplicationMsword = 'application/msword',\n ApplicationOctetStream = 'application/octet-stream',\n ApplicationOgg = 'application/ogg',\n ApplicationPdf = 'application/pdf',\n ApplicationRtf = 'application/rtf',\n ApplicationVndamazonebook = 'application/vnd.amazon.ebook',\n ApplicationVndappleinstallerxml = 'application/vnd.apple.installer+xml',\n ApplicationVndmsexcel = 'application/vnd.ms-excel',\n ApplicationVndmsfontobject = 'application/vnd.ms-fontobject',\n ApplicationVndmspowerpoint = 'application/vnd.ms-powerpoint',\n ApplicationVndmozillaxulxml = 'application/vnd.mozilla.xul+xml',\n ApplicationVndoasisopendocumentpresentation = 'application/vnd.oasis.opendocument.presentation',\n ApplicationVndoasisopendocumentspreadsheet = 'application/vnd.oasis.opendocument.spreadsheet',\n ApplicationVndoasisopendocumenttext = 'application/vnd.oasis.opendocument.text',\n ApplicationVndopenxmlformatsofficedocumentpresentationmlpresentation = 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n ApplicationVndopenxmlformatsofficedocumentspreadsheetmlsheet = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n ApplicationVndopenxmlformatsofficedocumentwordprocessingmldocument = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n ApplicationX7zcompressed = 'application/x-7z-compressed',\n ApplicationXabiword = 'application/x-abiword',\n ApplicationXcdf = 'application/x-cdf',\n ApplicationXcsh = 'application/x-csh',\n ApplicationXfreearc = 'application/x-freearc',\n ApplicationXhttpdphp = 'application/x-httpd-php',\n ApplicationXbzip = 'application/x-bzip',\n ApplicationXbzip2 = 'application/x-bzip2',\n ApplicationXsh = 'application/x-sh',\n ApplicationXtar = 'application/x-tar',\n ApplicationXhtmlxml = 'application/xhtml+xml',\n ApplicationXml = 'application/xml',\n ApplicationZip = 'application/zip',\n Audio3gpp = 'audio/3gpp',\n Audio3gpp2 = 'audio/3gpp2',\n AudioAac = 'audio/aac',\n AudioMidi = 'audio/midi',\n AudioMpeg = 'audio/mpeg',\n AudioOgg = 'audio/ogg',\n AudioOpus = 'audio/ogg',\n AudioWav = 'audio/wav',\n AudioWebm = 'audio/webm',\n FontOtf = 'font/otf',\n FontTtf = 'font/ttf',\n FontWoff = 'font/woff',\n FontWoff2 = 'font/woff2',\n ImageApng = 'image/apng',\n ImageAvif = 'image/avif',\n ImageBmp = 'image/bmp',\n ImageGif = 'image/gif',\n ImageJpeg = 'image/jpeg',\n ImagePng = 'image/png',\n ImageSvgxml = 'image/svg+xml',\n ImageVndmicrosofticon = 'image/vnd.microsoft.icon',\n ImageWebp = 'image/webp',\n Markdown = 'text/markdown',\n TextCalendar = 'text/calendar',\n TextCss = 'text/css',\n TextCsv = 'text/csv',\n TextHtml = 'text/html',\n TextJavascript = 'text/javascript',\n TextPlain = 'text/plain',\n Video3gpp = 'video/3gpp',\n Video3gpp2 = 'video/3gpp2',\n VideoMp2t = 'video/mp2t',\n VideoMp4 = 'video/mp4',\n VideoMpeg = 'video/mpeg',\n VideoOgg = 'video/ogg',\n VideoWebm = 'video/webm',\n VideoXmsvideo = 'video/x-msvideo'\n}\n\n/**\n * Get ContentType from file extension\n */\nexport function contentTypeFromExtension(ext: string): ContentType {\n switch (ext) {\n case 'aac':\n return ContentType.AudioAac\n case 'abw':\n return ContentType.ApplicationXabiword\n case 'apng':\n return ContentType.ImageApng\n case 'arc':\n return ContentType.ApplicationXfreearc\n case 'avif':\n return ContentType.ImageAvif\n case 'avi':\n return ContentType.VideoXmsvideo\n case 'azw':\n return ContentType.ApplicationVndamazonebook\n case 'bin':\n return ContentType.ApplicationOctetStream\n case 'bmp':\n return ContentType.ImageBmp\n case 'bz':\n return ContentType.ApplicationXbzip\n case 'bz2':\n return ContentType.ApplicationXbzip2\n case 'cda':\n return ContentType.ApplicationXcdf\n case 'csh':\n return ContentType.ApplicationXcsh\n case 'css':\n return ContentType.TextCss\n case 'csv':\n return ContentType.TextCsv\n case 'doc':\n return ContentType.ApplicationMsword\n case 'docx':\n return ContentType.ApplicationVndopenxmlformatsofficedocumentwordprocessingmldocument\n case 'eot':\n return ContentType.ApplicationVndmsfontobject\n case 'epub':\n return ContentType.ApplicationEpubzip\n case 'gz':\n return ContentType.ApplicationGzip\n case 'gif':\n return ContentType.ImageGif\n case 'htm':\n case 'html':\n return ContentType.TextHtml\n case 'ico':\n return ContentType.ImageVndmicrosofticon\n case 'ics':\n return ContentType.TextCalendar\n case 'jar':\n return ContentType.ApplicationJavaarchive\n case 'jpeg':\n case 'jpg':\n return ContentType.ImageJpeg\n case 'js':\n case 'mjs':\n return ContentType.TextJavascript\n case 'json':\n return ContentType.ApplicationJson\n case 'jsonld':\n return ContentType.ApplicationLdjson\n case 'mid':\n case 'midi':\n return ContentType.AudioMidi\n case 'mp3':\n return ContentType.AudioMpeg\n case 'mp4':\n return ContentType.VideoMp4\n case 'mpeg':\n return ContentType.VideoMpeg\n case 'mpkg':\n return ContentType.ApplicationVndappleinstallerxml\n case 'odp':\n return ContentType.ApplicationVndoasisopendocumentpresentation\n case 'ods':\n return ContentType.ApplicationVndoasisopendocumentspreadsheet\n case 'odt':\n return ContentType.ApplicationVndoasisopendocumenttext\n case 'oga':\n return ContentType.AudioOgg\n case 'ogv':\n case 'ogg':\n return ContentType.VideoOgg\n case 'ogx':\n return ContentType.ApplicationOgg\n case 'opus':\n return ContentType.AudioOpus\n case 'otf':\n return ContentType.FontOtf\n case 'png':\n return ContentType.ImagePng\n case 'pdf':\n return ContentType.ApplicationPdf\n case 'php':\n return ContentType.ApplicationXhttpdphp\n case 'ppt':\n return ContentType.ApplicationVndmspowerpoint\n case 'pptx':\n return ContentType.ApplicationVndopenxmlformatsofficedocumentpresentationmlpresentation\n case 'rar':\n return ContentType.ApplicationXtar // No direct mapping, fallback to tar\n case 'rtf':\n return ContentType.ApplicationRtf\n case 'sh':\n return ContentType.ApplicationXsh\n case 'svg':\n return ContentType.ImageSvgxml\n case 'tar':\n return ContentType.ApplicationXtar\n case 'tif':\n case 'tiff':\n return ContentType.ImageSvgxml // No direct mapping, fallback to svg+xml\n case 'ts':\n return ContentType.VideoMp2t\n case 'ttf':\n return ContentType.FontTtf\n case 'txt':\n return ContentType.TextPlain\n case 'vsd':\n return ContentType.ApplicationOctetStream // No direct mapping, fallback to octet-stream\n case 'wav':\n return ContentType.AudioWav\n case 'weba':\n return ContentType.AudioWebm\n case 'webm':\n return ContentType.VideoWebm\n case 'webp':\n return ContentType.ImageWebp\n case 'woff':\n return ContentType.FontWoff\n case 'woff2':\n return ContentType.FontWoff2\n case 'xhtml':\n return ContentType.ApplicationXhtmlxml\n case 'xls':\n return ContentType.ApplicationVndmsexcel\n case 'xlsx':\n return ContentType.ApplicationVndopenxmlformatsofficedocumentspreadsheetmlsheet\n case 'xml':\n return ContentType.ApplicationXml\n case 'xul':\n return ContentType.ApplicationVndmozillaxulxml\n case 'zip':\n return ContentType.ApplicationZip\n case '7z':\n return ContentType.ApplicationX7zcompressed\n default:\n return ContentType.ApplicationOctetStream\n }\n}\n\n/**\n * Get ContentType from file path\n */\nexport function contentTypeFromFilePath(path: string): ContentType {\n const ext = path.toLowerCase().split('.').pop() || ''\n return contentTypeFromExtension(ext)\n}\n\n/**\n * Convert string to ContentType enum\n */\nexport function contentTypeFromString(value: string): ContentType {\n switch (value) {\n case 'audio/aac':\n return ContentType.AudioAac\n case 'application/x-abiword':\n return ContentType.ApplicationXabiword\n case 'image/apng':\n return ContentType.ImageApng\n case 'application/x-freearc':\n return ContentType.ApplicationXfreearc\n case 'image/avif':\n return ContentType.ImageAvif\n case 'video/x-msvideo':\n return ContentType.VideoXmsvideo\n case 'application/vnd.amazon.ebook':\n return ContentType.ApplicationVndamazonebook\n case 'application/octet-stream':\n return ContentType.ApplicationOctetStream\n case 'image/bmp':\n return ContentType.ImageBmp\n case 'application/x-bzip':\n return ContentType.ApplicationXbzip\n case 'application/x-bzip2':\n return ContentType.ApplicationXbzip2\n case 'application/x-cdf':\n return ContentType.ApplicationXcdf\n case 'application/x-csh':\n return ContentType.ApplicationXcsh\n case 'text/css':\n return ContentType.TextCss\n case 'text/csv':\n return ContentType.TextCsv\n case 'application/msword':\n return ContentType.ApplicationMsword\n case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':\n return ContentType.ApplicationVndopenxmlformatsofficedocumentwordprocessingmldocument\n case 'application/vnd.ms-fontobject':\n return ContentType.ApplicationVndmsfontobject\n case 'application/epub+zip':\n return ContentType.ApplicationEpubzip\n case 'application/gzip':\n return ContentType.ApplicationGzip\n case 'image/gif':\n return ContentType.ImageGif\n case 'text/html':\n return ContentType.TextHtml\n case 'image/vnd.microsoft.icon':\n return ContentType.ImageVndmicrosofticon\n case 'text/calendar':\n return ContentType.TextCalendar\n case 'application/java-archive':\n return ContentType.ApplicationJavaarchive\n case 'image/jpeg':\n return ContentType.ImageJpeg\n case 'text/javascript':\n return ContentType.TextJavascript\n case 'application/json':\n return ContentType.ApplicationJson\n case 'application/ld+json':\n return ContentType.ApplicationLdjson\n case 'audio/midi':\n return ContentType.AudioMidi\n case 'audio/mpeg':\n return ContentType.AudioMpeg\n case 'video/mp4':\n return ContentType.VideoMp4\n case 'video/mpeg':\n return ContentType.VideoMpeg\n case 'application/vnd.apple.installer+xml':\n return ContentType.ApplicationVndappleinstallerxml\n case 'application/vnd.oasis.opendocument.presentation':\n return ContentType.ApplicationVndoasisopendocumentpresentation\n case 'application/vnd.oasis.opendocument.spreadsheet':\n return ContentType.ApplicationVndoasisopendocumentspreadsheet\n case 'application/vnd.oasis.opendocument.text':\n return ContentType.ApplicationVndoasisopendocumenttext\n case 'audio/ogg':\n return ContentType.AudioOgg\n case 'video/ogg':\n return ContentType.VideoOgg\n case 'application/ogg':\n return ContentType.ApplicationOgg\n case 'audio/opus':\n return ContentType.AudioOpus\n case 'font/otf':\n return ContentType.FontOtf\n case 'image/png':\n return ContentType.ImagePng\n case 'application/pdf':\n return ContentType.ApplicationPdf\n case 'application/x-httpd-php':\n return ContentType.ApplicationXhttpdphp\n case 'application/vnd.ms-powerpoint':\n return ContentType.ApplicationVndmspowerpoint\n case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':\n return ContentType.ApplicationVndopenxmlformatsofficedocumentpresentationmlpresentation\n case 'application/vnd.rar':\n return ContentType.ApplicationXtar // No direct mapping, fallback to tar\n case 'application/rtf':\n return ContentType.ApplicationRtf\n case 'application/x-sh':\n return ContentType.ApplicationXsh\n case 'image/svg+xml':\n return ContentType.ImageSvgxml\n case 'application/x-tar':\n return ContentType.ApplicationXtar\n case 'image/tiff':\n return ContentType.ImageSvgxml // No direct mapping, fallback to svg+xml\n case 'video/mp2t':\n return ContentType.VideoMp2t\n case 'font/ttf':\n return ContentType.FontTtf\n case 'text/plain':\n return ContentType.TextPlain\n case 'application/vnd.visio':\n return ContentType.ApplicationOctetStream // No direct mapping, fallback to octet-stream\n case 'audio/wav':\n return ContentType.AudioWav\n case 'audio/webm':\n return ContentType.AudioWebm\n case 'video/webm':\n return ContentType.VideoWebm\n case 'image/webp':\n return ContentType.ImageWebp\n case 'font/woff':\n return ContentType.FontWoff\n case 'font/woff2':\n return ContentType.FontWoff2\n case 'application/xhtml+xml':\n return ContentType.ApplicationXhtmlxml\n case 'application/vnd.ms-excel':\n return ContentType.ApplicationVndmsexcel\n case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':\n return ContentType.ApplicationVndopenxmlformatsofficedocumentspreadsheetmlsheet\n case 'application/xml':\n return ContentType.ApplicationXml\n case 'application/vnd.mozilla.xul+xml':\n return ContentType.ApplicationVndmozillaxulxml\n case 'application/zip':\n return ContentType.ApplicationZip\n case 'application/x-7z-compressed':\n return ContentType.ApplicationX7zcompressed\n default:\n throw new Error('Invalid conversion to content type')\n }\n}\n","export const mainPackage = {\n // Latest Walrus Site Package, get from https://raw.githubusercontent.com/MystenLabs/walrus-sites/refs/heads/mainnet/sites-config.yaml\n mainnet: {\n packageId:\n '0x26eb7ee8688da02c5f671679524e379f0b837a12f1d1d799f255b7eea260ad27',\n aggregator: 'https://aggregator.walrus-mainnet.walrus.space',\n walrusCoinType:\n '0x356a26eb9e012a68958082340d4c4116e7f55615cf27affcff209cf0ae544f59::wal::WAL',\n walrusPackageId:\n '0xfa65cb2d62f4d39e60346fb7d501c12538ca2bbc646eaa37ece2aec5f897814e'\n },\n testnet: {\n packageId:\n '0xf99aee9f21493e1590e7e5a9aea6f343a1f381031a04a732724871fc294be799',\n aggregator: 'https://aggregator.walrus-testnet.walrus.space',\n walrusCoinType:\n '0x8270feb7375eee355e64fdb69c50abb6b5f9393a722883c1cf45f8e26048810a::wal::WAL',\n walrusPackageId:\n '0xa998b8719ca1c0a6dc4e24a859bbb39f5477417f71885fbf2967a6510f699144'\n }\n}\n","/**\n * Calculates SHA-256 hash of input message.\n * @param message Uint8Array to hash\n * @returns Promise<Uint8Array> Resulting hash as Uint8Array\n */\nexport async function getSHA256Hash(message: Uint8Array): Promise<Uint8Array> {\n try {\n const hash = await crypto.subtle.digest('SHA-256', new Uint8Array(message))\n return new Uint8Array(hash)\n } catch (error) {\n throw new Error(\n `Failed to compute SHA-256 hash: ${(error as Error).message}`\n )\n }\n}\n\n/**\n * Converts a SHA-256 hash (32-byte Uint8Array) to a little-endian bigint (U256).\n * This matches the Rust U256::from_le_bytes behavior.\n */\nexport function sha256ToU256(hash: Uint8Array): bigint {\n if (hash.length !== 32) throw new Error('Hash must be 32 bytes')\n let result = 0n\n for (let i = 0; i < 32; i++) {\n result |= BigInt(hash[i]) << (8n * BigInt(i)) // little-endian\n }\n return result\n}\n","/**\n * Converts a Sui object ID (hex string) to a Walrus Site URL for the given portal.\n * @param objectId - The Sui object ID (hex string, with or without 0x prefix)\n * @param portalDomain - The portal domain, e.g., \"portal.example.com\"\n * @param https - Whether to use HTTPS\n * @returns The Walrus Site URL for the portal\n */\nexport function objectIdToWalrusSiteUrl(\n objectId: string,\n portalDomain = 'localhost:3000',\n https = false\n): string {\n // Remove 0x prefix if present\n const cleanObjectId = objectId.startsWith('0x') ? objectId.slice(2) : objectId\n\n // Convert hex to decimal, then to base36\n const base36Encoded = BigInt(`0x${cleanObjectId}`).toString(36)\n\n // Construct and return the URL\n return `http${https ? 's' : ''}://${base36Encoded}.${portalDomain}`\n}\n\n/**\n * Converts a SuiNS domain to a Walrus Site URL for the given portal.\n * @param suinsDomain - The SuiNS domain, e.g., \"wal-0\"\n * @param portalDomain - The portal domain, e.g., \"portal.example.com\"\n * @param https - Whether to use HTTPS\n * @returns The Walrus Site URL for the portal\n */\nexport function suinsDomainToWalrusSiteUrl(\n suinsDomain: string,\n portalDomain = 'localhost:3000',\n https = false\n): string {\n return `http${https ? 's' : ''}://${suinsDomain}.${portalDomain}`\n}\n","/**\n * Converts a blob ID (base64url) to a U256 bigint.\n *\n * @param blobIdBase64 - The blob ID to convert.\n * @returns The corresponding U256 bigint.\n */\nexport function blobIdBase64ToU256(blobIdBase64: string): bigint {\n // Add padding if needed\n const padded = blobIdBase64 + '='.repeat((4 - (blobIdBase64.length % 4)) % 4)\n const bytes = Uint8Array.from(\n atob(padded.replace(/-/g, '+').replace(/_/g, '/')),\n c => c.charCodeAt(0)\n )\n // Convert bytes to BigInt (little-endian)\n let result = 0n\n for (let i = 0; i < bytes.length; i++) {\n result += BigInt(bytes[i]) << (8n * BigInt(i))\n }\n return result\n}\n\n/**\n * Checks if the given network is supported.\n *\n * @param network - The network to check.\n * @returns True if the network is supported, false otherwise.\n */\nexport function isSupportedNetwork(\n network: string\n): network is 'mainnet' | 'testnet' {\n return network === 'mainnet' || network === 'testnet'\n}\n\n/**\n * Converts a U256 bigint to a blob ID (base64url) assuming little-endian byte order.\n *\n * @param value - The bigint value to convert.\n * @returns The corresponding base64url-encoded blob ID (without padding).\n */\nexport function u256ToBlobIdBase64(value: bigint): string {\n if (value < 0n) {\n throw new Error('Value must be a non-negative bigint')\n }\n\n // Convert BigInt to bytes (little-endian)\n const bytes: number[] = []\n let temp = value\n\n while (temp > 0n) {\n bytes.push(Number(temp & 0xffn))\n temp >>= 8n\n }\n\n if (bytes.length === 0) {\n bytes.push(0)\n }\n\n const binary = String.fromCharCode(...bytes)\n\n // Base64url encode without padding\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nexport function fromBase64(base64String: string): Uint8Array<ArrayBuffer> {\n return Uint8Array.from(atob(base64String), char => char.charCodeAt(0))\n}\n\nconst CHUNK_SIZE = 8192\nexport function toBase64(bytes: Uint8Array): string {\n // Special-case the simple case for speed's sake.\n if (bytes.length < CHUNK_SIZE) {\n return btoa(String.fromCharCode(...bytes))\n }\n\n let output = ''\n for (let i = 0; i < bytes.length; i += CHUNK_SIZE) {\n const chunk = bytes.slice(i, i + CHUNK_SIZE)\n output += String.fromCharCode(...chunk)\n }\n\n return btoa(output)\n}\n","export const QUILT_PATCH_ID_INTERNAL_HEADER = 'x-wal-quilt-patch-internal-id'\n","import type {\n ObjectOwner,\n SuiTransactionBlockResponse\n} from '@mysten/sui/client'\n\n/**\n * Get the object id of the site that was published in the transaction.\n *\n * @param address - The address of the owner to search for\n * @param response - The Sui transaction block response containing the transaction effects\n * @returns The object ID of the created site, or undefined if not found. This can happen if,\n * for example, no object owned by the provided `address` was created\n * in the transaction, or if the transaction did not result in the expected object creation\n * structure that this function relies on.\n */\nexport function getSiteIdFromResponse(\n address: string,\n response: SuiTransactionBlockResponse\n): string | undefined {\n return response?.effects?.created?.find(\n e => getOwnerAddress(e.owner) === address\n )?.reference.objectId\n}\n\n/**\n * Extracts the address from different types of object owners.\n *\n * @remarks This function will return address of both AddressOwner and ObjectOwner,\n * address of ObjectOwner is converted from object id, even though the type is SuiAddress.\n *\n * @param obj - The object owner to extract the address from\n * @returns The address string associated with the owner, `undefined` if not found\n */\nfunction getOwnerAddress(obj: ObjectOwner): string | undefined {\n if (typeof obj !== 'object') return\n if ('AddressOwner' in obj) return obj.AddressOwner\n if ('ObjectOwner' in obj) return obj.ObjectOwner\n if ('ConsensusAddressOwner' in obj) return obj.ConsensusAddressOwner.owner\n}\n","// Constants from the Rust code\nconst BLOB_ID_LENGTH = 32\nconst QUILT_PATCH_SIZE = 5\nconst QUILT_PATCH_ID_SIZE = BLOB_ID_LENGTH + QUILT_PATCH_SIZE\nconst QUILT_PATCH_VERSION_1 = 1\n\n/**\n * Decodes a URL-safe base64 string without padding.\n * In browser, you might need a library like 'js-base64' or implement this.\n */\nfunction decodeUrlSafeBase64NoPad(str: string): Uint8Array {\n // Replace URL-safe chars back to standard base64\n const base64 = str.replace(/-/g, '+').replace(/_/g, '/')\n // Add padding if needed\n const padded = base64.padEnd(\n base64.length + ((4 - (base64.length % 4)) % 4),\n '='\n )\n const binary = atob(padded)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return bytes\n}\n\n/**\n * Converts a byte array to hex string.\n */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Extracts the patch hex from a quilt patch ID string.\n * @param quiltPatchId The base64-encoded quilt patch ID string\n * @returns The patch hex prefixed with '0x'\n * @throws Error if decoding fails or version is unsupported\n */\nexport function extractPatchHex(quiltPatchId: string): string {\n // Decode the base64 string\n const bytes = decodeUrlSafeBase64NoPad(quiltPatchId)\n\n // Must have exactly QUILT_PATCH_ID_SIZE bytes\n if (bytes.length !== QUILT_PATCH_ID_SIZE) {\n throw new Error(\n `Expected ${QUILT_PATCH_ID_SIZE} bytes when decoding quilt-patch-id version 1, got ${bytes.length}`\n )\n }\n\n // Extract patch_bytes (bytes after the blob_id)\n const patchBytes = bytes.slice(BLOB_ID_LENGTH, QUILT_PATCH_ID_SIZE)\n\n // Check version\n const version = patchBytes[0]\n if (version !== QUILT_PATCH_VERSION_1) {\n throw new Error(`Quilt patch version ${version} is not implemented`)\n }\n\n // Convert to hex and prefix with '0x'\n const patchHex = `0x${bytesToHex(patchBytes)}`\n return patchHex\n}\n","import debug from 'debug'\nimport type { SiteData, SiteDataDiff } from '~/types'\n\nconst log = debug('site-builder:site-data-utils')\n\nexport function hasUpdate(\n diff: SiteDataDiff | undefined\n): diff is SiteDataDiff {\n if (!diff) return false\n // Check if there are any non-unchanged resource operations\n if (diff.resources.some(r => r.op !== 'unchanged')) return true\n if (diff.site_name.op !== 'noop') return true\n if (diff.metadata.op !== 'noop') return true\n if (diff.routes?.op !== 'noop') return true\n return false\n}\n\nexport function computeSiteDataDiff(\n next: SiteData,\n current: SiteData\n): SiteDataDiff {\n log('๐งฎ Compute site data diff...')\n log('ยป Current site data:', current)\n log('ยป Next site data:', next)\n\n const resource_ops = computeResourceDiff(current, next)\n const route_ops = computeRoutesDiff(current, next)\n const metadata_ops = computeMetadataDiff(current, next)\n const site_name_ops: SiteDataDiff['site_name'] =\n current.site_name !== next.site_name\n ? { op: 'update', data: next.site_name ?? '' }\n : { op: 'noop' }\n\n const result: SiteDataDiff = {\n resources: resource_ops,\n routes: route_ops,\n metadata: metadata_ops,\n site_name: site_name_ops\n }\n log('โ
Computed site data diff:', result)\n\n return result\n}\n\nfunction computeRoutesDiff(\n current: SiteData,\n next: SiteData\n): SiteDataDiff['routes'] {\n const currentRoutePaths = new Map(current.routes || [])\n const nextRoutePaths = new Map(next.routes || [])\n\n // Check if there are any changes (added, modified, or deleted routes)\n let hasChanges = false\n\n // Check for new or modified routes\n for (const [path, resource] of nextRoutePaths) {\n if (\n !currentRoutePaths.has(path) ||\n currentRoutePaths.get(path) !== resource\n ) {\n hasChanges = true\n break\n }\n }\n\n // Check for deleted routes\n if (!hasChanges) {\n for (const path of currentRoutePaths.keys()) {\n if (!nextRoutePaths.has(path)) {\n hasChanges = true\n break\n }\n }\n }\n\n // If no changes, return noop\n if (!hasChanges) return { op: 'noop' }\n\n // Return update with all routes (unchanged + changed)\n return { op: 'update', data: next.routes ?? [] }\n}\n\nfunction computeResourceDiff(\n current: SiteData,\n next: SiteData\n): SiteDataDiff['resources'] {\n const resource_ops: SiteDataDiff['resources'] = []\n\n // Create maps for efficient lookup by path\n const currentResMap = new Map(current.resources.map(res => [res.path, res]))\n const nextResMap = new Map(next.resources.map(res => [res.path, res]))\n\n // Collect delete operations first (matching Rust's ordering: delete -> create -> unchanged)\n // This ensures resources are removed before new ones are added at the same path\n for (const [path, currentResource] of currentResMap) {\n const nextResource = nextResMap.get(path)\n // Delete if: resource no longer exists OR resource has changed (different hash)\n if (!nextResource || nextResource.blob_hash !== currentResource.blob_hash) {\n resource_ops.push({ op: 'deleted', data: currentResource })\n }\n }\n\n // Then collect create operations\n for (const [path, nextResource] of nextResMap) {\n const currentResource = currentResMap.get(path)\n // Create if: resource is new OR resource has changed (different hash)\n if (\n !currentResource ||\n nextResource.blob_hash !== currentResource.blob_hash\n ) {\n resource_ops.push({ op: 'created', data: nextResource })\n }\n }\n\n // Finally collect unchanged operations\n for (const [path, nextResource] of nextResMap) {\n const currentResource = currentResMap.get(path)\n // Unchanged if: resource exists and hash matches\n if (\n currentResource &&\n nextResource.blob_hash === currentResource.blob_hash\n ) {\n resource_ops.push({ op: 'unchanged', data: currentResource })\n }\n }\n\n return resource_ops\n}\n\nfunction computeMetadataDiff(\n current: SiteData,\n next: SiteData\n): SiteDataDiff['metadata'] {\n // If both are undefined/null, no change\n if (!current.metadata && !next.metadata) return { op: 'noop' }\n\n // If one is undefined/null and the other isn't, it's a change\n if (!current.metadata || !next.metadata)\n return { op: 'update', data: next.metadata ?? {} }\n\n // Compare each property individually\n const isChanged =\n current.metadata.link !== next.metadata.link ||\n current.metadata.image_url !== next.metadata.image_url ||\n current.metadata.description !== next.metadata.description ||\n current.metadata.project_url !== next.metadata.project_url ||\n current.metadata.creator !== next.metadata.creator\n\n return isChanged ? { op: 'update', data: next.metadata } : { op: 'noop' }\n}\n","import {\n Transaction,\n type TransactionArgument,\n type TransactionObjectArgument,\n type TransactionResult\n} from '@mysten/sui/transactions'\nimport type { Metadata, SuiResource } from '~/types'\n\nexport class WalrusSiteTransaction extends Transaction {\n constructor(\n /** Walrus Site Package ID */\n public packageId: string\n ) {\n super()\n }\n\n /** Create New Range Option */\n site_newRangeOption(range?: {\n start?: number\n end?: number\n }): TransactionObjectArgument {\n return this.moveCall({\n target: `${this.packageId}::site::new_range_option`,\n arguments: [\n this.pure.option('u64', range?.start),\n this.pure.option('u64', range?.end)\n ]\n })\n }\n\n /** Create New Resource */\n site_newResource(\n data: SuiResource,\n rangeObj?: TransactionArgument\n ): TransactionObjectArgument {\n return this.moveCall({\n target: `${this.packageId}::site::new_resource`,\n arguments: [\n this.pure.string(data.path),\n this.pure.u256(data.blob_id),\n this.pure.u256(data.blob_hash),\n ...(rangeObj ? [rangeObj] : [])\n ]\n })\n }\n\n /** Create New Metadata */\n site_newMetadata(data: Metadata): TransactionResult {\n return this.moveCall({\n target: `${this.packageId}::metadata::new_metadata`,\n arguments: [\n this.pure.option('string', data.link),\n this.pure.option('string', data.image_url),\n this.pure.option('string', data.description),\n this.pure.option('string', data.project_url),\n this.pure.option('string', data.creator)\n ]\n })\n }\n\n /** Create New Site */\n site_newSite(name: string, metadata: TransactionArgument) {\n return this.moveCall({\n target: `${this.packageId}::site::new_site`,\n arguments: [this.pure.string(name), metadata]\n })\n }\n\n /** Update Site Name */\n site_updateName(site: TransactionObjectArgument, name: string) {\n return this.moveCall({\n target: `${this.packageId}::site::update_name`,\n arguments: [site, this.pure.string(name)]\n })\n }\n\n /** Add Header to Resource */\n site_addHeader(\n resource: TransactionObjectArgument,\n key: string,\n value: string\n ) {\n return this.moveCall({\n target: `${this.packageId}::site::add_header`,\n arguments: [resource, this.pure.string(key), this.pure.string(value)]\n })\n }\n\n /** Add Resource to Site */\n site_addResource(\n site: TransactionObjectArgument,\n resource: TransactionObjectArgument\n ) {\n return this.moveCall({\n target: `${this.packageId}::site::add_resource`,\n arguments: [site, resource]\n })\n }\n\n site_createRoutes(site: TransactionObjectArgument) {\n return this.moveCall({\n target: `${this.packageId}::site::create_routes`,\n arguments: [site]\n })\n }\n\n site_insertRoute(\n site: TransactionObjectArgument,\n name: string,\n value: string\n ) {\n return this.moveCall({\n target: `${this.packageId}::site::insert_route`,\n arguments: [site, this.pure.string(name), this.pure.string(value)]\n })\n }\n\n /**\n * Adds the move calls to remove the routes object.\n */\n site_remoteRoutes(site: TransactionObjectArgument) {\n return this.moveCall({\n target: `${this.packageId}::site::remove_all_routes_if_exist`,\n arguments: [site]\n })\n }\n\n /** @deprecated Use site_remoteRoutes instead */\n site_removeAllRoutesIfExist(site: TransactionObjectArgument) {\n return this.moveCall({\n target: `${this.packageId}::site::remove_all_routes_if_exist`,\n arguments: [site]\n })\n }\n\n site_updateMetadata(\n site: TransactionObjectArgument,\n metadata: TransactionArgument\n ) {\n return this.moveCall({\n target: `${this.packageId}::site::update_metadata`,\n arguments: [site, metadata]\n })\n }\n\n site_removeResourceIfExists(\n site: TransactionObjectArgument,\n resourcePath: string\n ) {\n return this.moveCall({\n target: `${this.packageId}::site::remove_resource_if_exists`,\n arguments: [site, this.pure.string(resourcePath)]\n })\n }\n\n /** Burn the site */\n site_burn(site: TransactionObjectArgument) {\n return this.moveCall({\n target: `${this.packageId}::site::burn`,\n arguments: [site]\n })\n }\n}\n","import type { Transaction, TransactionArgument } from '@mysten/sui/transactions'\nimport debug from 'debug'\nimport type { SiteDataDiff } from '~/types'\nimport { WalrusSiteTransaction } from './walrus-site-transaction'\n\nconst log = debug('site-builder:tx-builder')\n\nexport function buildSiteCreationTx(\n siteId: string | undefined,\n diff: SiteDataDiff,\n packageId: string,\n ownerAddr: string\n): Transaction {\n const tx = new WalrusSiteTransaction(packageId)\n let commandCount = 0\n\n // Create or reference Site Object\n let site: TransactionArgument\n if (!siteId) {\n log('Creating new site...')\n if (diff.metadata.op === 'noop')\n throw new Error('Creating site requires metadata')\n if (diff.site_name.op === 'noop')\n throw new Error('Creating site requires site name')\n\n log('New site metadata', diff.metadata.data)\n const metadata = tx.site_newMetadata(diff.metadata.data)\n log('New site name', diff.site_name.data)\n site = tx.site_newSite(diff.site_name.data, metadata)\n } else {\n log('Updating existing site...')\n site = tx.object(siteId)\n if (diff.metadata.op !== 'noop') {\n log('Updating site metadata', diff.metadata.data)\n log(`[${++commandCount}] Creating new metadata object`)\n const metadata = tx.site_newMetadata(diff.metadata.data)\n log(`[${++commandCount}] Updating site metadata`)\n tx.site_updateMetadata(site, metadata)\n }\n if (diff.site_name.op !== 'noop') {\n log(`[${++commandCount}] Updating site name`, diff.site_name.data)\n tx.site_updateName(site, diff.site_name.data)\n }\n }\n\n // Update Resources\n for (const { op, data } of diff.resources) {\n switch (op) {\n case 'unchanged':\n continue\n case 'deleted':\n log(`[${++commandCount}] Removing resource`, data.path)\n tx.site_removeResourceIfExists(site, data.path)\n continue\n case 'created': {\n log(`Creating new resource`, data.path)\n log(`[${++commandCount}] Creating new range`, data.range)\n const range = tx.site_newRangeOption(data.range)\n log(`[${++commandCount}] Creating new resource object`)\n const res = tx.site_newResource(data, range)\n for (const { key, value } of data.headers) {\n log(`ยป [${++commandCount}] Adding header`, [key, value])\n tx.site_addHeader(res, key, value)\n }\n log(`[${++commandCount}] Adding resource to site`)\n tx.site_addResource(site, res)\n break\n }\n case 'removedRoutes':\n log('Removing all routes as part of resource update...')\n log(`[${++commandCount}] Removing existing routes...`)\n tx.site_remoteRoutes(site)\n break\n case 'burnedSite':\n log('Burning site as part of resource update...')\n log(`[${++commandCount}] Burning site object...`)\n tx.site_burn(site)\n break\n default:\n throw new Error(`Unhandled resource operation: ${op}`)\n }\n }\n\n if (diff.routes.op !== 'noop') {\n log('Updating site routes...')\n\n log(`[${++commandCount}] Removing existing routes...`)\n tx.site_remoteRoutes(site)\n\n if (diff.routes.data.length) {\n log(`[${++commandCount}] Creating new Routes object...`)\n tx.site_createRoutes(site)\n for (const [path, val] of diff.routes.data) {\n log(`[${++commandCount}] Inserting route`, path, '->', val)\n tx.site_insertRoute(site, path, val)\n }\n }\n }\n\n // Transfer site ownership if new site\n if (!siteId) {\n log(`[${++commandCount}] Transferring site ownership to`, ownerAddr)\n tx.transferObjects([site], tx.pure.address(ownerAddr))\n }\n\n return tx as Transaction\n}\n","import { isSupportedNetwork, mainPackage } from '~/lib'\n\n/**\n * Response item for a patch in a quilt.\n *\n * > Fetched from https://github.com/MystenLabs/walrus/blob/main/crates/walrus-service/aggregator_openapi.yamlv1/quilts/{quilt_id}/patches\n */\nexport interface QuiltPatchItem {\n /** The identifier of the patch (e.g., filename). */\n identifier: string\n /** The QuiltPatchId for this patch, encoded as URL-safe base64. */\n patch_id: string\n /** Tags for the patch. */\n tags: Record<string, string>\n}\n\n/**\n * Helps fetch patches for a list of blob IDs.\n */\nexport async function fetchBlobsPatches(\n blobIds: string[],\n network: string\n): Promise<Array<QuiltPatchItem>> {\n if (!isSupportedNetwork(network)) throw new Error(`Unsupported network`)\n const { aggregator } = mainPackage[network]\n const patches: Array<QuiltPatchItem> = []\n for (const blobId of blobIds) {\n const res = await fetch(`${aggregator}/v1/quilts/${blobId}/patches`)\n const items = (await res.json()) as Array<QuiltPatchItem>\n\n // add only unique patches\n patches.push(\n ...items.filter(p => !patches.some(pt => pt.patch_id === p.patch_id))\n )\n }\n return patches\n}\n","import type { ObjectResponseError } from '@mysten/sui/client'\n\nexport function handleSuiClientError(error: ObjectResponseError): never {\n switch (error.code) {\n case 'deleted':\n throw new Error('Walrus site has been deleted')\n case 'notExists':\n throw new Error('Walrus site does not exist')\n case 'displayError':\n throw new Error('Failed to fetch Walrus site display data')\n case 'dynamicFieldNotFound':\n throw new Error('Walrus site dynamic field not found')\n default:\n throw new Error(`Unknown error when fetching Walrus site!`)\n }\n}\n","import type { DynamicFieldInfo, SuiClient } from '@mysten/sui/client'\n\nexport class ChainService {\n #suiClient: SuiClient\n\n constructor(suiClient: SuiClient) {\n this.#suiClient = suiClient\n }\n\n async fetchSiteDynamicFields(siteId: string): Promise<DynamicFieldInfo[]> {\n const dynamicFields: DynamicFieldInfo[] = []\n let cursor: string | null = null\n while (true) {\n const page = await this.#suiClient.getDynamicFields({\n parentId: siteId,\n cursor\n })\n cursor = page.nextCursor\n dynamicFields.push(...page.data)\n if (!page.hasNextPage) break\n }\n return dynamicFields\n }\n}\n","import { bcs } from '@mysten/sui/bcs'\nimport type { SuiClient } from '@mysten/sui/client'\nimport { deriveDynamicFieldID, fromBase64 } from '@mysten/sui/utils'\nimport debug from 'debug'\nimport { contentTypeFromFilePath } from '../content.ts'\nimport { handleSuiClientError } from '../lib/handleSuiClientError.ts'\nimport { isSupportedNetwork, mainPackage } from '../lib/index.ts'\nimport { computeSiteDataDiff } from '../lib/site-data.utils.ts'\nimport type {\n IAsset,\n ResourceChainValue,\n Routes,\n SiteData,\n SiteDataDiff,\n SuiResource,\n WalrusSiteDisplayData,\n WSResources\n} from '../types.ts'\nimport { ChainService } from './chain.service.ts'\n\nconst log = debug('site-builder:site-service')\n\n// BCS struct for parsing Routes dynamic field from chain\nconst Address = bcs.bytes(32)\nconst RoutesStruct = bcs.struct('Routes', {\n routes_list: bcs.map(bcs.string(), bcs.string())\n})\nconst DynamicFieldStruct = bcs.struct('DynamicField', {\n parentId: Address,\n name: bcs.vector(bcs.u8()),\n value: RoutesStruct\n})\n\n/** The name of the dynamic field containing the routes (matches ROUTES_FIELD in site.move) */\nconst ROUTES_FIELD = new TextEncoder().encode('routes')\n\nexport class SiteService {\n #suiClient: SuiClient\n #chainSrv: ChainService\n\n constructor(suiClient: SuiClient) {\n this.#suiClient = suiClient\n this.#chainSrv = new ChainService(suiClient)\n }\n\n /**\n * Calculate the diff between provided files and existing on-chain site data.\n *\n * @param files - The IAsset array containing files to be deployed\n * @param wsResources - The Walrus Site resources metadata (routes, headers, etc.)\n * @param siteId - The existing site ID to compare against. If undefined, all files are treated as new.\n * @returns The computed site data diff\n */\n async calculateSiteDiff(\n files: IAsset[],\n wsResources: WSResources\n ): Promise<SiteDataDiff> {\n log('๐ Calculating site diff...')\n\n // Build the next site data from provided files\n const nextSiteData = await this.#buildSiteDataFromFiles(files, wsResources)\n log(\n '๐ Built next site data with',\n nextSiteData.resources.length,\n 'resources',\n nextSiteData\n )\n\n // If no siteId, treat as new site (compare against empty site)\n if (!wsResources.object_id) {\n log('๐ No existing site ID, treating all resources as new')\n const emptySiteData: SiteData = { resources: [] }\n return computeSiteDataDiff(nextSiteData, emptySiteData)\n }\n\n // Fetch existing site data from chain\n log('๐ Fetching existing site data for:', wsResources.object_id)\n const existingSiteData = await this.getSiteDataFromChain(\n wsResources.object_id\n )\n log(\n '๐ฅ Fetched existing site with',\n existingSiteData.resources.length,\n 'resources:',\n existingSiteData\n )\n\n return computeSiteDataDiff(nextSiteData, existingSiteData)\n }\n\n async getSiteDataFromChain(siteId: string): Promise<SiteData> {\n // Fetch site object and display data\n const objRes = await this.#suiClient.getObject({\n id: siteId,\n options: { showDisplay: true }\n })\n\n const error = objRes.data?.display?.error ?? objRes.error\n if (error) handleSuiClientError(error)\n\n const data = objRes.data?.display?.data\n if (!data) throw new Error('No data returned for Walrus site')\n const siteData = data as unknown as WalrusSiteDisplayData\n\n // Fetch resources and routes in parallel\n const [resources, routes] = await Promise.all([\n this.#fetchSiteResources(siteId),\n this.#fetchSiteRoutes(siteId)\n ])\n\n return {\n site_name: siteData.name,\n metadata: siteData,\n resources,\n routes\n }\n }\n\n /**\n * Build SiteData from WalrusFile array.\n *\n * This method:\n * 1. Builds resources from files\n * 2. Validates that provided routes point to existing resource paths\n * 3. Generates default routes if none are provided\n */\n async #buildSiteDataFromFiles(\n files: IAsset[],\n wsResources: WSResources\n ): Promise<SiteData> {\n const resources: SuiResource[] = []\n\n for (const file of files) {\n const { path, hashU256 } = file\n const resource: SuiResource = {\n path,\n blob_id: '<pending>', // Will be filled after upload\n blob_hash: hashU256.toString(),\n headers: wsResources.headers ?? [\n { key: 'content-encoding', value: 'identity' },\n { key: 'content-type', value: contentTypeFromFilePath(path) }\n ]\n }\n resources.push(resource)\n }\n\n // Build a set of all resource paths for validation\n const resourcePaths = new Set(resources.map(r => r.path))\n\n // Validate and process routes\n const routes = this.#processRoutes(wsResources.routes, resourcePaths)\n\n return {\n resources,\n routes,\n site_name: wsResources.site_name,\n metadata: wsResources.metadata\n }\n }\n\n /**\n * Process routes: validate provided routes\n *\n * Routes map a route path (e.g., \"/path1\") to a resource path (e.g., \"/index.html\").\n * The Move contract validates that the resource path exists when inserting a route.\n *\n * @param providedRoutes - Routes provided via wsResources\n * @param resourcePaths - Set of all resource paths in the site\n * @returns Validated routes\n * @throws Error if any route points to a non-existent resource path\n */\n #processRoutes(\n providedRoutes: Routes | undefined,\n resourcePaths: Set<string>\n ): Routes | undefined {\n // If routes are provided, validate them\n if (providedRoutes && providedRoutes.length > 0) {\n const invalidRoutes: Array<{ route: string; target: string }> = []\n\n for (const [routePath, resourcePath] of providedRoutes) {\n // Check if the target resource path exists\n if (!resourcePaths.has(resourcePath)) {\n invalidRoutes.push({ route: routePath, target: resourcePath })\n }\n }\n\n if (invalidRoutes.length > 0) {\n const invalidList = invalidRoutes\n .map(\n r => ` - Route \"${r.route}\" -> \"${r.target}\" (resource not found)`\n )\n .join('\\n')\n throw new Error(\n `Invalid routes: the following routes point to non-existent resources:\\n${invalidList}\\n` +\n `Available resource paths: ${Array.from(resourcePaths).join(', ')}`\n )\n }\n\n log('โ
Validated', providedRoutes.length, 'routes')\n return providedRoutes\n }\n }\n\n /**\n * Fetch routes from the site's Routes dynamic field.\n * Routes are stored as a dynamic field with name `b\"routes\"` (vector<u8>).\n */\n async #fetchSiteRoutes(siteId: string): Promise<Routes | undefined> {\n log('๐ค๏ธ Fetching routes for site:', siteId)\n\n // Derive the dynamic field ID for the routes field\n const routesMoveType = 'vector<u8>'\n const dynamicFieldId = deriveDynamicFieldID(\n siteId,\n routesMoveType,\n bcs.vector(bcs.u8()).serialize(ROUTES_FIELD).toBytes()\n )\n\n log('๐ Routes dynamic field ID:', dynamicFieldId)\n\n const routesObj = await this.#suiClient.getObject({\n id: dynamicFieldId,\n options: { showBcs: true }\n })\n\n const objectData = routesObj.data\n if (\n !objectData ||\n !objectData.bcs ||\n objectData.bcs.dataType !== 'moveObject'\n ) {\n log('โน๏ธ No routes dynamic field found for site')\n return undefined\n }\n\n // Parse the BCS data to extract routes\n const parsed = DynamicFieldStruct.parse(fromBase64(objectData.bcs.bcsBytes))\n const routesList = parsed.value.routes_list\n\n // Convert Map to array of tuples (our Routes type)\n const routes: Routes = Array.from(routesList.entries())\n log('โ
Fetched', routes.length, 'routes from chain')\n\n return routes.length > 0 ? routes : undefined\n }\n\n async #fetchSiteResources(siteId: string): Promise<SuiResource[]> {\n const network = this.#suiClient.network\n if (!isSupportedNetwork(network))\n throw new Error(`Unsupported network: ${network}`)\n\n const packageId = mainPackage[network].packageId\n const dynamicFields = await this.#chainSrv.fetchSiteDynamicFields(siteId)\n const resourcePaths = dynamicFields\n .filter(f => f.objectType === `${packageId}::site::Resource`)\n .filter(r => r.name.type === `${packageId}::site::ResourcePath`)\n\n // Fetch resource details\n const resources: SuiResource[] = []\n for (const rp of resourcePaths) {\n const content = await this.#suiClient\n .getObject({ id: rp.objectId, options: { showContent: true } })\n .then(res => res.data?.content)\n\n if (!content || content?.dataType !== 'moveObject')\n throw new Error('Invalid resource object data type')\n\n const fields = content.fields\n if (Array.isArray(fields))\n throw new Error('Invalid resource object fields')\n if (!('value' in fields))\n throw new Error('Invalid resource object fields value')\n\n const { fields: resourceFields } = fields.value as ResourceChainValue\n const result: SuiResource = {\n blob_hash: resourceFields.blob_hash,\n blob_id: resourceFields.blob_id,\n headers: resourceFields.headers.fields.contents.map(c => c.fields),\n path: resourceFields.path\n }\n resources.push(result)\n }\n return resources\n }\n}\n","import type { SuiClient, SuiTransactionBlockResponse } from '@mysten/sui/client'\nimport type { Transaction } from '@mysten/sui/transactions'\nimport { toBase64 } from '@mysten/sui/utils'\nimport debug from 'debug'\nimport type {\n ISignAndExecuteTransaction,\n ISponsorConfig,\n ITransaction\n} from '../types'\n\nconst log = debug('site-builder:transaction-executor')\n\nexport interface TransactionExecutorOptions {\n suiClient: SuiClient\n walletAddress: string\n signAndExecuteTransaction: ISignAndExecuteTransaction\n sponsorConfig?: ISponsorConfig\n}\n\nexport interface ExecuteTransactionOptions {\n transaction: Transaction\n description: string\n /**\n * Callback to record transaction history\n */\n onTransactionRecorded?: (transaction: ITransaction) => void\n}\n\n/**\n * Service for executing transactions with optional sponsor support.\n * Centralizes transaction execution logic to avoid code duplication.\n */\nexport class TransactionExecutorService {\n constructor(private options: TransactionExecutorOptions) {}\n\n /**\n * Execute a transaction with automatic sponsor detection.\n * Returns the transaction digest.\n */\n async execute({\n transaction,\n description,\n onTransactionRecorded\n }: ExecuteTransactionOptions): Promise<string> {\n const digest = this.options.sponsorConfig\n ? await this.#executeSponsoredTransaction(transaction, description)\n : await this.#executeRegularTransaction(transaction, description)\n\n onTransactionRecorded?.({\n digest,\n description,\n timestamp: Date.now()\n })\n\n return digest\n }\n\n /**\n * Execute a transaction and return the full response.\n * Useful when you need to extract data from the response.\n */\n async executeWithResponse({\n transaction,\n description,\n onTransactionRecorded\n }: ExecuteTransactionOptions): Promise<SuiTransactionBlockResponse> {\n let response: SuiTransactionBlockResponse\n\n if (this.options.sponsorConfig) {\n const digest = await this.#executeSponsoredTransaction(\n transaction,\n description\n )\n response = await this.options.suiClient.waitForTransaction({\n digest,\n options: {\n showEffects: true,\n showObjectChanges: true\n }\n })\n } else {\n response = await this.options.signAndExecuteTransaction({ transaction })\n }\n\n onTransactionRecorded?.({\n digest: response.digest,\n description,\n timestamp: Date.now()\n })\n\n return response\n }\n\n /**\n * Check if sponsor is enabled\n */\n get isSponsorEnabled(): boolean {\n return !!this.options.sponsorConfig\n }\n\n /**\n * Handle sponsored transaction execution.\n */\n async #executeSponsoredTransaction(\n transaction: Transaction,\n description: string\n ): Promise<string> {\n const { sponsorConfig, walletAddress, suiClient } = this.options\n\n if (!sponsorConfig?.apiClient) {\n throw new Error('Sponsor config not available')\n }\n\n log(`๐ซ Executing sponsored transaction: ${description}`)\n\n // Step 1: Set sender\n transaction.setSenderIfNotSet(walletAddress)\n\n // Step 2: Build transaction bytes\n const txBytes = await transaction.build({\n client: suiClient,\n onlyTransactionKind: true\n })\n\n // Step 3: Request sponsorship\n const { bytes, digest: sponsorDigest } =\n await sponsorConfig.apiClient.sponsorTransaction({\n txBytes: toBase64(txBytes),\n sender: walletAddress\n })\n log(`โ
Transaction sponsored with digest: ${sponsorDigest}`)\n\n // Step 4: Sign the sponsored transaction\n const { signature } = await sponsorConfig.signTransaction({\n transaction: bytes\n })\n if (!signature) {\n throw new Error(\n 'Failed to sign sponsored transaction: No signature returned'\n )\n }\n\n // Step 5: Execute the sponsored transaction\n const { digest: executeDigest } =\n await sponsorConfig.apiClient.executeTransaction({\n digest: sponsorDigest,\n signature: signature\n })\n log(`โ
Sponsored transaction executed: ${executeDigest}`)\n\n return executeDigest\n }\n\n /**\n * Handle regular (non-sponsored) transaction execution.\n */\n async #executeRegularTransaction(\n transaction: Transaction,\n description: string\n ): Promise<string> {\n log(`๐ Executing regular transaction: ${description}`)\n const { digest } = await this.options.signAndExecuteTransaction({\n transaction\n })\n log(`โ
Regular transaction executed: ${digest}`)\n return digest\n }\n}\n","import type { SuiClient } from '@mysten/sui/client'\nimport type { Transaction } from '@mysten/sui/transactions'\nimport {\n type WalrusClient,\n WalrusFile,\n type WriteFilesFlow\n} from '@mysten/walrus'\nimport debug from 'debug'\nimport { mainPackage } from './lib/constants'\nimport { QUILT_PATCH_ID_INTERNAL_HEADER } from './lib/internal-constants'\nimport { getSiteIdFromResponse } from './lib/onchain-data-helpers'\nimport { extractPatchHex } from './lib/path-id'\nimport { hasUpdate } from './lib/site-data.utils'\nimport { buildSiteCreationTx } from './lib/tx-builder'\nimport { blobIdBase64ToU256, isSupportedNetwork } from './lib/utils'\nimport { fetchBlobsPatches } from './queries/blobs-patches.query'\nimport { SiteService } from './services/site.service'\nimport { TransactionExecutorService } from './services/transaction-executor.service'\nimport type {\n IAsset,\n ICertifiedBlob,\n ISignAndExecuteTransaction,\n ISponsorConfig,\n ITransaction,\n IUpdateWalrusSiteFlow,\n SiteDataDiff,\n WSResources\n} from './types'\n\nconst log = debug('site-builder:deploy-flow')\n\ninterface IState {\n siteUpdates?: SiteDataDiff\n writeFilesFlow?: WriteFilesFlow\n transactions: ITransaction[]\n}\n\n/**\n * Represents the deployment flow for a Walrus site.\n *\n * When the transactions to upload a blob are signed by a wallet in a browser,\n * some wallets will use popups to prompt the user for a signature. If the\n * popups are not opened in direct response to a user interaction,\n * they may be blocked by the browser.\n *\n * To avoid this, we need to ensure that we execute the transactions that\n * register and certify the blob in separate events handlers by creating\n * separate buttons for the user to click for each step.\n */\nexport class UpdateWalrusSiteFlow implements IUpdateWalrusSiteFlow {\n private state: IState = { transactions: [] }\n private siteSvc: SiteService\n private txExecutor: TransactionExecutorService\n\n constructor(\n /**\n * The Walrus client used for interacting with the Walrus API.\n */\n private walrus: WalrusClient,\n /**\n * The Sui client used for interacting with the Sui API.\n */\n private suiClient: SuiClient,\n /**\n * The site's assets to be deployed.\n */\n private assets: IAsset[],\n /**\n * The Walrus Site resources information.\n */\n private wsResource: WSResources,\n /**\n * The function used to sign and execute transactions.\n *\n * Get by calling `useSignAndExecuteTransaction` hook in `'@mysten/dapp-kit'`.\n *\n * ```ts\n * const { mutateAsync: signAndExecuteTransaction } =\n * useSignAndExecuteTransaction({\n * execute: async ({ bytes, signature }) =>\n * await suiClient.executeTransactionBlock({\n * transactionBlock: bytes,\n * signature,\n * options: {\n * // Raw effects are required so the effects can be reported back to the wallet\n * showRawEffects: true,\n * // Select additional data to return\n * showObjectChanges: true\n * }\n * })\n * })\n * ```\n */\n private signAndExecuteTransaction: ISignAndExecuteTransaction,\n /**\n * The sponsor configuration for handling sponsored transactions.\n */\n private sponsorConfig: ISponsorConfig | undefined,\n /**\n * The active wallet address.\n */\n private walletAddr: string\n ) {\n this.siteSvc = new SiteService(this.suiClient)\n this.txExecutor = new TransactionExecutorService({\n suiClient: this.suiClient,\n walletAddress: this.walletAddr,\n signAndExecuteTransaction: this.signAndExecuteTransaction,\n sponsorConfig: this.sponsorConfig\n })\n\n // Bind methods\n for (const method of [\n 'prepareResources',\n 'writeResources',\n 'certifyResources',\n 'writeSite'\n ] satisfies (keyof UpdateWalrusSiteFlow)[]) {\n // biome-ignore lint/suspicious/noExplicitAny: no issue\n this[method] = this[method].bind(this) as any\n }\n }\n\n async prepareResources(): Promise<SiteDataDiff> {\n log('๐ Calculating site diff...')\n const diff = await this.siteSvc.calculateSiteDiff(\n this.assets,\n this.wsResource\n )\n log('โ
Site diff calculated:', diff)\n this.state.siteUpdates = diff\n\n if (!diff.resources.some(r => r.op === 'created')) {\n log('โญ๏ธ No new resources detected, skipping upload entirely...')\n return diff\n }\n\n // Step 1: Prepare the files for upload (including unchanged files that are needed)\n const flow = this.walrus.writeFilesFlow({\n files: this.assets.map(f =>\n WalrusFile.from({ identifier: f.path, contents: f.content })\n )\n })\n this.state.writeFilesFlow = flow\n\n log('๐ฆ Getting', this.assets.length, 'files ready for upload...')\n await this.state.writeFilesFlow.encode()\n log('โ
Files prepared successfully')\n return diff\n }\n\n async writeResources(\n epochs: number | 'max',\n permanent = false\n ): Promise<void> {\n log('๐ Starting asset upload...')\n const { writeFilesFlow } = this.state\n if (!writeFilesFlow) throw new Error('Must prepare resources first')\n\n // Step 2: Register the blob (triggered by user clicking a register button after the encode step)\n log('๐ Registering blob on chain...', { epochs, permanent })\n const tx = writeFilesFlow.register({\n deletable: !permanent,\n epochs: epochs === 'max' ? 57 : epochs,\n owner: this.walletAddr\n })\n\n const digest = await this.txExecutor.execute({\n transaction: tx,\n description: 'Register blob on Walrus network',\n onTransactionRecorded: this.#recordTransaction.bind(this)\n })\n\n // Step 3: Upload the data to storage nodes\n // This can be done immediately after the register step, or as a separate step the user initiates\n log('โ๏ธ Uploading data to storage nodes...')\n await writeFilesFlow.upload({ digest })\n log('โ
Data uploaded successfully')\n }\n\n async certifyResources(): Promise<void> {\n log('๐ Starting asset certification...')\n const { writeFilesFlow } = this.state\n if (!writeFilesFlow) throw new Error('Write files flow not initialized')\n\n const certifyTx = writeFilesFlow.certify()\n\n await this.txExecutor.execute({\n transaction: certifyTx,\n description: 'Certify blob storage',\n onTransactionRecorded: this.#recordTransaction.bind(this)\n })\n\n log('โ
Assets certified successfully')\n await this.#fetchAndUpdateBlobPatches()\n }\n\n /** Fetches patches for certified blobs and updates the site data accordingly */\n async #fetchAndUpdateBlobPatches() {\n const certifiedFiles = await this.state.writeFilesFlow?.listFiles()\n if (!certifiedFiles?.length) throw new Error('No certified files found')\n log('๐ Certified files:', certifiedFiles)\n\n const uniqueBlobIds = Array.from(new Set(certifiedFiles.map(f => f.blobId)))\n log('๐ Fetching patches for blob IDs:', uniqueBlobIds)\n const patches = await fetchBlobsPatches(\n uniqueBlobIds,\n this.suiClient.network\n )\n log('๐งฉ Fetched patches:', patches)\n\n const fileIdentifierByPatchId = new Map(\n patches.map(p => [p.patch_id, p.identifier])\n )\n const hashByBlobId = new Map(\n this.state.siteUpdates?.resources\n .filter(a => a.op === 'created')\n .map(a => [a.data.path, a.data.blob_hash]) || []\n )\n\n const blobs: Array<ICertifiedBlob> = certifiedFiles.map(\n (file): ICertifiedBlob => ({\n patchId: file.id,\n blobId: file.blobId,\n suiObjectId: file.blobObject.id.id,\n endEpoch: file.blobObject.storage.end_epoch,\n identifier: fileIdentifierByPatchId.get(file.id) || 'unknown',\n blobHash:\n hashByBlobId.get(fileIdentifierByPatchId.get(file.id) || '') ?? ''\n })\n )\n log('โ
Certified blobs:', blobs)\n\n log('๐ Updating site data with certified files...')\n const patchIdByPath = new Map(blobs.map(b => [b.identifier, b.patchId]))\n const blobIdByPath = new Map(blobs.map(b => [b.identifier, b.blobId]))\n this.state.siteUpdates?.resources.forEach(r => {\n if (r.op !== 'created') return\n const patchId = patchIdByPath.get(r.data.path)\n const blobId = blobIdByPath.get(r.data.path)\n if (!patchId) {\n log(`Blob ID for ${r.data.path} not found`)\n return\n }\n if (!blobId) {\n log(`Blob ID for ${r.data.path} not found`)\n return\n }\n r.data.blob_id = blobIdBase64ToU256(blobId).toString()\n r.data.headers.push({\n key: QUILT_PATCH_ID_INTERNAL_HEADER,\n value: extractPatchHex(patchId)\n })\n })\n log(\n 'โ
Updated state SiteData with certified files',\n this.state.siteUpdates\n )\n }\n\n async writeSite(): Promise<{ siteId: string }> {\n const { siteUpdates } = this.state\n if (!hasUpdate(siteUpdates)) {\n if (!this.wsResource.object_id) throw new Error('No data to create site')\n log('โญ๏ธ No site updates to apply')\n return { siteId: this.wsResource.object_id }\n }\n log('๐ Starting site update...')\n\n const tx = this.#createSiteUpdateTransaction({\n siteId: this.wsResource.object_id,\n siteUpdates,\n ownerAddr: this.walletAddr\n })\n\n const res = await this.txExecutor.executeWithResponse({\n transaction: tx,\n description: 'Update Walrus site metadata',\n onTransactionRecorded: this.#recordTransaction.bind(this)\n })\n\n console.log('๐ Transaction response:', res)\n\n if (this.wsResource.object_id) {\n log('โ
Site updated successfully', res)\n return { siteId: this.wsResource.object_id }\n }\n\n const siteId = getSiteIdFromResponse(this.walletAddr, res)\n if (!siteId) throw new Error('Could not find site ID from response')\n log('โ
Created new Walrus site with ID:', siteId)\n this.wsResource.object_id = siteId\n return { siteId }\n }\n\n getTransactions(): ITransaction[] {\n return this.state.transactions\n }\n\n /**\n * Record a transaction with its description.\n */\n #recordTransaction(transaction: ITransaction): void {\n if (!this.state.transactions) {\n this.state.transactions = []\n }\n this.state.transactions.push(transaction)\n }\n\n /**\n * Create transaction to update a Walrus Site\n */\n #createSiteUpdateTransaction({\n ownerAddr,\n siteUpdates,\n siteId\n }: {\n siteId: string | undefined\n siteUpdates: SiteDataDiff\n ownerAddr: string\n }): Transaction {\n log('โก๏ธ Creating site update transaction')\n\n const network = this.suiClient.network\n if (!isSupportedNetwork(network))\n throw new Error(`Unsupported network: ${network}`)\n const packageId = mainPackage[network].packageId\n\n return buildSiteCreationTx(siteId, siteUpdates, packageId, ownerAddr)\n }\n}\n","import type { SuiClient } from '@mysten/sui/client'\nimport type { WalrusClient } from '@mysten/walrus'\nimport debug from 'debug'\nimport { UpdateWalrusSiteFlow } from './deploy-flow'\nimport { isSupportedNetwork, mainPackage } from './lib'\nimport { buildSiteCreationTx } from './lib/tx-builder'\nimport { TransactionExecutorService } from './services'\nimport { SiteService } from './services/site.service'\nimport type {\n IAsset,\n ISignAndExecuteTransaction,\n ISponsorConfig,\n IUpdateWalrusSiteFlow,\n IWalrusSiteBuilderSdk,\n WSResources\n} from './types'\n\nconst log = debug('site-builder:sdk')\n\n/**\n * SDK for publishing Walrus Sites.\n */\nexport class WalrusSiteBuilderSdk implements IWalrusSiteBuilderSdk {\n private txExecutor: TransactionExecutorService\n\n constructor(\n /**\n * The Walrus client used for interacting with the Walrus API.\n */\n public walrus: WalrusClient,\n /**\n * The Sui client used for interacting with the Sui API.\n */\n public suiClient: SuiClient,\n /**\n * The active wallet account.\n */\n public walletAddr: string,\n /**\n * The function used to sign and execute transactions.\n *\n * Get by calling `useSignAndExecuteTransaction` hook in `'@mysten/dapp-kit'`.\n *\n * ```ts\n * const { mutateAsync: signAndExecuteTransaction } =\n * useSignAndExecuteTransaction({\n * execute: async ({ bytes, signature }) =>\n * await suiClient.executeTransactionBlock({\n * transactionBlock: bytes,\n * signature,\n * options: {\n * // Raw effects are required so the effects can be reported back to the wallet\n * showRawEffects: true,\n * // Select additional data to return\n * showObjectChanges: true\n * }\n * })\n * })\n * ```\n */\n public signAndExecuteTransaction: ISignAndExecuteTransaction,\n /**\n * The function used to sign transactions.\n */\n public sponsorConfig?: ISponsorConfig\n ) {\n this.txExecutor = new TransactionExecutorService({\n suiClient,\n walletAddress: this.walletAddr,\n signAndExecuteTransaction,\n sponsorConfig\n })\n }\n\n /**\n * Create a deploy flow for deploying a Walrus Site.\n */\n executeSiteUpdateFlow(\n assets: IAsset[],\n wsResource: WSResources\n ): IUpdateWalrusSiteFlow {\n return new UpdateWalrusSiteFlow(\n this.walrus,\n this.suiClient,\n assets,\n wsResource,\n this.signAndExecuteTransaction,\n this.sponsorConfig,\n this.walletAddr\n )\n }\n\n async updateSiteMetadata(\n siteId: string,\n siteName: string,\n metadata: WSResources['metadata']\n ): Promise<string> {\n const siteSvc = new SiteService(this.suiClient)\n const siteUpdates = await siteSvc.calculateSiteDiff([], {\n object_id: siteId,\n site_name: siteName,\n metadata\n })\n\n log('๐ Starting site update...')\n\n const network = this.suiClient.network\n if (!isSupportedNetwork(network))\n throw new Error(`Unsupported network: ${network}`)\n const packageId = mainPackage[network].packageId\n\n const tx = buildSiteCreationTx(\n siteId,\n siteUpdates,\n packageId,\n this.walletAddr\n )\n\n const res = await this.txExecutor.executeWithResponse({\n transaction: tx,\n description: 'Update Walrus site metadata'\n })\n\n console.log('๐ Transaction response:', res)\n return res.digest\n }\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cmdoss/walrus-site-builder",
|
|
3
|
+
"version": "2.2.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public",
|
|
10
|
+
"tag": "latest"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"peerDependencies": {
|
|
16
|
+
"@mysten/sui": "^1.45.2",
|
|
17
|
+
"@mysten/wallet-standard": "^0.19.9",
|
|
18
|
+
"@mysten/walrus": "^0.9.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/debug": "^4.1.12",
|
|
22
|
+
"@types/node": "^22.19.3",
|
|
23
|
+
"tsdown": "^0.18.2"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"debug": "^4.4.3"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"dev": "tsdown --platform browser --watch --ignore-watch .turbo",
|
|
30
|
+
"test": "node --test",
|
|
31
|
+
"test:watch": "node --test --watch",
|
|
32
|
+
"test:coverage": "node --test --experimental-test-coverage --test-coverage-exclude='src/**/*.test.ts'",
|
|
33
|
+
"check:types": "tsc --noEmit",
|
|
34
|
+
"build": "tsdown --platform browser --minify"
|
|
35
|
+
}
|
|
36
|
+
}
|