calldatauploader-sdk 0.0.0-stage → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +207 -2
- package/package.json +62 -6
- package/spec.md +325 -0
- package/src/flatdirectory.ts +648 -0
- package/src/index.ts +3 -0
- package/src/node/file.ts +70 -0
- package/src/param/abi.ts +17 -0
- package/src/param/bytecode.ts +18 -0
- package/src/param/constant.ts +76 -0
- package/src/param/index.ts +4 -0
- package/src/param/type.ts +114 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/retry.ts +133 -0
- package/src/utils/uploader.ts +108 -0
- package/src/utils/util.ts +50 -0
- package/src/utils/web3.ts +41 -0
- package/test.js +119 -0
- package/tsconfig.json +110 -0
- package/tsup.config.ts +55 -0
package/README.md
CHANGED
|
@@ -1,3 +1,208 @@
|
|
|
1
|
-
#
|
|
1
|
+
# calldatauploader-sdk
|
|
2
2
|
|
|
3
|
-
This
|
|
3
|
+
This SDK aims to standardize the interaction between applications and the EthStorage network to achieve reliable and
|
|
4
|
+
efficient data management functionality.
|
|
5
|
+
|
|
6
|
+
This SDK provides the `FlatDirectory` class, a higher-level data management tool that provides methods for uploading
|
|
7
|
+
and downloading data of arbitrary size. Uploads are performed by sending the data through calldata.
|
|
8
|
+
|
|
9
|
+
Click here to view [spec](./spec.md).
|
|
10
|
+
|
|
11
|
+
# Installation
|
|
12
|
+
|
|
13
|
+
Install the SDK using [npm](https://www.npmjs.com/package/calldatauploader-sdk):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
$ npm install calldatauploader-sdk
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
# Example Usage
|
|
20
|
+
|
|
21
|
+
## FlatDirectory
|
|
22
|
+
|
|
23
|
+
### create
|
|
24
|
+
|
|
25
|
+
Create a `FlatDirectory` instance.
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
const { FlatDirectory } = require("calldatauploader-sdk");
|
|
29
|
+
|
|
30
|
+
const rpc = "https://rpc.beta.testnet.l2.quarkchain.io:8545";
|
|
31
|
+
const ethStorageRpc = "https://rpc.beta.testnet.l2.ethstorage.io:9596";
|
|
32
|
+
const privateKey = "0xabcd...";
|
|
33
|
+
|
|
34
|
+
const flatDirectory = await FlatDirectory.create({
|
|
35
|
+
rpc: rpc,
|
|
36
|
+
ethStorageRpc: ethStorageRpc,
|
|
37
|
+
privateKey: privateKey,
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If `FlatDirectory` has been deployed, it can be set through the `address` field.
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
const address = "0x987..."; // FlatDirectory address
|
|
45
|
+
const flatDirectory = await FlatDirectory.create({
|
|
46
|
+
rpc: rpc,
|
|
47
|
+
ethStorageRpc: ethStorageRpc,
|
|
48
|
+
privateKey: privateKey,
|
|
49
|
+
address: address,
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
If you only need the `download` function, you can create a `FlatDirectory` using the following pattern.
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
const address = "0x987..."; // FlatDirectory address
|
|
57
|
+
const flatDirectory = await FlatDirectory.create({
|
|
58
|
+
ethStorageRpc: 'https://rpc.beta.testnet.l2.ethstorage.io:9596',
|
|
59
|
+
address: address
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### deploy
|
|
64
|
+
|
|
65
|
+
Deploy the implementation
|
|
66
|
+
contract [FlatDirectory](https://github.com/ethstorage/evm-large-storage)
|
|
67
|
+
for [EIP-5018](https://eips.ethereum.org/EIPS/eip-5018) standard.
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
const contractAddress = await flatDirectory.deploy();
|
|
71
|
+
console.log(`FlatDirectory address is ${contractAddress}.`);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### upload
|
|
75
|
+
|
|
76
|
+
Upload `buffer | file` to the FlatDirectory. The content is sliced into chunks and each chunk is sent through calldata.
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
const callback = {
|
|
80
|
+
onProgress: function (progress, count, isChange) {
|
|
81
|
+
console.log(`Uploaded ${progress} of ${count} chunks`);
|
|
82
|
+
},
|
|
83
|
+
onFail: function (err) {
|
|
84
|
+
console.log(err);
|
|
85
|
+
},
|
|
86
|
+
onFinish: function (totalUploadChunks, totalUploadSize, totalCost) {
|
|
87
|
+
console.log(`Total upload chunk count is ${totalUploadChunks}, size is ${totalUploadSize}, total cost is ${totalCost}`);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const request = {
|
|
92
|
+
key: "test.txt",
|
|
93
|
+
content: Buffer.from("big data"),
|
|
94
|
+
callback: callback
|
|
95
|
+
}
|
|
96
|
+
await flatDirectory.upload(request);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
If you want to use `file`, it can be divided into browser and Node.js.
|
|
100
|
+
|
|
101
|
+
Browser
|
|
102
|
+
```javascript
|
|
103
|
+
// <input id='fileToUpload' />
|
|
104
|
+
const file = document.getElementById('fileToUpload').files[0];
|
|
105
|
+
|
|
106
|
+
const request = {
|
|
107
|
+
key: "test.txt",
|
|
108
|
+
content: file,
|
|
109
|
+
callback: callback
|
|
110
|
+
}
|
|
111
|
+
await flatDirectory.upload(request);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Node.js
|
|
115
|
+
```javascript
|
|
116
|
+
const {NodeFile} = require("calldatauploader-sdk/file");
|
|
117
|
+
const file = new NodeFile("/usr/download/test.jpg");
|
|
118
|
+
|
|
119
|
+
const request = {
|
|
120
|
+
key: "test.txt",
|
|
121
|
+
content: file,
|
|
122
|
+
callback: callback
|
|
123
|
+
}
|
|
124
|
+
await flatDirectory.upload(request);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### download
|
|
128
|
+
|
|
129
|
+
Monitor the download progress by passing in a callback function.
|
|
130
|
+
|
|
131
|
+
```js
|
|
132
|
+
const key = "test.txt";
|
|
133
|
+
await flatDirectory.download(key, {
|
|
134
|
+
onProgress: function (progress, count, chunk) {
|
|
135
|
+
console.log(`Download ${progress} of ${count} chunks, this chunk is ${Buffer.from(chunk).toString()}`);
|
|
136
|
+
},
|
|
137
|
+
onFail: function (error) {
|
|
138
|
+
console.error("Error download data:", error);
|
|
139
|
+
},
|
|
140
|
+
onFinish: function () {
|
|
141
|
+
console.log("Download success.");
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### estimateCost
|
|
147
|
+
|
|
148
|
+
Estimate gas costs before uploading.
|
|
149
|
+
|
|
150
|
+
```js
|
|
151
|
+
const request = {
|
|
152
|
+
key: "example1.txt",
|
|
153
|
+
content: Buffer.from("large data to upload")
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const cost = await flatDirectory.estimateCost(request);
|
|
157
|
+
console.log(`Gas Cost: ${cost.gasCost}, Storage Cost: ${cost.storageCost}`);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Use `file`.
|
|
161
|
+
|
|
162
|
+
Browser
|
|
163
|
+
```javascript
|
|
164
|
+
// <input id='fileToUpload' />
|
|
165
|
+
const file = document.getElementById('fileToUpload').files[0];
|
|
166
|
+
|
|
167
|
+
const request = {
|
|
168
|
+
key: "example1.txt",
|
|
169
|
+
content: file
|
|
170
|
+
}
|
|
171
|
+
const cost = await flatDirectory.estimateCost(request);
|
|
172
|
+
console.log(`Gas Cost: ${cost.gasCost}, Storage Cost: ${cost.storageCost}`);
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Node.js
|
|
176
|
+
```javascript
|
|
177
|
+
const {NodeFile} = require("calldatauploader-sdk/file");
|
|
178
|
+
const file = new NodeFile("/usr/download/test.jpg");
|
|
179
|
+
|
|
180
|
+
const request = {
|
|
181
|
+
key: "example1.txt",
|
|
182
|
+
content: file
|
|
183
|
+
}
|
|
184
|
+
const cost = await flatDirectory.estimateCost(request);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
### Chunk options
|
|
189
|
+
|
|
190
|
+
Uploads are sliced into calldata chunks. Both `estimateCost` and `upload`
|
|
191
|
+
requests accept two optional fields:
|
|
192
|
+
|
|
193
|
+
| Field | Type | Default | Description |
|
|
194
|
+
|----------------|--------|---------|----------------------------------------------------------|
|
|
195
|
+
| `maxChunkSize` | number | `64` | data size of each chunk, in KB |
|
|
196
|
+
| `maxChunks` | number | `100` | maximum number of chunks requested in a single call |
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
const request = {
|
|
200
|
+
key: "example1.txt",
|
|
201
|
+
content: Buffer.from("large data to upload"),
|
|
202
|
+
maxChunkSize: 32, // 32 KB per chunk
|
|
203
|
+
maxChunks: 120 // at most 120 chunks per request
|
|
204
|
+
}
|
|
205
|
+
await flatDirectory.upload({ ...request, callback });
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
`fetchHashes(keys, maxChunks)` accepts the same chunk limit as its second argument.
|
package/package.json
CHANGED
|
@@ -1,6 +1,62 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "calldatauploader-sdk",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "calldatauploader-sdk",
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"description": "EthStorage flat directory upload sdk (calldata only)",
|
|
5
|
+
"main": "./dist/node/index.cjs",
|
|
6
|
+
"types": "./dist/node/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"browser": "./dist/browser/index.mjs",
|
|
10
|
+
"node": {
|
|
11
|
+
"import": "./dist/node/index.mjs",
|
|
12
|
+
"require": "./dist/node/index.cjs"
|
|
13
|
+
},
|
|
14
|
+
"types": "./dist/node/index.d.ts",
|
|
15
|
+
"default": "./dist/node/index.mjs"
|
|
16
|
+
},
|
|
17
|
+
"./file": {
|
|
18
|
+
"node": {
|
|
19
|
+
"import": "./dist/node/file.mjs",
|
|
20
|
+
"require": "./dist/node/file.cjs"
|
|
21
|
+
},
|
|
22
|
+
"types": "./dist/node/file.d.ts"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsup",
|
|
27
|
+
"dev": "tsup --watch --env.NODE_ENV development",
|
|
28
|
+
"prepublishOnly": "npm run build"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"dotenv": "^16.4.5",
|
|
32
|
+
"ethers": "^6.17.0",
|
|
33
|
+
"p-limit": "^7.2.0"
|
|
34
|
+
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/0xCampanula/calldatauploader-sdk.git"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/0xCampanula/calldatauploader-sdk/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/0xCampanula/calldatauploader-sdk/main/",
|
|
43
|
+
"keywords": [
|
|
44
|
+
"File",
|
|
45
|
+
"Upload"
|
|
46
|
+
],
|
|
47
|
+
"author": "ethsorage",
|
|
48
|
+
"license": "ISC",
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"tsup": "^8.5.1",
|
|
51
|
+
"typescript": "^5.9.3"
|
|
52
|
+
},
|
|
53
|
+
"resolutions": {
|
|
54
|
+
"strip-ansi": "7.1.0",
|
|
55
|
+
"color-convert": "2.0.1",
|
|
56
|
+
"color-name": "1.1.4"
|
|
57
|
+
},
|
|
58
|
+
"overrides": {
|
|
59
|
+
"rollup": ">=4.59.0",
|
|
60
|
+
"picomatch": ">=4.0.4"
|
|
61
|
+
}
|
|
62
|
+
}
|
package/spec.md
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# EthStorage SDK Interface Specification
|
|
2
|
+
|
|
3
|
+
# Table of Contents
|
|
4
|
+
|
|
5
|
+
- [1. Introduction](#Introduction)
|
|
6
|
+
- [2. Class Overview](#Class_Overview)
|
|
7
|
+
- [3. FlatDirectory Class](#FlatDirectory)
|
|
8
|
+
- Static Methods
|
|
9
|
+
- create
|
|
10
|
+
- Methods
|
|
11
|
+
- deploy
|
|
12
|
+
- estimateCost
|
|
13
|
+
- upload
|
|
14
|
+
- download
|
|
15
|
+
- fetchHashes
|
|
16
|
+
- setDefault
|
|
17
|
+
- remove
|
|
18
|
+
- [4. Version History](#Version)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<p id="Introduction"></p>
|
|
23
|
+
|
|
24
|
+
# 1. Introduction
|
|
25
|
+
|
|
26
|
+
This SDK aims to standardize the interaction between applications and the EthStorage network to achieve reliable and
|
|
27
|
+
efficient data management functionality.
|
|
28
|
+
|
|
29
|
+
This SDK includes the `FlatDirectory` class, a higher-level data management tool that provides methods for uploading
|
|
30
|
+
and downloading data of arbitrary size. Uploading is performed by sending the data through calldata in fixed-size
|
|
31
|
+
chunks, and each chunk is written to the FlatDirectory contract with `writeChunkByCalldata`.
|
|
32
|
+
|
|
33
|
+
<p id="Class_Overview"></p>
|
|
34
|
+
|
|
35
|
+
# 2. Class Overview
|
|
36
|
+
|
|
37
|
+
## FlatDirectory Class
|
|
38
|
+
|
|
39
|
+
| Method Name | Description |
|
|
40
|
+
|--------------|----------------------------------------------------------------|
|
|
41
|
+
| create | Create an instance of FlatDirectory |
|
|
42
|
+
| deploy | Deploy a FlatDirectory contract |
|
|
43
|
+
| estimateCost | Estimate the cost of uploading data (gas cost) |
|
|
44
|
+
| upload | Asynchronously upload data of arbitrary size via calldata |
|
|
45
|
+
| download | Asynchronously download data |
|
|
46
|
+
| fetchHashes | Get chunk hashes of data in batches |
|
|
47
|
+
| setDefault | Set the default file for FlatDirectory |
|
|
48
|
+
| remove | Remove a file from the FlatDirectory contract |
|
|
49
|
+
|
|
50
|
+
<p id="FlatDirectory"></p>
|
|
51
|
+
|
|
52
|
+
# 3. FlatDirectory Class
|
|
53
|
+
|
|
54
|
+
## Static Methods
|
|
55
|
+
|
|
56
|
+
### create
|
|
57
|
+
|
|
58
|
+
**Description**: Create an instance of `FlatDirectory`.
|
|
59
|
+
|
|
60
|
+
**Parameters**
|
|
61
|
+
- `config` (object): Configuration object containing necessary settings.
|
|
62
|
+
- `rpc` (string, optional): RPC for any evm network. Required for operations that send transactions.
|
|
63
|
+
- `ethStorageRpc` (string, optional): The EthStorage network rpc corresponding to this evm network, the data is obtained from
|
|
64
|
+
the EthStorage network.
|
|
65
|
+
- `privateKey` (string, optional): Wallet private key. Required for operations that send transactions.
|
|
66
|
+
- `address` (string, optional): FlatDirectory contract address. If it does not exist, the `deploy` method can be
|
|
67
|
+
called to create one.
|
|
68
|
+
|
|
69
|
+
**Example**
|
|
70
|
+
```javascript
|
|
71
|
+
const config = {
|
|
72
|
+
rpc: "your_rpc",
|
|
73
|
+
ethStorageRpc: "ethstorage_rpc",
|
|
74
|
+
privateKey: "your_private_key",
|
|
75
|
+
address: "flat_directory_address"
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const flatDirectory = await FlatDirectory.create(config);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Methods
|
|
82
|
+
|
|
83
|
+
### deploy
|
|
84
|
+
|
|
85
|
+
**Description**: Deploy a FlatDirectory contract. If the `address` is not set when creating a `FlatDirectory`, you must
|
|
86
|
+
call deploy before other functions.
|
|
87
|
+
|
|
88
|
+
**Returns**
|
|
89
|
+
- `address` (Promise<string | null>): A Promise that resolves to the FlatDirectory address, or `null` on failure.
|
|
90
|
+
|
|
91
|
+
**Example**
|
|
92
|
+
```javascript
|
|
93
|
+
const address = await flatDirectory.deploy();
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### estimateCost
|
|
97
|
+
|
|
98
|
+
**Description**: Estimate the cost of uploading data|file through calldata.
|
|
99
|
+
|
|
100
|
+
**Parameters**
|
|
101
|
+
- `request` (object): Configuration of the upload object containing necessary settings.
|
|
102
|
+
- `key` (string): The key of the data.
|
|
103
|
+
- `content` (Buffer|File): The content to be uploaded, which can be either a Buffer or a File.
|
|
104
|
+
- `maxFeePerGas` (bigint, optional): Custom max fee per gas, in wei (EIP-1559). Defaults to `1.1 × latest-block base fee + maxPriorityFeePerGas` (i.e. `baseFee * 11 / 10`, base fee from the node).
|
|
105
|
+
- `maxPriorityFeePerGas` (bigint, optional): Custom max priority fee per gas, in wei (EIP-1559). Defaults to `100` wei.
|
|
106
|
+
- `gasPrice` (bigint, optional): Custom gas price, in wei (legacy chains without EIP-1559, e.g. BNB Chain). Defaults to the node-suggested gas price.
|
|
107
|
+
- `chunkHashes` (string[], optional): The chunk hashes corresponding to the content. If this parameter exists, no
|
|
108
|
+
request to retrieve the hashes will be triggered.
|
|
109
|
+
- `maxChunkSize` (number, optional): Size of each data chunk, in KB. Defaults to `DEFAULT_MAX_CHUNK_SIZE_KB` (64).
|
|
110
|
+
- `maxChunks` (number, optional): Maximum number of chunks requested in a single call. Defaults to `MAX_CHUNKS`.
|
|
111
|
+
|
|
112
|
+
**Returns**
|
|
113
|
+
- `cost` (`Promise<object>`): A Promise that resolves to an object containing:
|
|
114
|
+
- `gasCost` (BigInt): The estimated gas cost.
|
|
115
|
+
- `storageCost` (BigInt): The estimated storage cost.
|
|
116
|
+
|
|
117
|
+
**Example**
|
|
118
|
+
```javascript
|
|
119
|
+
const request = {
|
|
120
|
+
key: "example1.txt",
|
|
121
|
+
maxFeePerGas: 30000000000n, // 30 gwei, in wei
|
|
122
|
+
maxPriorityFeePerGas: 1500000000n, // 1.5 gwei, in wei
|
|
123
|
+
content: Buffer.from("large data to upload")
|
|
124
|
+
}
|
|
125
|
+
const cost = await flatDirectory.estimateCost(request);
|
|
126
|
+
console.log(`Gas Cost: ${cost.gasCost}, Storage Cost: ${cost.storageCost}`);
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
If you want to use `file`, it can be divided into browser and Node.js.
|
|
130
|
+
|
|
131
|
+
Browser
|
|
132
|
+
```javascript
|
|
133
|
+
// <input id='fileToUpload' />
|
|
134
|
+
const file = document.getElementById('fileToUpload').files[0];
|
|
135
|
+
|
|
136
|
+
const request = {
|
|
137
|
+
key: "example1.txt",
|
|
138
|
+
content: file
|
|
139
|
+
}
|
|
140
|
+
const cost = await flatDirectory.estimateCost(request);
|
|
141
|
+
console.log(`Gas Cost: ${cost.gasCost}, Storage Cost: ${cost.storageCost}`);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Node.js
|
|
145
|
+
```javascript
|
|
146
|
+
const {NodeFile} = require("calldatauploader-sdk/file");
|
|
147
|
+
const file = new NodeFile("/usr/download/test.jpg");
|
|
148
|
+
|
|
149
|
+
const request = {
|
|
150
|
+
key: "example1.txt",
|
|
151
|
+
content: file
|
|
152
|
+
}
|
|
153
|
+
const cost = await flatDirectory.estimateCost(request);
|
|
154
|
+
console.log(`Gas Cost: ${cost.gasCost}, Storage Cost: ${cost.storageCost}`);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### upload
|
|
158
|
+
|
|
159
|
+
**Description**: Upload data of arbitrary size via calldata.
|
|
160
|
+
|
|
161
|
+
**Parameters**
|
|
162
|
+
- `request` (object): Configuration of the upload object containing necessary settings.
|
|
163
|
+
- `key` (string): The key of the data.
|
|
164
|
+
- `content` (Buffer|File): The content to be uploaded, which can be either a Buffer or a File.
|
|
165
|
+
- `maxFeePerGas` (bigint, optional): Custom max fee per gas, in wei (EIP-1559). Defaults to `1.1 × latest-block base fee + maxPriorityFeePerGas` (i.e. `baseFee * 11 / 10`, base fee from the node).
|
|
166
|
+
- `maxPriorityFeePerGas` (bigint, optional): Custom max priority fee per gas, in wei (EIP-1559). Defaults to `100` wei.
|
|
167
|
+
- `gasPrice` (bigint, optional): Custom gas price, in wei (legacy chains without EIP-1559, e.g. BNB Chain). Defaults to the node-suggested gas price.
|
|
168
|
+
- `chunkHashes` (string[], optional): The chunk hashes corresponding to the content. If this parameter exists, no
|
|
169
|
+
request to retrieve the hashes will be triggered.
|
|
170
|
+
- `maxChunkSize` (number, optional): Size of each data chunk, in KB. Defaults to `DEFAULT_MAX_CHUNK_SIZE_KB` (64).
|
|
171
|
+
- `maxChunks` (number, optional): Maximum number of chunks requested in a single call. Defaults to `MAX_CHUNKS`.
|
|
172
|
+
- `callback` (object): An object containing callback functions:
|
|
173
|
+
- `onProgress(currentChunk, totalChunks, isChange)` (function): Called during the upload process to track progress.
|
|
174
|
+
- **`currentChunk`** (number): The index of the currently uploading chunk.
|
|
175
|
+
- **`totalChunks`** (number): The total number of chunks to be uploaded.
|
|
176
|
+
- **`isChange`** (boolean): Indicates whether the content has changed.
|
|
177
|
+
- `onFail(error)` (function): Called when an error occurs during the upload process.
|
|
178
|
+
- **`error`** (Error): The error object describing the failure.
|
|
179
|
+
- `onFinish(totalUploadChunks, totalUploadSize, totalCost)` (function): Called when the upload is completed.
|
|
180
|
+
- **`totalUploadChunks`** (number): The total number of uploaded chunks.
|
|
181
|
+
- **`totalUploadSize`** (number): The total uploaded size (in bytes).
|
|
182
|
+
- **`totalCost`** (bigint): The total cost of the upload, including **storage cost** and **gas cost**.
|
|
183
|
+
- `onTransactionSent(txHash, chunkIds)` (function, optional): Called right after a transaction is sent.
|
|
184
|
+
- **`txHash`** (string): The transaction hash.
|
|
185
|
+
- **`chunkIds`** (number[] | number): The chunk id(s) contained in the transaction.
|
|
186
|
+
|
|
187
|
+
**Example**
|
|
188
|
+
```javascript
|
|
189
|
+
const cb = {
|
|
190
|
+
onProgress: function (progress, count, isChange) {
|
|
191
|
+
console.log(`Uploaded ${progress} of ${count} chunks`);
|
|
192
|
+
},
|
|
193
|
+
onFail: function (error) {
|
|
194
|
+
console.error("Error uploading data:", error);
|
|
195
|
+
},
|
|
196
|
+
onFinish: function (totalUploadChunks, totalUploadSize, totalCost) {
|
|
197
|
+
console.log(`Total upload chunk count is ${totalUploadChunks}, size is ${totalUploadSize}, total cost is ${totalCost}`);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
const request = {
|
|
201
|
+
key: "example1.txt",
|
|
202
|
+
maxFeePerGas: 30000000000n, // 30 gwei, in wei
|
|
203
|
+
maxPriorityFeePerGas: 1500000000n, // 1.5 gwei, in wei
|
|
204
|
+
content: Buffer.from("large data to upload"),
|
|
205
|
+
callback: cb
|
|
206
|
+
}
|
|
207
|
+
await flatDirectory.upload(request);
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Use `file`.
|
|
211
|
+
|
|
212
|
+
Browser
|
|
213
|
+
```javascript
|
|
214
|
+
// <input id='fileToUpload' />
|
|
215
|
+
const file = document.getElementById('fileToUpload').files[0];
|
|
216
|
+
|
|
217
|
+
const request = {
|
|
218
|
+
key: "example1.txt",
|
|
219
|
+
maxFeePerGas: 30000000000n, // 30 gwei, in wei
|
|
220
|
+
maxPriorityFeePerGas: 1500000000n, // 1.5 gwei, in wei
|
|
221
|
+
content: file,
|
|
222
|
+
callback: cb
|
|
223
|
+
}
|
|
224
|
+
await flatDirectory.upload(request);
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Node.js
|
|
228
|
+
```javascript
|
|
229
|
+
const {NodeFile} = require("calldatauploader-sdk/file");
|
|
230
|
+
const file = new NodeFile("/usr/download/test.jpg");
|
|
231
|
+
|
|
232
|
+
const request = {
|
|
233
|
+
key: "example1.txt",
|
|
234
|
+
maxFeePerGas: 30000000000n, // 30 gwei, in wei
|
|
235
|
+
maxPriorityFeePerGas: 1500000000n, // 1.5 gwei, in wei
|
|
236
|
+
content: file,
|
|
237
|
+
callback: cb
|
|
238
|
+
}
|
|
239
|
+
await flatDirectory.upload(request);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### download
|
|
243
|
+
|
|
244
|
+
**Description**: Asynchronously download data by key. Get the progress and data in the callback function.
|
|
245
|
+
|
|
246
|
+
**Parameters**
|
|
247
|
+
- `key` (string): The key for the data to be read.
|
|
248
|
+
- `callback` (object): An object containing callback functions:
|
|
249
|
+
- `onProgress(currentChunk, totalChunks, chunkData)` (function): Called during the download process to track progress and receive chunk data.
|
|
250
|
+
- **`currentChunk`** (number): The index of the currently downloading chunk.
|
|
251
|
+
- **`totalChunks`** (number): The total number of chunks to be downloaded.
|
|
252
|
+
- **`chunkData`** (Uint8Array): The binary data of the current chunk.
|
|
253
|
+
- `onFail(error)` (function): Called when an error occurs during the download process.
|
|
254
|
+
- **`error`** (Error): The error object describing the failure.
|
|
255
|
+
- `onFinish()` (function): Indicates that the download was finish.
|
|
256
|
+
|
|
257
|
+
**Example**
|
|
258
|
+
```javascript
|
|
259
|
+
flatDirectory.download("example.txt", {
|
|
260
|
+
onProgress: function (progress, count, chunk) {
|
|
261
|
+
console.log(`Download ${progress} of ${count} chunks, this chunk is ${Buffer.from(chunk).toString()}`);
|
|
262
|
+
},
|
|
263
|
+
onFail: function (error) {
|
|
264
|
+
console.error("Error download data:", error);
|
|
265
|
+
},
|
|
266
|
+
onFinish: function () {
|
|
267
|
+
console.log("Download finish.");
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### fetchHashes
|
|
273
|
+
|
|
274
|
+
**Description**: Retrieve the chunk hashes corresponding to the batch of keys.
|
|
275
|
+
|
|
276
|
+
**Parameters**
|
|
277
|
+
- `keys` (string[]): The keys to be retrieved.
|
|
278
|
+
- `maxChunks` (number, optional): Maximum number of chunks requested in a single call, defaults to `MAX_CHUNKS`.
|
|
279
|
+
|
|
280
|
+
**Returns**
|
|
281
|
+
- `result` (Promise<Record<string, string[]>>): A Promise that resolves to an object where each key (from the input keys) maps to an array of chunk hashes.
|
|
282
|
+
|
|
283
|
+
**Example**
|
|
284
|
+
```javascript
|
|
285
|
+
const keys = ["key1", "key2"];
|
|
286
|
+
const result = await flatDirectory.fetchHashes(keys);
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### setDefault
|
|
290
|
+
|
|
291
|
+
**Description**: Set the default file for FlatDirectory, the file that is accessed by default when no file name is
|
|
292
|
+
provided.
|
|
293
|
+
|
|
294
|
+
**Parameters**
|
|
295
|
+
- `filename` (string): The filename of the default file.
|
|
296
|
+
|
|
297
|
+
**Returns**
|
|
298
|
+
- `status` (Promise<boolean>): A Promise that resolves to the execution result. `true|false`
|
|
299
|
+
|
|
300
|
+
**Example**
|
|
301
|
+
```javascript
|
|
302
|
+
const defaultFile = "index.html";
|
|
303
|
+
const status = await flatDirectory.setDefault(defaultFile);
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### remove
|
|
307
|
+
|
|
308
|
+
**Description**: Remove a file from the FlatDirectory contract.
|
|
309
|
+
|
|
310
|
+
**Parameters**
|
|
311
|
+
- `key` (string): The key of the file to be removed.
|
|
312
|
+
|
|
313
|
+
**Returns**
|
|
314
|
+
- `status` (Promise<boolean>): A Promise that resolves to the execution result. `true|false`
|
|
315
|
+
|
|
316
|
+
**Example**
|
|
317
|
+
```javascript
|
|
318
|
+
const status = await flatDirectory.remove("index.html");
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
<p id="Version"></p>
|
|
322
|
+
|
|
323
|
+
# 4. Version History
|
|
324
|
+
|
|
325
|
+
- v1.1.1: Initial release with basic storage and data management functionalities.
|