@shelby-protocol/cli 0.0.12 → 0.0.13
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/bin/entry.js +602 -602
- package/package.json +3 -3
package/bin/entry.js
CHANGED
|
@@ -4,12 +4,73 @@
|
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
|
|
6
6
|
// package.json
|
|
7
|
-
var version = "0.0.
|
|
7
|
+
var version = "0.0.13";
|
|
8
8
|
|
|
9
9
|
// src/commands/account.tsx
|
|
10
10
|
import readline from "readline";
|
|
11
11
|
import { Account as Account3, AptosApiError as AptosApiError2, Ed25519PrivateKey as Ed25519PrivateKey4 } from "@aptos-labs/ts-sdk";
|
|
12
12
|
|
|
13
|
+
// ../../packages/sdk/dist/chunk-RBFWGDMY.mjs
|
|
14
|
+
import { AptosConfig, Network } from "@aptos-labs/ts-sdk";
|
|
15
|
+
var getAptosConfig = (config) => {
|
|
16
|
+
if (config.aptos) {
|
|
17
|
+
return new AptosConfig(config.aptos);
|
|
18
|
+
}
|
|
19
|
+
let aptosConfig;
|
|
20
|
+
switch (config.network) {
|
|
21
|
+
case "local":
|
|
22
|
+
aptosConfig = new AptosConfig({
|
|
23
|
+
network: Network.LOCAL
|
|
24
|
+
});
|
|
25
|
+
break;
|
|
26
|
+
case "shelbynet":
|
|
27
|
+
aptosConfig = new AptosConfig({
|
|
28
|
+
network: Network.SHELBYNET,
|
|
29
|
+
clientConfig: {
|
|
30
|
+
API_KEY: config.apiKey
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
break;
|
|
34
|
+
default:
|
|
35
|
+
throw new Error(`Unsupported network: ${config.network}`);
|
|
36
|
+
}
|
|
37
|
+
return aptosConfig;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// ../../packages/sdk/dist/chunk-SEXQTDX6.mjs
|
|
41
|
+
import { Network as Network2 } from "@aptos-labs/ts-sdk";
|
|
42
|
+
var NetworkToShelbyRPCBaseUrl = {
|
|
43
|
+
[Network2.SHELBYNET]: "https://api.shelbynet.shelby.xyz/shelby",
|
|
44
|
+
[Network2.DEVNET]: void 0,
|
|
45
|
+
[Network2.TESTNET]: void 0,
|
|
46
|
+
[Network2.MAINNET]: void 0,
|
|
47
|
+
[Network2.LOCAL]: void 0,
|
|
48
|
+
[Network2.CUSTOM]: void 0
|
|
49
|
+
};
|
|
50
|
+
var NetworkToShelbyBlobIndexerBaseUrl = {
|
|
51
|
+
[Network2.SHELBYNET]: "https://api.shelbynet.aptoslabs.com/nocode/v1/public/cmforrguw0042s601fn71f9l2/v1/graphql",
|
|
52
|
+
[Network2.DEVNET]: void 0,
|
|
53
|
+
[Network2.TESTNET]: void 0,
|
|
54
|
+
[Network2.MAINNET]: void 0,
|
|
55
|
+
[Network2.LOCAL]: void 0,
|
|
56
|
+
[Network2.CUSTOM]: void 0
|
|
57
|
+
};
|
|
58
|
+
var SHELBY_DEPLOYER = "0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5";
|
|
59
|
+
var SHELBYUSD_TOKEN_NAME = "ShelbyUSD";
|
|
60
|
+
var SHELBYUSD_FA_METADATA_ADDRESS = "0x1b18363a9f1fe5e6ebf247daba5cc1c18052bb232efdc4c50f556053922d98e1";
|
|
61
|
+
|
|
62
|
+
// ../../packages/sdk/dist/chunk-CTGCK3H2.mjs
|
|
63
|
+
import {
|
|
64
|
+
AccountAddress,
|
|
65
|
+
Aptos,
|
|
66
|
+
Hex
|
|
67
|
+
} from "@aptos-labs/ts-sdk";
|
|
68
|
+
|
|
69
|
+
// ../../packages/sdk/dist/chunk-I6NG5GNL.mjs
|
|
70
|
+
function sleep(ms) {
|
|
71
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
72
|
+
}
|
|
73
|
+
|
|
13
74
|
// ../../node_modules/.pnpm/tslib@2.8.1/node_modules/tslib/tslib.es6.mjs
|
|
14
75
|
var __assign = function() {
|
|
15
76
|
__assign = Object.assign || function __assign2(t) {
|
|
@@ -3257,55 +3318,6 @@ function getSdk(client, withWrapper = defaultWrapper) {
|
|
|
3257
3318
|
};
|
|
3258
3319
|
}
|
|
3259
3320
|
|
|
3260
|
-
// ../../packages/sdk/dist/chunk-RBFWGDMY.mjs
|
|
3261
|
-
import { AptosConfig, Network } from "@aptos-labs/ts-sdk";
|
|
3262
|
-
var getAptosConfig = (config) => {
|
|
3263
|
-
if (config.aptos) {
|
|
3264
|
-
return new AptosConfig(config.aptos);
|
|
3265
|
-
}
|
|
3266
|
-
let aptosConfig;
|
|
3267
|
-
switch (config.network) {
|
|
3268
|
-
case "local":
|
|
3269
|
-
aptosConfig = new AptosConfig({
|
|
3270
|
-
network: Network.LOCAL
|
|
3271
|
-
});
|
|
3272
|
-
break;
|
|
3273
|
-
case "shelbynet":
|
|
3274
|
-
aptosConfig = new AptosConfig({
|
|
3275
|
-
network: Network.SHELBYNET,
|
|
3276
|
-
clientConfig: {
|
|
3277
|
-
API_KEY: config.apiKey
|
|
3278
|
-
}
|
|
3279
|
-
});
|
|
3280
|
-
break;
|
|
3281
|
-
default:
|
|
3282
|
-
throw new Error(`Unsupported network: ${config.network}`);
|
|
3283
|
-
}
|
|
3284
|
-
return aptosConfig;
|
|
3285
|
-
};
|
|
3286
|
-
|
|
3287
|
-
// ../../packages/sdk/dist/chunk-SEXQTDX6.mjs
|
|
3288
|
-
import { Network as Network2 } from "@aptos-labs/ts-sdk";
|
|
3289
|
-
var NetworkToShelbyRPCBaseUrl = {
|
|
3290
|
-
[Network2.SHELBYNET]: "https://api.shelbynet.shelby.xyz/shelby",
|
|
3291
|
-
[Network2.DEVNET]: void 0,
|
|
3292
|
-
[Network2.TESTNET]: void 0,
|
|
3293
|
-
[Network2.MAINNET]: void 0,
|
|
3294
|
-
[Network2.LOCAL]: void 0,
|
|
3295
|
-
[Network2.CUSTOM]: void 0
|
|
3296
|
-
};
|
|
3297
|
-
var NetworkToShelbyBlobIndexerBaseUrl = {
|
|
3298
|
-
[Network2.SHELBYNET]: "https://api.shelbynet.aptoslabs.com/nocode/v1/public/cmforrguw0042s601fn71f9l2/v1/graphql",
|
|
3299
|
-
[Network2.DEVNET]: void 0,
|
|
3300
|
-
[Network2.TESTNET]: void 0,
|
|
3301
|
-
[Network2.MAINNET]: void 0,
|
|
3302
|
-
[Network2.LOCAL]: void 0,
|
|
3303
|
-
[Network2.CUSTOM]: void 0
|
|
3304
|
-
};
|
|
3305
|
-
var SHELBY_DEPLOYER = "0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5";
|
|
3306
|
-
var SHELBYUSD_TOKEN_NAME = "ShelbyUSD";
|
|
3307
|
-
var SHELBYUSD_FA_METADATA_ADDRESS = "0x1b18363a9f1fe5e6ebf247daba5cc1c18052bb232efdc4c50f556053922d98e1";
|
|
3308
|
-
|
|
3309
3321
|
// ../../packages/sdk/dist/chunk-VPT45MTZ.mjs
|
|
3310
3322
|
import { Network as Network3 } from "@aptos-labs/ts-sdk";
|
|
3311
3323
|
|
|
@@ -3854,14 +3866,8 @@ function getShelbyIndexerClient(config) {
|
|
|
3854
3866
|
});
|
|
3855
3867
|
}
|
|
3856
3868
|
|
|
3857
|
-
// ../../packages/sdk/dist/chunk-OTBLZL2S.mjs
|
|
3858
|
-
import { AccountAddress } from "@aptos-labs/ts-sdk";
|
|
3859
|
-
var createBlobKey = (params) => {
|
|
3860
|
-
return `@${AccountAddress.from(params.account).toStringLongWithoutPrefix()}/${params.blobName}`;
|
|
3861
|
-
};
|
|
3862
|
-
|
|
3863
3869
|
// ../../packages/sdk/dist/chunk-KBUWZXFA.mjs
|
|
3864
|
-
import { Hex } from "@aptos-labs/ts-sdk";
|
|
3870
|
+
import { Hex as Hex2 } from "@aptos-labs/ts-sdk";
|
|
3865
3871
|
async function* readInChunks(input, chunkSize) {
|
|
3866
3872
|
let idx = 0;
|
|
3867
3873
|
if (isReadableStream(input)) {
|
|
@@ -3921,7 +3927,7 @@ function zeroPadBytes(buffer, desiredLength) {
|
|
|
3921
3927
|
return paddedBuffer;
|
|
3922
3928
|
}
|
|
3923
3929
|
async function concatHashes(parts) {
|
|
3924
|
-
const chunks = parts.map((part) =>
|
|
3930
|
+
const chunks = parts.map((part) => Hex2.fromHexInput(part).toUint8Array());
|
|
3925
3931
|
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
|
|
3926
3932
|
const combined = new Uint8Array(totalLength);
|
|
3927
3933
|
let offset = 0;
|
|
@@ -3929,7 +3935,7 @@ async function concatHashes(parts) {
|
|
|
3929
3935
|
combined.set(chunk, offset);
|
|
3930
3936
|
offset += chunk.byteLength;
|
|
3931
3937
|
}
|
|
3932
|
-
return
|
|
3938
|
+
return Hex2.fromHexInput(
|
|
3933
3939
|
new Uint8Array(await crypto.subtle.digest("SHA-256", combined))
|
|
3934
3940
|
);
|
|
3935
3941
|
}
|
|
@@ -4125,158 +4131,435 @@ function buildClayConfig(input) {
|
|
|
4125
4131
|
};
|
|
4126
4132
|
}
|
|
4127
4133
|
|
|
4128
|
-
// ../../packages/sdk/dist/chunk-
|
|
4134
|
+
// ../../packages/sdk/dist/chunk-FIFKKWXV.mjs
|
|
4135
|
+
import { AccountAddress as AccountAddress2 } from "@aptos-labs/ts-sdk";
|
|
4129
4136
|
import { z } from "zod";
|
|
4130
|
-
var
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
// the size is known statically from the current configuration
|
|
4134
|
-
chunk_commitments: z.array(z.string())
|
|
4135
|
-
}).refine(
|
|
4136
|
-
(data) => {
|
|
4137
|
-
return data.chunk_commitments.length === DEFAULT_ERASURE_K + DEFAULT_ERASURE_M;
|
|
4138
|
-
},
|
|
4139
|
-
{
|
|
4140
|
-
message: `Chunkset must have exactly ${DEFAULT_ERASURE_K + DEFAULT_ERASURE_M} chunks (ERASURE_K + ERASURE_M = ${DEFAULT_ERASURE_K} + ${DEFAULT_ERASURE_M})`,
|
|
4141
|
-
path: ["chunk_commitments"]
|
|
4142
|
-
}
|
|
4143
|
-
);
|
|
4144
|
-
function expectedTotalChunksets(rawSize, chunksetSize = DEFAULT_CHUNKSET_SIZE_BYTES) {
|
|
4145
|
-
if (chunksetSize <= 0) {
|
|
4146
|
-
throw new Error("chunksetSize must be positive");
|
|
4147
|
-
}
|
|
4148
|
-
if (rawSize === 0) return 1;
|
|
4149
|
-
return Math.ceil(rawSize / chunksetSize);
|
|
4150
|
-
}
|
|
4151
|
-
var BlobCommitmentsSchema = z.object({
|
|
4152
|
-
schema_version: z.string(),
|
|
4153
|
-
raw_data_size: z.number(),
|
|
4154
|
-
// FIXME I am not sure about this being here, or if it should be somewhere else
|
|
4155
|
-
blob_merkle_root: z.string(),
|
|
4156
|
-
chunkset_commitments: z.array(ChunksetCommitmentSchema)
|
|
4157
|
-
}).refine(
|
|
4158
|
-
(data) => {
|
|
4159
|
-
return expectedTotalChunksets(data.raw_data_size) === data.chunkset_commitments.length;
|
|
4160
|
-
},
|
|
4161
|
-
{
|
|
4162
|
-
message: "Total chunkset count mismatches with raw data size",
|
|
4163
|
-
// FIXME put more details in here
|
|
4164
|
-
path: ["chunkset_commitments"]
|
|
4165
|
-
}
|
|
4166
|
-
);
|
|
4167
|
-
async function generateChunksetCommitments(shouldPad, chunksetIdx, chunksetData, expectedChunksetSize, provider, onChunk) {
|
|
4168
|
-
const { erasure_n } = provider.config;
|
|
4169
|
-
const chunkCommitments = [];
|
|
4170
|
-
const chunksetPayload = shouldPad ? zeroPadBytes(chunksetData, expectedChunksetSize) : validatePrePaddedChunkset(
|
|
4171
|
-
chunksetData,
|
|
4172
|
-
expectedChunksetSize,
|
|
4173
|
-
chunksetIdx
|
|
4174
|
-
);
|
|
4175
|
-
const { chunks } = provider.encode(chunksetPayload);
|
|
4176
|
-
if (chunks.length !== erasure_n) {
|
|
4177
|
-
throw new Error(
|
|
4178
|
-
`Erasure provider produced ${chunks.length} chunks, expected ${erasure_n}.`
|
|
4179
|
-
);
|
|
4180
|
-
}
|
|
4181
|
-
let chunkIdx = 0;
|
|
4182
|
-
for (const chunkData of chunks) {
|
|
4183
|
-
if (onChunk !== void 0) {
|
|
4184
|
-
await onChunk(chunksetIdx, chunkIdx, chunkData);
|
|
4185
|
-
}
|
|
4186
|
-
const chunkHash = await concatHashes([chunkData]);
|
|
4187
|
-
chunkCommitments.push(chunkHash);
|
|
4188
|
-
chunkIdx += 1;
|
|
4189
|
-
}
|
|
4190
|
-
const h = await concatHashes(
|
|
4191
|
-
chunkCommitments.map((chunk) => chunk.toUint8Array())
|
|
4192
|
-
);
|
|
4193
|
-
const entry = {
|
|
4194
|
-
chunkset_root: h.toString(),
|
|
4195
|
-
chunk_commitments: chunkCommitments.map((chunk) => chunk.toString())
|
|
4196
|
-
};
|
|
4197
|
-
return { h, entry };
|
|
4198
|
-
}
|
|
4199
|
-
async function generateCommitments(provider, fullData, onChunk, options) {
|
|
4200
|
-
const expectedChunksetSize = DEFAULT_CHUNKSET_SIZE_BYTES;
|
|
4201
|
-
const shouldPad = options?.pad ?? true;
|
|
4202
|
-
const chunksetCommitments = [];
|
|
4203
|
-
const chunksetCommitmentHashes = [];
|
|
4204
|
-
let rawDataSize = 0;
|
|
4205
|
-
const chunksetGen = readInChunks(fullData, expectedChunksetSize);
|
|
4206
|
-
for await (const [chunksetIdx, chunksetData] of chunksetGen) {
|
|
4207
|
-
rawDataSize += chunksetData.length;
|
|
4208
|
-
const { h, entry } = await generateChunksetCommitments(
|
|
4209
|
-
shouldPad,
|
|
4210
|
-
chunksetIdx,
|
|
4211
|
-
chunksetData,
|
|
4212
|
-
expectedChunksetSize,
|
|
4213
|
-
provider,
|
|
4214
|
-
onChunk
|
|
4215
|
-
);
|
|
4216
|
-
chunksetCommitments.push(entry);
|
|
4217
|
-
chunksetCommitmentHashes.push(h);
|
|
4218
|
-
}
|
|
4219
|
-
if (rawDataSize === 0) {
|
|
4220
|
-
const zeroChunkset = new Uint8Array(expectedChunksetSize);
|
|
4221
|
-
const { h, entry } = await generateChunksetCommitments(
|
|
4222
|
-
shouldPad,
|
|
4223
|
-
0,
|
|
4224
|
-
zeroChunkset,
|
|
4225
|
-
expectedChunksetSize,
|
|
4226
|
-
provider,
|
|
4227
|
-
onChunk
|
|
4228
|
-
);
|
|
4229
|
-
chunksetCommitments.push(entry);
|
|
4230
|
-
chunksetCommitmentHashes.push(h);
|
|
4231
|
-
}
|
|
4232
|
-
return {
|
|
4233
|
-
schema_version: "1.3",
|
|
4234
|
-
raw_data_size: rawDataSize,
|
|
4235
|
-
blob_merkle_root: (await concatHashes(
|
|
4236
|
-
chunksetCommitmentHashes.map((chunk) => chunk.toUint8Array())
|
|
4237
|
-
)).toString(),
|
|
4238
|
-
chunkset_commitments: chunksetCommitments
|
|
4239
|
-
};
|
|
4240
|
-
}
|
|
4241
|
-
function validatePrePaddedChunkset(chunkset, expectedSize, chunksetIdx) {
|
|
4242
|
-
if (chunkset.byteLength !== expectedSize) {
|
|
4243
|
-
throw new Error(
|
|
4244
|
-
`Chunkset ${chunksetIdx} has size ${chunkset.byteLength} bytes but expected ${expectedSize} bytes. Enable padding or supply pre-padded data before calling generateCommitments.`
|
|
4245
|
-
);
|
|
4246
|
-
}
|
|
4247
|
-
return chunkset;
|
|
4248
|
-
}
|
|
4137
|
+
var BlobNameSchema = z.string().min(1, "Blob name path parameter cannot be empty.").max(1024, "Blob name cannot exceed 1024 characters.").refine((name) => !name.endsWith("/"), {
|
|
4138
|
+
message: "Blob name cannot end with a slash"
|
|
4139
|
+
});
|
|
4249
4140
|
|
|
4250
|
-
// ../../packages/sdk/dist/chunk-
|
|
4251
|
-
import {
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
aptos;
|
|
4260
|
-
deployer;
|
|
4141
|
+
// ../../packages/sdk/dist/chunk-TEDFWEY6.mjs
|
|
4142
|
+
import { AccountAddress as AccountAddress3 } from "@aptos-labs/ts-sdk";
|
|
4143
|
+
function encodeURIComponentKeepSlashes(str) {
|
|
4144
|
+
return encodeURIComponent(str).replace(/%2F/g, "/");
|
|
4145
|
+
}
|
|
4146
|
+
var ShelbyRPCClient = class {
|
|
4147
|
+
baseUrl;
|
|
4148
|
+
apiKey;
|
|
4149
|
+
rpcConfig;
|
|
4261
4150
|
indexer;
|
|
4262
4151
|
/**
|
|
4263
|
-
*
|
|
4264
|
-
*
|
|
4152
|
+
* Creates a new ShelbyRPCClient for interacting with Shelby RPC nodes.
|
|
4153
|
+
* This client handles blob storage operations including upload and download.
|
|
4265
4154
|
*
|
|
4266
4155
|
* @param config - The client configuration object.
|
|
4267
4156
|
* @param config.network - The Shelby network to use.
|
|
4268
4157
|
*
|
|
4269
4158
|
* @example
|
|
4270
4159
|
* ```typescript
|
|
4271
|
-
* const
|
|
4272
|
-
*
|
|
4273
|
-
*
|
|
4274
|
-
*
|
|
4275
|
-
*
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4160
|
+
* const client = new ShelbyRPCClient({
|
|
4161
|
+
* network: Network.SHELBYNET,
|
|
4162
|
+
* apiKey: "AG-***",
|
|
4163
|
+
* });
|
|
4164
|
+
* ```
|
|
4165
|
+
*/
|
|
4166
|
+
constructor(config) {
|
|
4167
|
+
this.baseUrl = config.rpc?.baseUrl ?? NetworkToShelbyRPCBaseUrl.shelbynet;
|
|
4168
|
+
this.apiKey = config.apiKey ?? config.rpc?.apiKey;
|
|
4169
|
+
this.rpcConfig = config.rpc ?? {};
|
|
4170
|
+
this.indexer = getShelbyIndexerClient(config);
|
|
4171
|
+
}
|
|
4172
|
+
async #uploadPart(uploadId, partIdx, partData) {
|
|
4173
|
+
const nRetries = 5;
|
|
4174
|
+
for (let i = 0; i < nRetries; ++i) {
|
|
4175
|
+
const partResponse = await fetch(
|
|
4176
|
+
buildRequestUrl(
|
|
4177
|
+
`/v1/multipart-uploads/${uploadId}/parts/${partIdx}`,
|
|
4178
|
+
this.baseUrl
|
|
4179
|
+
),
|
|
4180
|
+
{
|
|
4181
|
+
method: "PUT",
|
|
4182
|
+
headers: {
|
|
4183
|
+
"Content-Type": "application/octet-stream",
|
|
4184
|
+
...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
|
|
4185
|
+
},
|
|
4186
|
+
body: partData
|
|
4187
|
+
}
|
|
4188
|
+
);
|
|
4189
|
+
if (partResponse.ok) return;
|
|
4190
|
+
if (i < nRetries - 1) {
|
|
4191
|
+
const delay = 2 ** i * 100;
|
|
4192
|
+
await sleep(delay);
|
|
4193
|
+
}
|
|
4194
|
+
}
|
|
4195
|
+
throw new Error(`Failed to upload part ${partIdx}.`);
|
|
4196
|
+
}
|
|
4197
|
+
async #putBlobMultipart(account, blobName, blobData, partSize = 5 * 1024 * 1024) {
|
|
4198
|
+
const startResponse = await fetch(
|
|
4199
|
+
buildRequestUrl("/v1/multipart-uploads", this.baseUrl),
|
|
4200
|
+
{
|
|
4201
|
+
method: "POST",
|
|
4202
|
+
headers: {
|
|
4203
|
+
"Content-Type": "application/json",
|
|
4204
|
+
...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
|
|
4205
|
+
},
|
|
4206
|
+
body: JSON.stringify({
|
|
4207
|
+
rawAccount: account.toString(),
|
|
4208
|
+
rawBlobName: blobName,
|
|
4209
|
+
rawPartSize: partSize
|
|
4210
|
+
})
|
|
4211
|
+
}
|
|
4212
|
+
);
|
|
4213
|
+
if (!startResponse.ok) {
|
|
4214
|
+
let errorBodyText = "Could not read error body";
|
|
4215
|
+
try {
|
|
4216
|
+
errorBodyText = await startResponse.text();
|
|
4217
|
+
} catch (_e) {
|
|
4218
|
+
}
|
|
4219
|
+
throw new Error(
|
|
4220
|
+
`Failed to start multipart upload! status: ${startResponse.status}, body: ${errorBodyText}`
|
|
4221
|
+
);
|
|
4222
|
+
}
|
|
4223
|
+
const { uploadId } = await startResponse.json();
|
|
4224
|
+
const totalParts = Math.ceil(blobData.length / partSize);
|
|
4225
|
+
for (let partIdx = 0; partIdx < totalParts; partIdx++) {
|
|
4226
|
+
const start = partIdx * partSize;
|
|
4227
|
+
const end = Math.min(start + partSize, blobData.length);
|
|
4228
|
+
const partData = blobData.slice(start, end);
|
|
4229
|
+
await this.#uploadPart(uploadId, partIdx, partData);
|
|
4230
|
+
}
|
|
4231
|
+
const completeResponse = await fetch(
|
|
4232
|
+
buildRequestUrl(
|
|
4233
|
+
`/v1/multipart-uploads/${uploadId}/complete`,
|
|
4234
|
+
this.baseUrl
|
|
4235
|
+
),
|
|
4236
|
+
{
|
|
4237
|
+
method: "POST",
|
|
4238
|
+
headers: {
|
|
4239
|
+
"Content-Type": "application/json",
|
|
4240
|
+
...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
|
|
4241
|
+
}
|
|
4242
|
+
}
|
|
4243
|
+
);
|
|
4244
|
+
if (!completeResponse.ok) {
|
|
4245
|
+
let errorBodyText = "Could not read error body";
|
|
4246
|
+
try {
|
|
4247
|
+
errorBodyText = await completeResponse.text();
|
|
4248
|
+
} catch (_e) {
|
|
4249
|
+
}
|
|
4250
|
+
throw new Error(
|
|
4251
|
+
`Failed to complete multipart upload! status: ${completeResponse.status}, body: ${errorBodyText}`
|
|
4252
|
+
);
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4255
|
+
/**
|
|
4256
|
+
* Uploads blob data to the Shelby RPC node for storage by storage providers.
|
|
4257
|
+
* This method should be called after blob commitments have been registered on the blockchain.
|
|
4258
|
+
* Uses multipart upload for efficient handling of large files.
|
|
4259
|
+
*
|
|
4260
|
+
* @param params.account - The account that owns the blob.
|
|
4261
|
+
* @param params.blobName - The name/path of the blob (e.g. "folder/file.txt").
|
|
4262
|
+
* @param params.blobData - The raw blob data as a Uint8Array.
|
|
4263
|
+
*
|
|
4264
|
+
* @example
|
|
4265
|
+
* ```typescript
|
|
4266
|
+
* const blobData = new TextEncoder().encode("Hello, world!");
|
|
4267
|
+
*
|
|
4268
|
+
* await client.putBlob({
|
|
4269
|
+
* account: AccountAddress.from("0x1"),
|
|
4270
|
+
* blobName: "greetings/hello.txt",
|
|
4271
|
+
* blobData
|
|
4272
|
+
* });
|
|
4273
|
+
* ```
|
|
4274
|
+
*/
|
|
4275
|
+
async putBlob(params) {
|
|
4276
|
+
BlobNameSchema.parse(params.blobName);
|
|
4277
|
+
await this.#putBlobMultipart(
|
|
4278
|
+
params.account,
|
|
4279
|
+
params.blobName,
|
|
4280
|
+
params.blobData
|
|
4281
|
+
);
|
|
4282
|
+
}
|
|
4283
|
+
// FIXME make this possible to stream in put ^^^
|
|
4284
|
+
/**
|
|
4285
|
+
* Downloads a blob from the Shelby RPC node.
|
|
4286
|
+
* Returns a streaming response with validation to ensure data integrity.
|
|
4287
|
+
*
|
|
4288
|
+
* @param params.account - The account that owns the blob.
|
|
4289
|
+
* @param params.blobName - The name/path of the blob (e.g. "folder/file.txt").
|
|
4290
|
+
* @param params.range - Optional byte range for partial downloads.
|
|
4291
|
+
* @param params.range.start - Starting byte position (inclusive).
|
|
4292
|
+
* @param params.range.end - Ending byte position (inclusive, optional).
|
|
4293
|
+
*
|
|
4294
|
+
* @returns A ShelbyBlob object containing the account, name, readable stream, and content length.
|
|
4295
|
+
*
|
|
4296
|
+
* @throws Error if the download fails or content length doesn't match.
|
|
4297
|
+
*
|
|
4298
|
+
* @example
|
|
4299
|
+
* ```typescript
|
|
4300
|
+
* // Download entire blob
|
|
4301
|
+
* const blob = await client.getBlob({
|
|
4302
|
+
* account: AccountAddress.from("0x1"),
|
|
4303
|
+
* blobName: "documents/report.pdf"
|
|
4304
|
+
* });
|
|
4305
|
+
*
|
|
4306
|
+
* // Download partial content (bytes 100-199)
|
|
4307
|
+
* const partial = await client.getBlob({
|
|
4308
|
+
* account: AccountAddress.from("0x1"),
|
|
4309
|
+
* blobName: "large-file.bin",
|
|
4310
|
+
* range: { start: 100, end: 199 }
|
|
4311
|
+
* });
|
|
4312
|
+
* ```
|
|
4313
|
+
*/
|
|
4314
|
+
async getBlob(params) {
|
|
4315
|
+
BlobNameSchema.parse(params.blobName);
|
|
4316
|
+
const url = buildRequestUrl(
|
|
4317
|
+
`/v1/blobs/${params.account.toString()}/${encodeURIComponentKeepSlashes(
|
|
4318
|
+
params.blobName
|
|
4319
|
+
)}`,
|
|
4320
|
+
this.baseUrl
|
|
4321
|
+
);
|
|
4322
|
+
const requestInit = {};
|
|
4323
|
+
if (params.range !== void 0) {
|
|
4324
|
+
const headers = new Headers();
|
|
4325
|
+
const { start, end } = params.range;
|
|
4326
|
+
if (end === void 0) {
|
|
4327
|
+
headers.set("Range", `bytes=${start}-`);
|
|
4328
|
+
} else {
|
|
4329
|
+
if (end < start) {
|
|
4330
|
+
throw new Error("Range end cannot be less than start.");
|
|
4331
|
+
}
|
|
4332
|
+
headers.set("Range", `bytes=${start}-${end}`);
|
|
4333
|
+
}
|
|
4334
|
+
requestInit.headers = headers;
|
|
4335
|
+
}
|
|
4336
|
+
const response = await fetch(url, {
|
|
4337
|
+
...requestInit,
|
|
4338
|
+
headers: {
|
|
4339
|
+
...requestInit.headers,
|
|
4340
|
+
...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
|
|
4341
|
+
}
|
|
4342
|
+
});
|
|
4343
|
+
if (!response.ok) {
|
|
4344
|
+
throw new Error(
|
|
4345
|
+
`Failed to download blob: ${response.status} ${response.statusText}`
|
|
4346
|
+
);
|
|
4347
|
+
}
|
|
4348
|
+
if (!response.body) {
|
|
4349
|
+
throw new Error("Response body is null");
|
|
4350
|
+
}
|
|
4351
|
+
const contentLengthHeader = response.headers.get("content-length");
|
|
4352
|
+
if (contentLengthHeader === null) {
|
|
4353
|
+
throw new Error(
|
|
4354
|
+
"Response did not have content-length header, which is required"
|
|
4355
|
+
);
|
|
4356
|
+
}
|
|
4357
|
+
const expectedContentLength = Number.parseInt(contentLengthHeader, 10);
|
|
4358
|
+
if (Number.isNaN(expectedContentLength)) {
|
|
4359
|
+
throw new Error(
|
|
4360
|
+
`Invalid content-length header received: ${contentLengthHeader}`
|
|
4361
|
+
);
|
|
4362
|
+
}
|
|
4363
|
+
const validatingStream = new ReadableStream({
|
|
4364
|
+
start(controller) {
|
|
4365
|
+
const maybeReader = response.body?.getReader();
|
|
4366
|
+
if (!maybeReader) {
|
|
4367
|
+
controller.error(new Error("Response body reader is unavailable"));
|
|
4368
|
+
return;
|
|
4369
|
+
}
|
|
4370
|
+
const reader = maybeReader;
|
|
4371
|
+
let bytesReceived = 0;
|
|
4372
|
+
function pump() {
|
|
4373
|
+
return reader.read().then(({ done, value }) => {
|
|
4374
|
+
if (done) {
|
|
4375
|
+
if (bytesReceived !== expectedContentLength) {
|
|
4376
|
+
controller.error(
|
|
4377
|
+
new Error(
|
|
4378
|
+
`Downloaded data size (${bytesReceived} bytes) does not match content-length header (${expectedContentLength} bytes). This might indicate a partial or corrupted download.`
|
|
4379
|
+
)
|
|
4380
|
+
);
|
|
4381
|
+
return;
|
|
4382
|
+
}
|
|
4383
|
+
controller.close();
|
|
4384
|
+
return;
|
|
4385
|
+
}
|
|
4386
|
+
bytesReceived += value.byteLength;
|
|
4387
|
+
controller.enqueue(value);
|
|
4388
|
+
return pump();
|
|
4389
|
+
}).catch((error) => {
|
|
4390
|
+
controller.error(error);
|
|
4391
|
+
});
|
|
4392
|
+
}
|
|
4393
|
+
return pump();
|
|
4394
|
+
}
|
|
4395
|
+
});
|
|
4396
|
+
return {
|
|
4397
|
+
account: AccountAddress3.from(params.account),
|
|
4398
|
+
name: params.blobName,
|
|
4399
|
+
readable: validatingStream,
|
|
4400
|
+
contentLength: expectedContentLength
|
|
4401
|
+
};
|
|
4402
|
+
}
|
|
4403
|
+
};
|
|
4404
|
+
|
|
4405
|
+
// ../../packages/sdk/dist/chunk-OTBLZL2S.mjs
|
|
4406
|
+
import { AccountAddress as AccountAddress4 } from "@aptos-labs/ts-sdk";
|
|
4407
|
+
var createBlobKey = (params) => {
|
|
4408
|
+
return `@${AccountAddress4.from(params.account).toStringLongWithoutPrefix()}/${params.blobName}`;
|
|
4409
|
+
};
|
|
4410
|
+
|
|
4411
|
+
// ../../packages/sdk/dist/chunk-LTV26KU4.mjs
|
|
4412
|
+
import { z as z2 } from "zod";
|
|
4413
|
+
var ChunksetCommitmentSchema = z2.object({
|
|
4414
|
+
// Chunkset root (vector commitment of child chunks)
|
|
4415
|
+
chunkset_root: z2.string().nullable(),
|
|
4416
|
+
// the size is known statically from the current configuration
|
|
4417
|
+
chunk_commitments: z2.array(z2.string())
|
|
4418
|
+
}).refine(
|
|
4419
|
+
(data) => {
|
|
4420
|
+
return data.chunk_commitments.length === DEFAULT_ERASURE_K + DEFAULT_ERASURE_M;
|
|
4421
|
+
},
|
|
4422
|
+
{
|
|
4423
|
+
message: `Chunkset must have exactly ${DEFAULT_ERASURE_K + DEFAULT_ERASURE_M} chunks (ERASURE_K + ERASURE_M = ${DEFAULT_ERASURE_K} + ${DEFAULT_ERASURE_M})`,
|
|
4424
|
+
path: ["chunk_commitments"]
|
|
4425
|
+
}
|
|
4426
|
+
);
|
|
4427
|
+
function expectedTotalChunksets(rawSize, chunksetSize = DEFAULT_CHUNKSET_SIZE_BYTES) {
|
|
4428
|
+
if (chunksetSize <= 0) {
|
|
4429
|
+
throw new Error("chunksetSize must be positive");
|
|
4430
|
+
}
|
|
4431
|
+
if (rawSize === 0) return 1;
|
|
4432
|
+
return Math.ceil(rawSize / chunksetSize);
|
|
4433
|
+
}
|
|
4434
|
+
var BlobCommitmentsSchema = z2.object({
|
|
4435
|
+
schema_version: z2.string(),
|
|
4436
|
+
raw_data_size: z2.number(),
|
|
4437
|
+
// FIXME I am not sure about this being here, or if it should be somewhere else
|
|
4438
|
+
blob_merkle_root: z2.string(),
|
|
4439
|
+
chunkset_commitments: z2.array(ChunksetCommitmentSchema)
|
|
4440
|
+
}).refine(
|
|
4441
|
+
(data) => {
|
|
4442
|
+
return expectedTotalChunksets(data.raw_data_size) === data.chunkset_commitments.length;
|
|
4443
|
+
},
|
|
4444
|
+
{
|
|
4445
|
+
message: "Total chunkset count mismatches with raw data size",
|
|
4446
|
+
// FIXME put more details in here
|
|
4447
|
+
path: ["chunkset_commitments"]
|
|
4448
|
+
}
|
|
4449
|
+
);
|
|
4450
|
+
async function generateChunksetCommitments(shouldPad, chunksetIdx, chunksetData, expectedChunksetSize, provider, onChunk) {
|
|
4451
|
+
const { erasure_n } = provider.config;
|
|
4452
|
+
const chunkCommitments = [];
|
|
4453
|
+
const chunksetPayload = shouldPad ? zeroPadBytes(chunksetData, expectedChunksetSize) : validatePrePaddedChunkset(
|
|
4454
|
+
chunksetData,
|
|
4455
|
+
expectedChunksetSize,
|
|
4456
|
+
chunksetIdx
|
|
4457
|
+
);
|
|
4458
|
+
const { chunks } = provider.encode(chunksetPayload);
|
|
4459
|
+
if (chunks.length !== erasure_n) {
|
|
4460
|
+
throw new Error(
|
|
4461
|
+
`Erasure provider produced ${chunks.length} chunks, expected ${erasure_n}.`
|
|
4462
|
+
);
|
|
4463
|
+
}
|
|
4464
|
+
let chunkIdx = 0;
|
|
4465
|
+
for (const chunkData of chunks) {
|
|
4466
|
+
if (onChunk !== void 0) {
|
|
4467
|
+
await onChunk(chunksetIdx, chunkIdx, chunkData);
|
|
4468
|
+
}
|
|
4469
|
+
const chunkHash = await concatHashes([chunkData]);
|
|
4470
|
+
chunkCommitments.push(chunkHash);
|
|
4471
|
+
chunkIdx += 1;
|
|
4472
|
+
}
|
|
4473
|
+
const h = await concatHashes(
|
|
4474
|
+
chunkCommitments.map((chunk) => chunk.toUint8Array())
|
|
4475
|
+
);
|
|
4476
|
+
const entry = {
|
|
4477
|
+
chunkset_root: h.toString(),
|
|
4478
|
+
chunk_commitments: chunkCommitments.map((chunk) => chunk.toString())
|
|
4479
|
+
};
|
|
4480
|
+
return { h, entry };
|
|
4481
|
+
}
|
|
4482
|
+
async function generateCommitments(provider, fullData, onChunk, options) {
|
|
4483
|
+
const expectedChunksetSize = DEFAULT_CHUNKSET_SIZE_BYTES;
|
|
4484
|
+
const shouldPad = options?.pad ?? true;
|
|
4485
|
+
const chunksetCommitments = [];
|
|
4486
|
+
const chunksetCommitmentHashes = [];
|
|
4487
|
+
let rawDataSize = 0;
|
|
4488
|
+
const chunksetGen = readInChunks(fullData, expectedChunksetSize);
|
|
4489
|
+
for await (const [chunksetIdx, chunksetData] of chunksetGen) {
|
|
4490
|
+
rawDataSize += chunksetData.length;
|
|
4491
|
+
const { h, entry } = await generateChunksetCommitments(
|
|
4492
|
+
shouldPad,
|
|
4493
|
+
chunksetIdx,
|
|
4494
|
+
chunksetData,
|
|
4495
|
+
expectedChunksetSize,
|
|
4496
|
+
provider,
|
|
4497
|
+
onChunk
|
|
4498
|
+
);
|
|
4499
|
+
chunksetCommitments.push(entry);
|
|
4500
|
+
chunksetCommitmentHashes.push(h);
|
|
4501
|
+
}
|
|
4502
|
+
if (rawDataSize === 0) {
|
|
4503
|
+
const zeroChunkset = new Uint8Array(expectedChunksetSize);
|
|
4504
|
+
const { h, entry } = await generateChunksetCommitments(
|
|
4505
|
+
shouldPad,
|
|
4506
|
+
0,
|
|
4507
|
+
zeroChunkset,
|
|
4508
|
+
expectedChunksetSize,
|
|
4509
|
+
provider,
|
|
4510
|
+
onChunk
|
|
4511
|
+
);
|
|
4512
|
+
chunksetCommitments.push(entry);
|
|
4513
|
+
chunksetCommitmentHashes.push(h);
|
|
4514
|
+
}
|
|
4515
|
+
return {
|
|
4516
|
+
schema_version: "1.3",
|
|
4517
|
+
raw_data_size: rawDataSize,
|
|
4518
|
+
blob_merkle_root: (await concatHashes(
|
|
4519
|
+
chunksetCommitmentHashes.map((chunk) => chunk.toUint8Array())
|
|
4520
|
+
)).toString(),
|
|
4521
|
+
chunkset_commitments: chunksetCommitments
|
|
4522
|
+
};
|
|
4523
|
+
}
|
|
4524
|
+
function validatePrePaddedChunkset(chunkset, expectedSize, chunksetIdx) {
|
|
4525
|
+
if (chunkset.byteLength !== expectedSize) {
|
|
4526
|
+
throw new Error(
|
|
4527
|
+
`Chunkset ${chunksetIdx} has size ${chunkset.byteLength} bytes but expected ${expectedSize} bytes. Enable padding or supply pre-padded data before calling generateCommitments.`
|
|
4528
|
+
);
|
|
4529
|
+
}
|
|
4530
|
+
return chunkset;
|
|
4531
|
+
}
|
|
4532
|
+
|
|
4533
|
+
// ../../packages/sdk/dist/chunk-MEINKPI3.mjs
|
|
4534
|
+
import {
|
|
4535
|
+
AccountAddress as AccountAddress5,
|
|
4536
|
+
Aptos as Aptos2,
|
|
4537
|
+
AptosConfig as AptosConfig2,
|
|
4538
|
+
Hex as Hex3,
|
|
4539
|
+
MoveVector
|
|
4540
|
+
} from "@aptos-labs/ts-sdk";
|
|
4541
|
+
var ShelbyBlobClient = class _ShelbyBlobClient {
|
|
4542
|
+
aptos;
|
|
4543
|
+
deployer;
|
|
4544
|
+
indexer;
|
|
4545
|
+
/**
|
|
4546
|
+
* The ShelbyBlobClient is used to interact with the Shelby contract on the Aptos blockchain. This
|
|
4547
|
+
* includes functions for registering blob commitments and retrieving blob metadata.
|
|
4548
|
+
*
|
|
4549
|
+
* @param config - The client configuration object.
|
|
4550
|
+
* @param config.network - The Shelby network to use.
|
|
4551
|
+
*
|
|
4552
|
+
* @example
|
|
4553
|
+
* ```typescript
|
|
4554
|
+
* const blobClient = new ShelbyBlobClient({
|
|
4555
|
+
* aptos: {
|
|
4556
|
+
* network: Network.SHELBYNET,
|
|
4557
|
+
* clientConfig: {
|
|
4558
|
+
* API_KEY: "AG-***",
|
|
4559
|
+
* },
|
|
4560
|
+
* },
|
|
4561
|
+
* });
|
|
4562
|
+
* ```
|
|
4280
4563
|
*/
|
|
4281
4564
|
constructor(config) {
|
|
4282
4565
|
const baseAptosConfig = getAptosConfig(config);
|
|
@@ -4288,8 +4571,8 @@ var ShelbyBlobClient = class _ShelbyBlobClient {
|
|
|
4288
4571
|
API_KEY: baseAptosConfig.clientConfig?.API_KEY ?? config.apiKey
|
|
4289
4572
|
}
|
|
4290
4573
|
});
|
|
4291
|
-
this.aptos = new
|
|
4292
|
-
this.deployer = config.deployer ??
|
|
4574
|
+
this.aptos = new Aptos2(aptosConfig);
|
|
4575
|
+
this.deployer = config.deployer ?? AccountAddress5.fromString(SHELBY_DEPLOYER);
|
|
4293
4576
|
this.indexer = getShelbyIndexerClient(config);
|
|
4294
4577
|
}
|
|
4295
4578
|
/**
|
|
@@ -4338,15 +4621,15 @@ var ShelbyBlobClient = class _ShelbyBlobClient {
|
|
|
4338
4621
|
);
|
|
4339
4622
|
}
|
|
4340
4623
|
return {
|
|
4341
|
-
blobMerkleRoot:
|
|
4624
|
+
blobMerkleRoot: Hex3.fromHexInput(
|
|
4342
4625
|
metadata.blob_commitment
|
|
4343
4626
|
).toUint8Array(),
|
|
4344
|
-
owner:
|
|
4627
|
+
owner: AccountAddress5.fromString(metadata.owner),
|
|
4345
4628
|
name: params.name,
|
|
4346
4629
|
size: Number(metadata.blob_size),
|
|
4347
4630
|
encoding,
|
|
4348
4631
|
expirationMicros: metadata.expiration_micros,
|
|
4349
|
-
sliceAddress:
|
|
4632
|
+
sliceAddress: AccountAddress5.fromString(metadata.slice.inner),
|
|
4350
4633
|
isWritten: metadata.is_written
|
|
4351
4634
|
};
|
|
4352
4635
|
} catch (error) {
|
|
@@ -4378,7 +4661,7 @@ var ShelbyBlobClient = class _ShelbyBlobClient {
|
|
|
4378
4661
|
return this.getBlobs({
|
|
4379
4662
|
where: {
|
|
4380
4663
|
...params.where,
|
|
4381
|
-
owner: { _eq:
|
|
4664
|
+
owner: { _eq: AccountAddress5.from(params.account).toString() }
|
|
4382
4665
|
},
|
|
4383
4666
|
pagination: params.pagination,
|
|
4384
4667
|
orderBy: params.orderBy
|
|
@@ -4411,9 +4694,9 @@ var ShelbyBlobClient = class _ShelbyBlobClient {
|
|
|
4411
4694
|
});
|
|
4412
4695
|
return blobs.map(
|
|
4413
4696
|
(blob) => ({
|
|
4414
|
-
owner:
|
|
4697
|
+
owner: AccountAddress5.from(blob.owner),
|
|
4415
4698
|
name: blob.blob_name,
|
|
4416
|
-
blobMerkleRoot:
|
|
4699
|
+
blobMerkleRoot: Hex3.fromHexInput(blob.blob_commitment).toUint8Array(),
|
|
4417
4700
|
size: Number(blob.size),
|
|
4418
4701
|
// TODO: Add encoding when supported in NCI
|
|
4419
4702
|
encoding: {
|
|
@@ -4422,7 +4705,7 @@ var ShelbyBlobClient = class _ShelbyBlobClient {
|
|
|
4422
4705
|
...ERASURE_CODE_AND_CHUNK_MAPPING.ClayCode_16Total_10Data_13Helper
|
|
4423
4706
|
},
|
|
4424
4707
|
expirationMicros: Number(blob.expires_at),
|
|
4425
|
-
sliceAddress:
|
|
4708
|
+
sliceAddress: AccountAddress5.from(blob.slice_address),
|
|
4426
4709
|
isWritten: Boolean(Number(blob.is_written))
|
|
4427
4710
|
})
|
|
4428
4711
|
);
|
|
@@ -4445,7 +4728,7 @@ var ShelbyBlobClient = class _ShelbyBlobClient {
|
|
|
4445
4728
|
return blob_activities.map(
|
|
4446
4729
|
(activity) => ({
|
|
4447
4730
|
blobName: activity.blob_name,
|
|
4448
|
-
accountAddress:
|
|
4731
|
+
accountAddress: AccountAddress5.from(
|
|
4449
4732
|
activity.blob_name.substring(1, 65)
|
|
4450
4733
|
),
|
|
4451
4734
|
type: activityTypeMapping[activity.event_type] ?? "unknown",
|
|
@@ -4513,380 +4796,104 @@ var ShelbyBlobClient = class _ShelbyBlobClient {
|
|
|
4513
4796
|
const chunksetSize = params.options?.chunksetSizeBytes ?? DEFAULT_CHUNKSET_SIZE_BYTES;
|
|
4514
4797
|
const transaction = await this.aptos.transaction.build.simple({
|
|
4515
4798
|
...params.options?.build,
|
|
4516
|
-
data: _ShelbyBlobClient.createRegisterBlobPayload({
|
|
4517
|
-
deployer: this.deployer,
|
|
4518
|
-
account: params.account.accountAddress,
|
|
4519
|
-
blobName: params.blobName,
|
|
4520
|
-
blobSize: params.size,
|
|
4521
|
-
blobMerkleRoot: params.blobMerkleRoot,
|
|
4522
|
-
numChunksets: expectedTotalChunksets(params.size, chunksetSize),
|
|
4523
|
-
expirationMicros: params.expirationMicros
|
|
4524
|
-
}),
|
|
4525
|
-
sender: params.account.accountAddress
|
|
4526
|
-
});
|
|
4527
|
-
return {
|
|
4528
|
-
transaction: await this.aptos.signAndSubmitTransaction({
|
|
4529
|
-
signer: params.account,
|
|
4530
|
-
transaction
|
|
4531
|
-
})
|
|
4532
|
-
};
|
|
4533
|
-
}
|
|
4534
|
-
/**
|
|
4535
|
-
* Creates a transaction payload to register a blob on the blockchain.
|
|
4536
|
-
* This is a static helper method for constructing the Move function call payload.
|
|
4537
|
-
*
|
|
4538
|
-
* @param params.deployer - Optional deployer account address. Defaults to SHELBY_DEPLOYER.
|
|
4539
|
-
* @param params.account - The account that will own the blob.
|
|
4540
|
-
* @param params.blobName - The name/path of the blob (e.g. "foo/bar.txt").
|
|
4541
|
-
* @param params.blobSize - The size of the blob in bytes.
|
|
4542
|
-
* @param params.blobMerkleRoot - The merkle root of the blob commitments as a hex string.
|
|
4543
|
-
* @param params.expirationMicros - The expiration time of the blob in microseconds.
|
|
4544
|
-
* @param params.numChunksets - The total number of chunksets in the blob.
|
|
4545
|
-
*
|
|
4546
|
-
* @returns An Aptos transaction payload data object for the register_blob Move function.
|
|
4547
|
-
*
|
|
4548
|
-
* @see https://github.com/shelby/shelby/blob/e08e84742cf2b80ad8bb7227deb3013398076d53/move/shelby_contract/sources/global_metadata.move#L357
|
|
4549
|
-
*/
|
|
4550
|
-
static createRegisterBlobPayload(params) {
|
|
4551
|
-
return {
|
|
4552
|
-
function: `${(params.deployer ?? SHELBY_DEPLOYER).toString()}::global_metadata::register_blob`,
|
|
4553
|
-
functionArguments: [
|
|
4554
|
-
params.blobName,
|
|
4555
|
-
params.expirationMicros,
|
|
4556
|
-
MoveVector.U8(params.blobMerkleRoot),
|
|
4557
|
-
params.numChunksets,
|
|
4558
|
-
params.blobSize,
|
|
4559
|
-
// TODO
|
|
4560
|
-
0,
|
|
4561
|
-
// payment tier
|
|
4562
|
-
0
|
|
4563
|
-
// encoding
|
|
4564
|
-
]
|
|
4565
|
-
};
|
|
4566
|
-
}
|
|
4567
|
-
/**
|
|
4568
|
-
* Creates a transaction payload to register multiple blobs on the blockchain.
|
|
4569
|
-
* This is a static helper method for constructing the Move function call payload.
|
|
4570
|
-
*
|
|
4571
|
-
* @param params.deployer - Optional deployer account address. Defaults to SHELBY_DEPLOYER.
|
|
4572
|
-
* @param params.account - The account that will own the blobs.
|
|
4573
|
-
* @param params.expirationMicros - The expiration time of the blobs in microseconds.
|
|
4574
|
-
* @param params.blobs - The blobs to register.
|
|
4575
|
-
* @param params.blobs.blobName - The name/path of the blob (e.g. "foo/bar.txt").
|
|
4576
|
-
* @param params.blobs.blobSize - The size of the blob in bytes.
|
|
4577
|
-
* @param params.blobs.blobMerkleRoot - The merkle root of the blob commitments as a hex string.
|
|
4578
|
-
* @param params.blobs.numChunksets - The total number of chunksets in the blob.
|
|
4579
|
-
*
|
|
4580
|
-
* @returns An Aptos transaction payload data object for the register_multiple_blobs Move function.
|
|
4581
|
-
*
|
|
4582
|
-
* @see https://github.com/shelby/shelby/blob/e08e84742cf2b80ad8bb7227deb3013398076d53/move/shelby_contract/sources/global_metadata.move#L357
|
|
4583
|
-
*/
|
|
4584
|
-
static createBatchRegisterBlobsPayload(params) {
|
|
4585
|
-
const blobNames = [];
|
|
4586
|
-
const blobMerkleRoots = [];
|
|
4587
|
-
const blobNumChunksets = [];
|
|
4588
|
-
const blobSizes = [];
|
|
4589
|
-
params.blobs.forEach((blob) => {
|
|
4590
|
-
blobNames.push(blob.blobName);
|
|
4591
|
-
blobMerkleRoots.push(MoveVector.U8(blob.blobMerkleRoot));
|
|
4592
|
-
blobNumChunksets.push(blob.numChunksets);
|
|
4593
|
-
blobSizes.push(blob.blobSize);
|
|
4594
|
-
});
|
|
4595
|
-
return {
|
|
4596
|
-
function: `${(params.deployer ?? SHELBY_DEPLOYER).toString()}::global_metadata::register_multiple_blobs`,
|
|
4597
|
-
functionArguments: [
|
|
4598
|
-
blobNames,
|
|
4599
|
-
params.expirationMicros,
|
|
4600
|
-
blobMerkleRoots,
|
|
4601
|
-
blobNumChunksets,
|
|
4602
|
-
blobSizes,
|
|
4603
|
-
// TODO
|
|
4604
|
-
0,
|
|
4605
|
-
0
|
|
4606
|
-
]
|
|
4607
|
-
};
|
|
4608
|
-
}
|
|
4609
|
-
};
|
|
4610
|
-
|
|
4611
|
-
// ../../packages/sdk/dist/chunk-FIFKKWXV.mjs
|
|
4612
|
-
import { AccountAddress as AccountAddress3 } from "@aptos-labs/ts-sdk";
|
|
4613
|
-
import { z as z2 } from "zod";
|
|
4614
|
-
var BlobNameSchema = z2.string().min(1, "Blob name path parameter cannot be empty.").max(1024, "Blob name cannot exceed 1024 characters.").refine((name) => !name.endsWith("/"), {
|
|
4615
|
-
message: "Blob name cannot end with a slash"
|
|
4616
|
-
});
|
|
4617
|
-
|
|
4618
|
-
// ../../packages/sdk/dist/chunk-I6NG5GNL.mjs
|
|
4619
|
-
function sleep(ms) {
|
|
4620
|
-
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
4621
|
-
}
|
|
4622
|
-
|
|
4623
|
-
// ../../packages/sdk/dist/chunk-GKRHKR3J.mjs
|
|
4624
|
-
import { AccountAddress as AccountAddress4 } from "@aptos-labs/ts-sdk";
|
|
4625
|
-
function encodeURIComponentKeepSlashes(str) {
|
|
4626
|
-
return encodeURIComponent(str).replace(/%2F/g, "/");
|
|
4627
|
-
}
|
|
4628
|
-
var ShelbyRPCClient = class {
|
|
4629
|
-
baseUrl;
|
|
4630
|
-
apiKey;
|
|
4631
|
-
rpcConfig;
|
|
4632
|
-
indexer;
|
|
4633
|
-
/**
|
|
4634
|
-
* Creates a new ShelbyRPCClient for interacting with Shelby RPC nodes.
|
|
4635
|
-
* This client handles blob storage operations including upload and download.
|
|
4636
|
-
*
|
|
4637
|
-
* @param config - The client configuration object.
|
|
4638
|
-
* @param config.network - The Shelby network to use.
|
|
4639
|
-
*
|
|
4640
|
-
* @example
|
|
4641
|
-
* ```typescript
|
|
4642
|
-
* const client = new ShelbyRPCClient({
|
|
4643
|
-
* network: Network.SHELBYNET,
|
|
4644
|
-
* apiKey: "AG-***",
|
|
4645
|
-
* });
|
|
4646
|
-
* ```
|
|
4647
|
-
*/
|
|
4648
|
-
constructor(config) {
|
|
4649
|
-
this.baseUrl = config.rpc?.baseUrl ?? NetworkToShelbyRPCBaseUrl.shelbynet;
|
|
4650
|
-
this.apiKey = config.apiKey ?? config.rpc?.apiKey;
|
|
4651
|
-
this.rpcConfig = config.rpc ?? {};
|
|
4652
|
-
this.indexer = getShelbyIndexerClient(config);
|
|
4653
|
-
}
|
|
4654
|
-
async #uploadPart(uploadId, partIdx, partData) {
|
|
4655
|
-
const nRetries = 5;
|
|
4656
|
-
for (let i = 0; i < nRetries; ++i) {
|
|
4657
|
-
const partResponse = await fetch(
|
|
4658
|
-
buildRequestUrl(
|
|
4659
|
-
`/v1/multipart-uploads/${uploadId}/parts/${partIdx}`,
|
|
4660
|
-
this.baseUrl
|
|
4661
|
-
),
|
|
4662
|
-
{
|
|
4663
|
-
method: "PUT",
|
|
4664
|
-
headers: {
|
|
4665
|
-
"Content-Type": "application/octet-stream",
|
|
4666
|
-
...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
|
|
4667
|
-
},
|
|
4668
|
-
body: partData
|
|
4669
|
-
}
|
|
4670
|
-
);
|
|
4671
|
-
if (partResponse.ok) return;
|
|
4672
|
-
if (i < nRetries - 1) {
|
|
4673
|
-
const delay = 2 ** i * 100;
|
|
4674
|
-
await sleep(delay);
|
|
4675
|
-
}
|
|
4676
|
-
}
|
|
4677
|
-
throw new Error(`Failed to upload part ${partIdx}.`);
|
|
4678
|
-
}
|
|
4679
|
-
async #putBlobMultipart(account, blobName, blobData, partSize = 5 * 1024 * 1024) {
|
|
4680
|
-
const startResponse = await fetch(
|
|
4681
|
-
buildRequestUrl("/v1/multipart-uploads", this.baseUrl),
|
|
4682
|
-
{
|
|
4683
|
-
method: "POST",
|
|
4684
|
-
headers: {
|
|
4685
|
-
"Content-Type": "application/json",
|
|
4686
|
-
...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
|
|
4687
|
-
},
|
|
4688
|
-
body: JSON.stringify({
|
|
4689
|
-
rawAccount: account.toString(),
|
|
4690
|
-
rawBlobName: blobName,
|
|
4691
|
-
rawPartSize: partSize
|
|
4692
|
-
})
|
|
4693
|
-
}
|
|
4694
|
-
);
|
|
4695
|
-
if (!startResponse.ok) {
|
|
4696
|
-
let errorBodyText = "Could not read error body";
|
|
4697
|
-
try {
|
|
4698
|
-
errorBodyText = await startResponse.text();
|
|
4699
|
-
} catch (_e) {
|
|
4700
|
-
}
|
|
4701
|
-
throw new Error(
|
|
4702
|
-
`Failed to start multipart upload! status: ${startResponse.status}, body: ${errorBodyText}`
|
|
4703
|
-
);
|
|
4704
|
-
}
|
|
4705
|
-
const { uploadId } = await startResponse.json();
|
|
4706
|
-
const totalParts = Math.ceil(blobData.length / partSize);
|
|
4707
|
-
for (let partIdx = 0; partIdx < totalParts; partIdx++) {
|
|
4708
|
-
const start = partIdx * partSize;
|
|
4709
|
-
const end = Math.min(start + partSize, blobData.length);
|
|
4710
|
-
const partData = blobData.slice(start, end);
|
|
4711
|
-
await this.#uploadPart(uploadId, partIdx, partData);
|
|
4712
|
-
}
|
|
4713
|
-
const completeResponse = await fetch(
|
|
4714
|
-
buildRequestUrl(
|
|
4715
|
-
`/v1/multipart-uploads/${uploadId}/complete`,
|
|
4716
|
-
this.baseUrl
|
|
4717
|
-
),
|
|
4718
|
-
{
|
|
4719
|
-
method: "POST",
|
|
4720
|
-
headers: {
|
|
4721
|
-
"Content-Type": "application/json",
|
|
4722
|
-
...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
|
|
4723
|
-
}
|
|
4724
|
-
}
|
|
4725
|
-
);
|
|
4726
|
-
if (!completeResponse.ok) {
|
|
4727
|
-
let errorBodyText = "Could not read error body";
|
|
4728
|
-
try {
|
|
4729
|
-
errorBodyText = await completeResponse.text();
|
|
4730
|
-
} catch (_e) {
|
|
4731
|
-
}
|
|
4732
|
-
throw new Error(
|
|
4733
|
-
`Failed to complete multipart upload! status: ${completeResponse.status}, body: ${errorBodyText}`
|
|
4734
|
-
);
|
|
4735
|
-
}
|
|
4799
|
+
data: _ShelbyBlobClient.createRegisterBlobPayload({
|
|
4800
|
+
deployer: this.deployer,
|
|
4801
|
+
account: params.account.accountAddress,
|
|
4802
|
+
blobName: params.blobName,
|
|
4803
|
+
blobSize: params.size,
|
|
4804
|
+
blobMerkleRoot: params.blobMerkleRoot,
|
|
4805
|
+
numChunksets: expectedTotalChunksets(params.size, chunksetSize),
|
|
4806
|
+
expirationMicros: params.expirationMicros
|
|
4807
|
+
}),
|
|
4808
|
+
sender: params.account.accountAddress
|
|
4809
|
+
});
|
|
4810
|
+
return {
|
|
4811
|
+
transaction: await this.aptos.signAndSubmitTransaction({
|
|
4812
|
+
signer: params.account,
|
|
4813
|
+
transaction
|
|
4814
|
+
})
|
|
4815
|
+
};
|
|
4736
4816
|
}
|
|
4737
4817
|
/**
|
|
4738
|
-
*
|
|
4739
|
-
* This
|
|
4740
|
-
* Uses multipart upload for efficient handling of large files.
|
|
4818
|
+
* Creates a transaction payload to register a blob on the blockchain.
|
|
4819
|
+
* This is a static helper method for constructing the Move function call payload.
|
|
4741
4820
|
*
|
|
4742
|
-
* @param params.
|
|
4743
|
-
* @param params.
|
|
4744
|
-
* @param params.
|
|
4821
|
+
* @param params.deployer - Optional deployer account address. Defaults to SHELBY_DEPLOYER.
|
|
4822
|
+
* @param params.account - The account that will own the blob.
|
|
4823
|
+
* @param params.blobName - The name/path of the blob (e.g. "foo/bar.txt").
|
|
4824
|
+
* @param params.blobSize - The size of the blob in bytes.
|
|
4825
|
+
* @param params.blobMerkleRoot - The merkle root of the blob commitments as a hex string.
|
|
4826
|
+
* @param params.expirationMicros - The expiration time of the blob in microseconds.
|
|
4827
|
+
* @param params.numChunksets - The total number of chunksets in the blob.
|
|
4745
4828
|
*
|
|
4746
|
-
* @
|
|
4747
|
-
* ```typescript
|
|
4748
|
-
* const blobData = new TextEncoder().encode("Hello, world!");
|
|
4829
|
+
* @returns An Aptos transaction payload data object for the register_blob Move function.
|
|
4749
4830
|
*
|
|
4750
|
-
*
|
|
4751
|
-
* account: AccountAddress.from("0x1"),
|
|
4752
|
-
* blobName: "greetings/hello.txt",
|
|
4753
|
-
* blobData
|
|
4754
|
-
* });
|
|
4755
|
-
* ```
|
|
4831
|
+
* @see https://github.com/shelby/shelby/blob/e08e84742cf2b80ad8bb7227deb3013398076d53/move/shelby_contract/sources/global_metadata.move#L357
|
|
4756
4832
|
*/
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4833
|
+
static createRegisterBlobPayload(params) {
|
|
4834
|
+
return {
|
|
4835
|
+
function: `${(params.deployer ?? SHELBY_DEPLOYER).toString()}::global_metadata::register_blob`,
|
|
4836
|
+
functionArguments: [
|
|
4837
|
+
params.blobName,
|
|
4838
|
+
params.expirationMicros,
|
|
4839
|
+
MoveVector.U8(params.blobMerkleRoot),
|
|
4840
|
+
params.numChunksets,
|
|
4841
|
+
params.blobSize,
|
|
4842
|
+
// TODO
|
|
4843
|
+
0,
|
|
4844
|
+
// payment tier
|
|
4845
|
+
0
|
|
4846
|
+
// encoding
|
|
4847
|
+
]
|
|
4848
|
+
};
|
|
4764
4849
|
}
|
|
4765
|
-
// FIXME make this possible to stream in put ^^^
|
|
4766
4850
|
/**
|
|
4767
|
-
*
|
|
4768
|
-
*
|
|
4769
|
-
*
|
|
4770
|
-
* @param params.account - The account that owns the blob.
|
|
4771
|
-
* @param params.blobName - The name/path of the blob (e.g. "folder/file.txt").
|
|
4772
|
-
* @param params.range - Optional byte range for partial downloads.
|
|
4773
|
-
* @param params.range.start - Starting byte position (inclusive).
|
|
4774
|
-
* @param params.range.end - Ending byte position (inclusive, optional).
|
|
4775
|
-
*
|
|
4776
|
-
* @returns A ShelbyBlob object containing the account, name, readable stream, and content length.
|
|
4851
|
+
* Creates a transaction payload to register multiple blobs on the blockchain.
|
|
4852
|
+
* This is a static helper method for constructing the Move function call payload.
|
|
4777
4853
|
*
|
|
4778
|
-
* @
|
|
4854
|
+
* @param params.deployer - Optional deployer account address. Defaults to SHELBY_DEPLOYER.
|
|
4855
|
+
* @param params.account - The account that will own the blobs.
|
|
4856
|
+
* @param params.expirationMicros - The expiration time of the blobs in microseconds.
|
|
4857
|
+
* @param params.blobs - The blobs to register.
|
|
4858
|
+
* @param params.blobs.blobName - The name/path of the blob (e.g. "foo/bar.txt").
|
|
4859
|
+
* @param params.blobs.blobSize - The size of the blob in bytes.
|
|
4860
|
+
* @param params.blobs.blobMerkleRoot - The merkle root of the blob commitments as a hex string.
|
|
4861
|
+
* @param params.blobs.numChunksets - The total number of chunksets in the blob.
|
|
4779
4862
|
*
|
|
4780
|
-
* @
|
|
4781
|
-
* ```typescript
|
|
4782
|
-
* // Download entire blob
|
|
4783
|
-
* const blob = await client.getBlob({
|
|
4784
|
-
* account: AccountAddress.from("0x1"),
|
|
4785
|
-
* blobName: "documents/report.pdf"
|
|
4786
|
-
* });
|
|
4863
|
+
* @returns An Aptos transaction payload data object for the register_multiple_blobs Move function.
|
|
4787
4864
|
*
|
|
4788
|
-
*
|
|
4789
|
-
* const partial = await client.getBlob({
|
|
4790
|
-
* account: AccountAddress.from("0x1"),
|
|
4791
|
-
* blobName: "large-file.bin",
|
|
4792
|
-
* range: { start: 100, end: 199 }
|
|
4793
|
-
* });
|
|
4794
|
-
* ```
|
|
4865
|
+
* @see https://github.com/shelby/shelby/blob/e08e84742cf2b80ad8bb7227deb3013398076d53/move/shelby_contract/sources/global_metadata.move#L357
|
|
4795
4866
|
*/
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
const
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
const headers = new Headers();
|
|
4807
|
-
const { start, end } = params.range;
|
|
4808
|
-
if (end === void 0) {
|
|
4809
|
-
headers.set("Range", `bytes=${start}-`);
|
|
4810
|
-
} else {
|
|
4811
|
-
if (end < start) {
|
|
4812
|
-
throw new Error("Range end cannot be less than start.");
|
|
4813
|
-
}
|
|
4814
|
-
headers.set("Range", `bytes=${start}-${end}`);
|
|
4815
|
-
}
|
|
4816
|
-
requestInit.headers = headers;
|
|
4817
|
-
}
|
|
4818
|
-
const response = await fetch(url, {
|
|
4819
|
-
...requestInit,
|
|
4820
|
-
headers: {
|
|
4821
|
-
...requestInit.headers,
|
|
4822
|
-
...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
|
|
4823
|
-
}
|
|
4824
|
-
});
|
|
4825
|
-
if (!response.ok) {
|
|
4826
|
-
throw new Error(
|
|
4827
|
-
`Failed to download blob: ${response.status} ${response.statusText}`
|
|
4828
|
-
);
|
|
4829
|
-
}
|
|
4830
|
-
if (!response.body) {
|
|
4831
|
-
throw new Error("Response body is null");
|
|
4832
|
-
}
|
|
4833
|
-
const contentLengthHeader = response.headers.get("content-length");
|
|
4834
|
-
if (contentLengthHeader === null) {
|
|
4835
|
-
throw new Error(
|
|
4836
|
-
"Response did not have content-length header, which is required"
|
|
4837
|
-
);
|
|
4838
|
-
}
|
|
4839
|
-
const expectedContentLength = Number.parseInt(contentLengthHeader, 10);
|
|
4840
|
-
if (Number.isNaN(expectedContentLength)) {
|
|
4841
|
-
throw new Error(
|
|
4842
|
-
`Invalid content-length header received: ${contentLengthHeader}`
|
|
4843
|
-
);
|
|
4844
|
-
}
|
|
4845
|
-
const validatingStream = new ReadableStream({
|
|
4846
|
-
start(controller) {
|
|
4847
|
-
const maybeReader = response.body?.getReader();
|
|
4848
|
-
if (!maybeReader) {
|
|
4849
|
-
controller.error(new Error("Response body reader is unavailable"));
|
|
4850
|
-
return;
|
|
4851
|
-
}
|
|
4852
|
-
const reader = maybeReader;
|
|
4853
|
-
let bytesReceived = 0;
|
|
4854
|
-
function pump() {
|
|
4855
|
-
return reader.read().then(({ done, value }) => {
|
|
4856
|
-
if (done) {
|
|
4857
|
-
if (bytesReceived !== expectedContentLength) {
|
|
4858
|
-
controller.error(
|
|
4859
|
-
new Error(
|
|
4860
|
-
`Downloaded data size (${bytesReceived} bytes) does not match content-length header (${expectedContentLength} bytes). This might indicate a partial or corrupted download.`
|
|
4861
|
-
)
|
|
4862
|
-
);
|
|
4863
|
-
return;
|
|
4864
|
-
}
|
|
4865
|
-
controller.close();
|
|
4866
|
-
return;
|
|
4867
|
-
}
|
|
4868
|
-
bytesReceived += value.byteLength;
|
|
4869
|
-
controller.enqueue(value);
|
|
4870
|
-
return pump();
|
|
4871
|
-
}).catch((error) => {
|
|
4872
|
-
controller.error(error);
|
|
4873
|
-
});
|
|
4874
|
-
}
|
|
4875
|
-
return pump();
|
|
4876
|
-
}
|
|
4867
|
+
static createBatchRegisterBlobsPayload(params) {
|
|
4868
|
+
const blobNames = [];
|
|
4869
|
+
const blobMerkleRoots = [];
|
|
4870
|
+
const blobNumChunksets = [];
|
|
4871
|
+
const blobSizes = [];
|
|
4872
|
+
params.blobs.forEach((blob) => {
|
|
4873
|
+
blobNames.push(blob.blobName);
|
|
4874
|
+
blobMerkleRoots.push(MoveVector.U8(blob.blobMerkleRoot));
|
|
4875
|
+
blobNumChunksets.push(blob.numChunksets);
|
|
4876
|
+
blobSizes.push(blob.blobSize);
|
|
4877
4877
|
});
|
|
4878
4878
|
return {
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4879
|
+
function: `${(params.deployer ?? SHELBY_DEPLOYER).toString()}::global_metadata::register_multiple_blobs`,
|
|
4880
|
+
functionArguments: [
|
|
4881
|
+
blobNames,
|
|
4882
|
+
params.expirationMicros,
|
|
4883
|
+
blobMerkleRoots,
|
|
4884
|
+
blobNumChunksets,
|
|
4885
|
+
blobSizes,
|
|
4886
|
+
// TODO
|
|
4887
|
+
0,
|
|
4888
|
+
0
|
|
4889
|
+
]
|
|
4883
4890
|
};
|
|
4884
4891
|
}
|
|
4885
4892
|
};
|
|
4886
4893
|
|
|
4887
|
-
// ../../packages/sdk/dist/chunk-
|
|
4894
|
+
// ../../packages/sdk/dist/chunk-2Y3ZLUYT.mjs
|
|
4888
4895
|
import {
|
|
4889
|
-
Aptos as
|
|
4896
|
+
Aptos as Aptos3
|
|
4890
4897
|
} from "@aptos-labs/ts-sdk";
|
|
4891
4898
|
var ShelbyClient = class {
|
|
4892
4899
|
/**
|
|
@@ -4943,7 +4950,7 @@ var ShelbyClient = class {
|
|
|
4943
4950
|
*/
|
|
4944
4951
|
constructor(config, provider) {
|
|
4945
4952
|
this.config = config;
|
|
4946
|
-
this.aptos = new
|
|
4953
|
+
this.aptos = new Aptos3(getAptosConfig(config));
|
|
4947
4954
|
this.coordination = new ShelbyBlobClient(config);
|
|
4948
4955
|
this.rpc = new ShelbyRPCClient(config);
|
|
4949
4956
|
this._provider = provider;
|
|
@@ -5039,16 +5046,29 @@ var ShelbyClient = class {
|
|
|
5039
5046
|
}
|
|
5040
5047
|
};
|
|
5041
5048
|
|
|
5042
|
-
// ../../packages/sdk/dist/chunk-
|
|
5049
|
+
// ../../packages/sdk/dist/chunk-X56YUBBI.mjs
|
|
5043
5050
|
var ShelbyNodeClient = class extends ShelbyClient {
|
|
5044
5051
|
};
|
|
5045
5052
|
|
|
5046
|
-
// ../../packages/sdk/dist/chunk-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
}
|
|
5053
|
+
// ../../packages/sdk/dist/chunk-7P6ASYW6.mjs
|
|
5054
|
+
var __defProp = Object.defineProperty;
|
|
5055
|
+
var __export = (target, all) => {
|
|
5056
|
+
for (var name in all)
|
|
5057
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5058
|
+
};
|
|
5059
|
+
|
|
5060
|
+
// ../../packages/sdk/dist/chunk-A4IG6GSE.mjs
|
|
5061
|
+
var testUtil_exports = {};
|
|
5062
|
+
__export(testUtil_exports, {
|
|
5063
|
+
makeChunk: () => makeChunk
|
|
5064
|
+
});
|
|
5065
|
+
function makeChunk(n) {
|
|
5066
|
+
const c = Buffer.alloc(n);
|
|
5067
|
+
for (let i = 0; i < n; ++i) {
|
|
5068
|
+
c[i] = i % 256;
|
|
5069
|
+
}
|
|
5070
|
+
return c;
|
|
5071
|
+
}
|
|
5052
5072
|
|
|
5053
5073
|
// ../../packages/sdk/dist/chunk-VRLIOKWG.mjs
|
|
5054
5074
|
import { Network as Network4 } from "@aptos-labs/ts-sdk";
|
|
@@ -5078,26 +5098,6 @@ function getShelbyAccountExplorerUrl(network, accountAddress) {
|
|
|
5078
5098
|
return `${baseUrl}/account/${accountAddress}`;
|
|
5079
5099
|
}
|
|
5080
5100
|
|
|
5081
|
-
// ../../packages/sdk/dist/chunk-7P6ASYW6.mjs
|
|
5082
|
-
var __defProp = Object.defineProperty;
|
|
5083
|
-
var __export = (target, all) => {
|
|
5084
|
-
for (var name in all)
|
|
5085
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5086
|
-
};
|
|
5087
|
-
|
|
5088
|
-
// ../../packages/sdk/dist/chunk-A4IG6GSE.mjs
|
|
5089
|
-
var testUtil_exports = {};
|
|
5090
|
-
__export(testUtil_exports, {
|
|
5091
|
-
makeChunk: () => makeChunk
|
|
5092
|
-
});
|
|
5093
|
-
function makeChunk(n) {
|
|
5094
|
-
const c = Buffer.alloc(n);
|
|
5095
|
-
for (let i = 0; i < n; ++i) {
|
|
5096
|
-
c[i] = i % 256;
|
|
5097
|
-
}
|
|
5098
|
-
return c;
|
|
5099
|
-
}
|
|
5100
|
-
|
|
5101
5101
|
// ../../packages/sdk/dist/chunk-C6RQ3AEU.mjs
|
|
5102
5102
|
import { Network as Network6 } from "@aptos-labs/ts-sdk";
|
|
5103
5103
|
function getAptosExplorerBaseUrl(network) {
|
|
@@ -7888,15 +7888,15 @@ async function createFileList(options, nodeClient, account) {
|
|
|
7888
7888
|
}
|
|
7889
7889
|
const ret = [];
|
|
7890
7890
|
for (const blobMd of matchingBlobList) {
|
|
7891
|
-
|
|
7891
|
+
let blobname;
|
|
7892
|
+
if (options.recursive) {
|
|
7893
|
+
blobname = blobMd.name.slice(1 + 64 + 1);
|
|
7894
|
+
} else {
|
|
7895
|
+
blobname = blobMd.name;
|
|
7896
|
+
}
|
|
7892
7897
|
const entry = {
|
|
7893
|
-
filename: denormBlobName2(
|
|
7894
|
-
|
|
7895
|
-
blobNameWithoutAccount,
|
|
7896
|
-
options.dst
|
|
7897
|
-
),
|
|
7898
|
-
blobname: blobNameWithoutAccount,
|
|
7899
|
-
// FIXME this is nasty
|
|
7898
|
+
filename: denormBlobName2(options.src, blobname, options.dst),
|
|
7899
|
+
blobname,
|
|
7900
7900
|
sizeBytes: blobMd.size
|
|
7901
7901
|
};
|
|
7902
7902
|
ret.push(entry);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shelby-protocol/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.13",
|
|
5
5
|
"private": false,
|
|
6
6
|
"bin": {
|
|
7
7
|
"shelby": "bin/entry.js"
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"wrap-ansi": "^9.0.2",
|
|
40
40
|
"yaml": "^2.7.1",
|
|
41
41
|
"zod": "^3.22.4",
|
|
42
|
-
"@shelby-protocol/
|
|
43
|
-
"@shelby-protocol/
|
|
42
|
+
"@shelby-protocol/clay-codes": "0.0.1",
|
|
43
|
+
"@shelby-protocol/sdk": "0.0.4"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/fs-extra": "^11.0.4",
|