@shelby-protocol/sdk 0.0.1-experimental.3 → 0.0.1
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 +41 -0
- package/dist/browser/index.d.ts +17 -8
- package/dist/browser/index.mjs +83 -34
- package/dist/chunk-3ZDXWPYC.mjs +65 -0
- package/dist/chunk-6MDQI7PW.mjs +177 -0
- package/dist/chunk-75VHXY5P.mjs +48 -0
- package/dist/chunk-APML3CGJ.mjs +176 -0
- package/dist/chunk-DLMDDEWF.mjs +112 -0
- package/dist/{chunk-HMKVGTZV.mjs → chunk-EAPAG4L7.mjs} +1 -1
- package/dist/{chunk-GGYTHP5F.mjs → chunk-FIFKKWXV.mjs} +19 -17
- package/dist/chunk-HPVCKAN2.mjs +41 -0
- package/dist/{chunk-IAHEBEM6.mjs → chunk-JSR44EDC.mjs} +96 -42
- package/dist/chunk-KBUWZXFA.mjs +92 -0
- package/dist/chunk-LTV26KU4.mjs +141 -0
- package/dist/chunk-NTJSNNA7.mjs +175 -0
- package/dist/{chunk-QEMIORTL.mjs → chunk-OTBLZL2S.mjs} +1 -1
- package/dist/chunk-RBFWGDMY.mjs +30 -0
- package/dist/chunk-VRLIOKWG.mjs +11 -0
- package/dist/chunk-XGMJ4CG4.mjs +384 -0
- package/dist/chunk-Z7RFCADT.mjs +0 -0
- package/dist/chunk-ZPW742E7.mjs +28 -0
- package/dist/clay-codes-Ce9EmXfa.d.ts +129 -0
- package/dist/core/blobs.mjs +1 -1
- package/dist/core/chunk.d.ts +34 -0
- package/dist/core/chunk.mjs +17 -0
- package/dist/core/clients/ShelbyBlobClient.d.ts +121 -89
- package/dist/core/clients/ShelbyBlobClient.mjs +11 -3
- package/dist/core/clients/ShelbyClient.d.ts +71 -30
- package/dist/core/clients/ShelbyClient.mjs +14 -9
- package/dist/core/clients/ShelbyClientConfig.d.ts +43 -9
- package/dist/core/clients/ShelbyClientConfig.mjs +1 -0
- package/dist/core/clients/ShelbyRPCClient.d.ts +47 -20
- package/dist/core/clients/ShelbyRPCClient.mjs +10 -3
- package/dist/core/clients/index.d.ts +10 -5
- package/dist/core/clients/index.mjs +16 -10
- package/dist/core/clients/utils.d.ts +7 -0
- package/dist/core/clients/utils.mjs +7 -0
- package/dist/core/commitments.d.ts +18 -18
- package/dist/core/commitments.mjs +7 -5
- package/dist/core/constants.d.ts +24 -19
- package/dist/core/constants.mjs +15 -15
- package/dist/core/erasure/clay-codes.d.ts +2 -0
- package/dist/core/erasure/clay-codes.mjs +9 -0
- package/dist/core/erasure/constants.d.ts +48 -0
- package/dist/core/erasure/constants.mjs +17 -0
- package/dist/core/erasure/default.d.ts +6 -0
- package/dist/core/erasure/default.mjs +9 -0
- package/dist/core/erasure/index.d.ts +4 -0
- package/dist/core/erasure/index.mjs +27 -0
- package/dist/core/erasure/provider.d.ts +2 -0
- package/dist/core/erasure/provider.mjs +0 -0
- package/dist/core/erasure/reed-solomon.d.ts +2 -0
- package/dist/core/erasure/reed-solomon.mjs +7 -0
- package/dist/core/erasure/utils.d.ts +12 -0
- package/dist/core/erasure/utils.mjs +33 -0
- package/dist/core/index.d.ts +17 -8
- package/dist/core/index.mjs +83 -34
- package/dist/core/layout.mjs +4 -2
- package/dist/core/networks.d.ts +7 -0
- package/dist/core/networks.mjs +9 -0
- package/dist/core/operations/generated/sdk.d.ts +686 -0
- package/dist/core/operations/generated/sdk.mjs +23 -0
- package/dist/core/operations/index.d.ts +31 -0
- package/dist/core/operations/index.mjs +12 -0
- package/dist/core/strings.d.ts +6 -0
- package/dist/core/strings.mjs +9 -0
- package/dist/core/types/blobs.d.ts +49 -79
- package/dist/core/types/encodings.d.ts +5 -13
- package/dist/core/types/encodings.mjs +0 -1
- package/dist/core/types/index.d.ts +4 -2
- package/dist/core/types/index.mjs +1 -1
- package/dist/core/types/placement_groups.d.ts +15 -0
- package/dist/core/types/placement_groups.mjs +0 -0
- package/dist/core/types/storage_providers.d.ts +31 -0
- package/dist/core/types/storage_providers.mjs +1 -0
- package/dist/core/utils.d.ts +15 -3
- package/dist/core/utils.mjs +5 -3
- package/dist/node/clients/ShelbyMetadataClient.d.ts +72 -0
- package/dist/node/clients/ShelbyMetadataClient.mjs +9 -0
- package/dist/node/clients/ShelbyNodeClient.d.ts +8 -3
- package/dist/node/clients/ShelbyNodeClient.mjs +15 -10
- package/dist/node/clients/index.d.ts +12 -5
- package/dist/node/clients/index.mjs +20 -11
- package/dist/node/index.d.ts +18 -8
- package/dist/node/index.mjs +89 -36
- package/package.json +25 -12
- package/dist/chunk-5Z3RVWU3.mjs +0 -67
- package/dist/chunk-B3CB2YEO.mjs +0 -318
- package/dist/chunk-D2FERD4A.mjs +0 -39
- package/dist/chunk-G263DBCY.mjs +0 -105
- package/dist/chunk-P7BVGLTV.mjs +0 -32
- package/dist/chunk-RYJCDQEK.mjs +0 -109
- package/dist/core/erasure.d.ts +0 -6
- package/dist/core/erasure.mjs +0 -7
- /package/dist/{chunk-7S6RVKYB.mjs → chunk-MB7C7VQF.mjs} +0 -0
- /package/dist/{chunk-IHTPXUYI.mjs → chunk-MQUVYMNQ.mjs} +0 -0
- /package/dist/{chunk-PLUDE5C3.mjs → chunk-RNXGC54D.mjs} +0 -0
- /package/dist/{chunk-QKT5R735.mjs → chunk-TUANYVZQ.mjs} +0 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// src/core/utils.ts
|
|
2
|
+
import { Hex } from "@aptos-labs/ts-sdk";
|
|
3
|
+
async function* readInChunks(input, chunkSize) {
|
|
4
|
+
let idx = 0;
|
|
5
|
+
if (isReadableStream(input)) {
|
|
6
|
+
const reader = input.getReader();
|
|
7
|
+
let buffer = new Uint8Array(chunkSize);
|
|
8
|
+
let bufferWriteOffset = 0;
|
|
9
|
+
try {
|
|
10
|
+
while (true) {
|
|
11
|
+
const { value, done } = await reader.read();
|
|
12
|
+
if (done) break;
|
|
13
|
+
if (value === void 0) continue;
|
|
14
|
+
let srcOffset = 0;
|
|
15
|
+
while (srcOffset < value.length) {
|
|
16
|
+
const remainingCapacity = chunkSize - bufferWriteOffset;
|
|
17
|
+
const bytesToCopy = Math.min(
|
|
18
|
+
remainingCapacity,
|
|
19
|
+
value.length - srcOffset
|
|
20
|
+
);
|
|
21
|
+
buffer.set(
|
|
22
|
+
value.subarray(srcOffset, srcOffset + bytesToCopy),
|
|
23
|
+
bufferWriteOffset
|
|
24
|
+
);
|
|
25
|
+
bufferWriteOffset += bytesToCopy;
|
|
26
|
+
srcOffset += bytesToCopy;
|
|
27
|
+
if (bufferWriteOffset >= chunkSize) {
|
|
28
|
+
yield [idx++, buffer];
|
|
29
|
+
buffer = new Uint8Array(chunkSize);
|
|
30
|
+
bufferWriteOffset = 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
} finally {
|
|
35
|
+
reader.releaseLock();
|
|
36
|
+
}
|
|
37
|
+
if (bufferWriteOffset > 0) {
|
|
38
|
+
yield [idx++, buffer.subarray(0, bufferWriteOffset)];
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const view = toUint8Array(input);
|
|
43
|
+
for (let offset = 0; offset < view.byteLength; offset += chunkSize) {
|
|
44
|
+
yield [
|
|
45
|
+
idx++,
|
|
46
|
+
view.subarray(offset, Math.min(offset + chunkSize, view.byteLength))
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function zeroPadBytes(buffer, desiredLength) {
|
|
51
|
+
if (buffer.byteLength === desiredLength) {
|
|
52
|
+
return buffer;
|
|
53
|
+
}
|
|
54
|
+
if (buffer.byteLength > desiredLength) {
|
|
55
|
+
return buffer.subarray(0, desiredLength);
|
|
56
|
+
}
|
|
57
|
+
const paddedBuffer = new Uint8Array(desiredLength);
|
|
58
|
+
paddedBuffer.set(buffer);
|
|
59
|
+
return paddedBuffer;
|
|
60
|
+
}
|
|
61
|
+
async function concatHashes(parts) {
|
|
62
|
+
const chunks = parts.map((part) => Hex.fromHexInput(part).toUint8Array());
|
|
63
|
+
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
|
|
64
|
+
const combined = new Uint8Array(totalLength);
|
|
65
|
+
let offset = 0;
|
|
66
|
+
for (const chunk of chunks) {
|
|
67
|
+
combined.set(chunk, offset);
|
|
68
|
+
offset += chunk.byteLength;
|
|
69
|
+
}
|
|
70
|
+
return Hex.fromHexInput(
|
|
71
|
+
new Uint8Array(await crypto.subtle.digest("SHA-256", combined))
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
function isReadableStream(value) {
|
|
75
|
+
return typeof value === "object" && value !== null && "getReader" in value && typeof value.getReader === "function";
|
|
76
|
+
}
|
|
77
|
+
function toUint8Array(view) {
|
|
78
|
+
return view instanceof Uint8Array ? view : new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
|
|
79
|
+
}
|
|
80
|
+
function buildRequestUrl(path, baseUrl) {
|
|
81
|
+
const baseHasSlash = baseUrl.endsWith("/");
|
|
82
|
+
const safeBase = baseHasSlash ? baseUrl : `${baseUrl}/`;
|
|
83
|
+
const safePath = path.replace(/^\/+/, "");
|
|
84
|
+
return new URL(safePath, safeBase);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export {
|
|
88
|
+
readInChunks,
|
|
89
|
+
zeroPadBytes,
|
|
90
|
+
concatHashes,
|
|
91
|
+
buildRequestUrl
|
|
92
|
+
};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import {
|
|
2
|
+
concatHashes,
|
|
3
|
+
readInChunks,
|
|
4
|
+
zeroPadBytes
|
|
5
|
+
} from "./chunk-KBUWZXFA.mjs";
|
|
6
|
+
import {
|
|
7
|
+
DEFAULT_CHUNKSET_SIZE_BYTES
|
|
8
|
+
} from "./chunk-APML3CGJ.mjs";
|
|
9
|
+
import {
|
|
10
|
+
DEFAULT_ERASURE_K,
|
|
11
|
+
DEFAULT_ERASURE_M
|
|
12
|
+
} from "./chunk-ZPW742E7.mjs";
|
|
13
|
+
|
|
14
|
+
// src/core/commitments.ts
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
var ChunksetCommitmentSchema = z.object({
|
|
17
|
+
// Chunkset root (vector commitment of child chunks)
|
|
18
|
+
chunkset_root: z.string().nullable(),
|
|
19
|
+
// the size is known statically from the current configuration
|
|
20
|
+
chunk_commitments: z.array(z.string())
|
|
21
|
+
}).refine(
|
|
22
|
+
(data) => {
|
|
23
|
+
return data.chunk_commitments.length === DEFAULT_ERASURE_K + DEFAULT_ERASURE_M;
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
message: `Chunkset must have exactly ${DEFAULT_ERASURE_K + DEFAULT_ERASURE_M} chunks (ERASURE_K + ERASURE_M = ${DEFAULT_ERASURE_K} + ${DEFAULT_ERASURE_M})`,
|
|
27
|
+
path: ["chunk_commitments"]
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
function expectedTotalChunksets(rawSize, chunksetSize = DEFAULT_CHUNKSET_SIZE_BYTES) {
|
|
31
|
+
if (chunksetSize <= 0) {
|
|
32
|
+
throw new Error("chunksetSize must be positive");
|
|
33
|
+
}
|
|
34
|
+
if (rawSize === 0) return 1;
|
|
35
|
+
return Math.ceil(rawSize / chunksetSize);
|
|
36
|
+
}
|
|
37
|
+
var BlobCommitmentsSchema = z.object({
|
|
38
|
+
schema_version: z.string(),
|
|
39
|
+
raw_data_size: z.number(),
|
|
40
|
+
// FIXME I am not sure about this being here, or if it should be somewhere else
|
|
41
|
+
blob_merkle_root: z.string(),
|
|
42
|
+
chunkset_commitments: z.array(ChunksetCommitmentSchema)
|
|
43
|
+
}).refine(
|
|
44
|
+
(data) => {
|
|
45
|
+
return expectedTotalChunksets(data.raw_data_size) === data.chunkset_commitments.length;
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
message: "Total chunkset count mismatches with raw data size",
|
|
49
|
+
// FIXME put more details in here
|
|
50
|
+
path: ["chunkset_commitments"]
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
async function generateChunksetCommitments(shouldPad, chunksetIdx, chunksetData, expectedChunksetSize, provider, onChunk) {
|
|
54
|
+
const { erasure_n } = provider.config;
|
|
55
|
+
const chunkCommitments = [];
|
|
56
|
+
const chunksetPayload = shouldPad ? zeroPadBytes(chunksetData, expectedChunksetSize) : validatePrePaddedChunkset(
|
|
57
|
+
chunksetData,
|
|
58
|
+
expectedChunksetSize,
|
|
59
|
+
chunksetIdx
|
|
60
|
+
);
|
|
61
|
+
const { chunks } = provider.encode(chunksetPayload);
|
|
62
|
+
if (chunks.length !== erasure_n) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`Erasure provider produced ${chunks.length} chunks, expected ${erasure_n}.`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
let chunkIdx = 0;
|
|
68
|
+
for (const chunkData of chunks) {
|
|
69
|
+
if (onChunk !== void 0) {
|
|
70
|
+
await onChunk(chunksetIdx, chunkIdx, chunkData);
|
|
71
|
+
}
|
|
72
|
+
const chunkHash = await concatHashes([chunkData]);
|
|
73
|
+
chunkCommitments.push(chunkHash);
|
|
74
|
+
chunkIdx += 1;
|
|
75
|
+
}
|
|
76
|
+
const h = await concatHashes(
|
|
77
|
+
chunkCommitments.map((chunk) => chunk.toUint8Array())
|
|
78
|
+
);
|
|
79
|
+
const entry = {
|
|
80
|
+
chunkset_root: h.toString(),
|
|
81
|
+
chunk_commitments: chunkCommitments.map((chunk) => chunk.toString())
|
|
82
|
+
};
|
|
83
|
+
return { h, entry };
|
|
84
|
+
}
|
|
85
|
+
async function generateCommitments(provider, fullData, onChunk, options) {
|
|
86
|
+
const expectedChunksetSize = DEFAULT_CHUNKSET_SIZE_BYTES;
|
|
87
|
+
const shouldPad = options?.pad ?? true;
|
|
88
|
+
const chunksetCommitments = [];
|
|
89
|
+
const chunksetCommitmentHashes = [];
|
|
90
|
+
let rawDataSize = 0;
|
|
91
|
+
const chunksetGen = readInChunks(fullData, expectedChunksetSize);
|
|
92
|
+
for await (const [chunksetIdx, chunksetData] of chunksetGen) {
|
|
93
|
+
rawDataSize += chunksetData.length;
|
|
94
|
+
const { h, entry } = await generateChunksetCommitments(
|
|
95
|
+
shouldPad,
|
|
96
|
+
chunksetIdx,
|
|
97
|
+
chunksetData,
|
|
98
|
+
expectedChunksetSize,
|
|
99
|
+
provider,
|
|
100
|
+
onChunk
|
|
101
|
+
);
|
|
102
|
+
chunksetCommitments.push(entry);
|
|
103
|
+
chunksetCommitmentHashes.push(h);
|
|
104
|
+
}
|
|
105
|
+
if (rawDataSize === 0) {
|
|
106
|
+
const zeroChunkset = new Uint8Array(expectedChunksetSize);
|
|
107
|
+
const { h, entry } = await generateChunksetCommitments(
|
|
108
|
+
shouldPad,
|
|
109
|
+
0,
|
|
110
|
+
zeroChunkset,
|
|
111
|
+
expectedChunksetSize,
|
|
112
|
+
provider,
|
|
113
|
+
onChunk
|
|
114
|
+
);
|
|
115
|
+
chunksetCommitments.push(entry);
|
|
116
|
+
chunksetCommitmentHashes.push(h);
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
schema_version: "1.3",
|
|
120
|
+
raw_data_size: rawDataSize,
|
|
121
|
+
blob_merkle_root: (await concatHashes(
|
|
122
|
+
chunksetCommitmentHashes.map((chunk) => chunk.toUint8Array())
|
|
123
|
+
)).toString(),
|
|
124
|
+
chunkset_commitments: chunksetCommitments
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function validatePrePaddedChunkset(chunkset, expectedSize, chunksetIdx) {
|
|
128
|
+
if (chunkset.byteLength !== expectedSize) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`Chunkset ${chunksetIdx} has size ${chunkset.byteLength} bytes but expected ${expectedSize} bytes. Enable padding or supply pre-padded data before calling generateCommitments.`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
return chunkset;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export {
|
|
137
|
+
ChunksetCommitmentSchema,
|
|
138
|
+
expectedTotalChunksets,
|
|
139
|
+
BlobCommitmentsSchema,
|
|
140
|
+
generateCommitments
|
|
141
|
+
};
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAptosConfig
|
|
3
|
+
} from "./chunk-RBFWGDMY.mjs";
|
|
4
|
+
import {
|
|
5
|
+
SHELBY_DEPLOYER
|
|
6
|
+
} from "./chunk-HPVCKAN2.mjs";
|
|
7
|
+
|
|
8
|
+
// src/node/clients/ShelbyMetadataClient.ts
|
|
9
|
+
import {
|
|
10
|
+
AccountAddress,
|
|
11
|
+
Aptos,
|
|
12
|
+
Hex
|
|
13
|
+
} from "@aptos-labs/ts-sdk";
|
|
14
|
+
var ShelbyMetadataClient = class {
|
|
15
|
+
aptos;
|
|
16
|
+
deployer;
|
|
17
|
+
/**
|
|
18
|
+
* The ShelbyMetadataClient is used to interact with the Shelby contract on the Aptos blockchain. This
|
|
19
|
+
* includes functions like gathering basic details about the Shelby system, including storage provider information.
|
|
20
|
+
*
|
|
21
|
+
* @param config.aptos.config - The Aptos config.
|
|
22
|
+
* @param config.shelbyDeployer - The deployer account address of the Shelby contract. If not provided, the default deployer address will be used.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const aptos = new Aptos(new AptosConfig({ network: Network.TESTNET }));
|
|
27
|
+
* const metadataClient = new ShelbyMetadataClient({ aptos });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
constructor(config) {
|
|
31
|
+
this.aptos = new Aptos(getAptosConfig(config));
|
|
32
|
+
this.deployer = config.deployer ?? AccountAddress.fromString(SHELBY_DEPLOYER);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Retrieves storage provider list from the blockchain.
|
|
36
|
+
*
|
|
37
|
+
* @returns A list of storage providers, or empty array if none exist.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const spList = await client.getStorageProviders();
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
async getStorageProviders() {
|
|
45
|
+
try {
|
|
46
|
+
const rawMetadata = await this.aptos.view({
|
|
47
|
+
payload: {
|
|
48
|
+
function: `${this.deployer.toString()}::global_metadata::get_all_storage_providers`,
|
|
49
|
+
functionArguments: []
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
const metadata = rawMetadata[0];
|
|
53
|
+
return metadata.map((provider) => ({
|
|
54
|
+
address: AccountAddress.fromString(provider.address),
|
|
55
|
+
ipAddress: provider.ip_address,
|
|
56
|
+
port: provider.port,
|
|
57
|
+
blsPublicKey: Hex.fromHexInput(provider.bls_public_key).toUint8Array(),
|
|
58
|
+
failureDomain: provider.failure_domain
|
|
59
|
+
}));
|
|
60
|
+
} catch (error) {
|
|
61
|
+
if (error instanceof Error && // Depending on the network, the error message may show up differently.
|
|
62
|
+
error.message?.includes("sub_status: Some(404)")) {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Retrieves the list of placement group addresses.
|
|
70
|
+
*
|
|
71
|
+
* @returns The placement group address list, or an empty array if none exist.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const pgList = await client.getPlacementGroupAddresses();
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
async getPlacementGroupAddresses() {
|
|
79
|
+
try {
|
|
80
|
+
const pgSizeMetadata = await this.aptos.view({
|
|
81
|
+
payload: {
|
|
82
|
+
function: `${this.deployer.toString()}::global_metadata::get_number_of_placement_groups`,
|
|
83
|
+
functionArguments: []
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
const finalPlacementGroupIndex = pgSizeMetadata[0] - 1;
|
|
87
|
+
const addressMetadataArray = await this.aptos.view({
|
|
88
|
+
payload: {
|
|
89
|
+
function: `${this.deployer.toString()}::global_metadata::get_placement_group_addresses`,
|
|
90
|
+
functionArguments: [0, finalPlacementGroupIndex]
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
const metadata = addressMetadataArray[0];
|
|
94
|
+
return metadata.map((pg) => AccountAddress.fromString(pg));
|
|
95
|
+
} catch (error) {
|
|
96
|
+
if (error instanceof Error && // Depending on the network, the error message may show up differently.
|
|
97
|
+
(error.message?.includes("sub_status: Some(404)") || error.message?.includes("E_PLACEMENT_GROUP_NOT_FOUND"))) {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Retrieves the list of slice addresses.
|
|
105
|
+
*
|
|
106
|
+
* @returns The slice group list, or an empty array if none exist.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const pgList = await client.getSliceAddresses();
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
async getSliceAddresses() {
|
|
114
|
+
try {
|
|
115
|
+
const sliceSizeMetadata = await this.aptos.view({
|
|
116
|
+
payload: {
|
|
117
|
+
function: `${this.deployer.toString()}::global_metadata::get_number_of_slices`,
|
|
118
|
+
functionArguments: []
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
const finalSliceIndex = sliceSizeMetadata[0] - 1;
|
|
122
|
+
const addressMetadataArray = await this.aptos.view({
|
|
123
|
+
payload: {
|
|
124
|
+
function: `${this.deployer.toString()}::global_metadata::get_slice_addresses`,
|
|
125
|
+
functionArguments: [0, finalSliceIndex]
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
const metadata = addressMetadataArray[0];
|
|
129
|
+
return metadata.map((slice) => AccountAddress.fromString(slice));
|
|
130
|
+
} catch (error) {
|
|
131
|
+
if (error instanceof Error && // Depending on the network, the error message may show up differently.
|
|
132
|
+
(error.message?.includes("sub_status: Some(404)") || error.message?.includes("E_SLICE_NOT_FOUND"))) {
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Retrieves the storage providers assigned to a slice, through a placement group.
|
|
140
|
+
*
|
|
141
|
+
* @param params.account - The address of the slice account.
|
|
142
|
+
* @returns The list of storage providers for the slice, or an empty array if none exist.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* const pgInfo = await client.getStorageProvidersForSlice();
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
async getStorageProvidersForSlice(params) {
|
|
150
|
+
const sliceMetadata = await this.aptos.view({
|
|
151
|
+
payload: {
|
|
152
|
+
function: `${this.deployer.toString()}::slice::get_slice_info`,
|
|
153
|
+
functionArguments: [params.account.toString()]
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
const placementGroupAddress = sliceMetadata[0].placement_group_assignments[0].placement_group_address;
|
|
157
|
+
const rawMetadata = await this.aptos.view({
|
|
158
|
+
payload: {
|
|
159
|
+
function: `${this.deployer.toString()}::placement_group::get_placement_group_info`,
|
|
160
|
+
functionArguments: [placementGroupAddress]
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
const members = rawMetadata[0].members;
|
|
164
|
+
const keys = members.flatMap((m) => {
|
|
165
|
+
const active = m.active?.vec.map((a) => a.address) ?? [];
|
|
166
|
+
const others = m.others?.data.map((o) => o.key) ?? [];
|
|
167
|
+
return [...active, ...others];
|
|
168
|
+
});
|
|
169
|
+
return keys.map((k) => AccountAddress.fromString(k));
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export {
|
|
174
|
+
ShelbyMetadataClient
|
|
175
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/core/blobs.ts
|
|
2
2
|
import { AccountAddress } from "@aptos-labs/ts-sdk";
|
|
3
3
|
var createBlobKey = (params) => {
|
|
4
|
-
return
|
|
4
|
+
return `@${AccountAddress.from(params.account).toStringLongWithoutPrefix()}/${params.blobName}`;
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
export {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/core/clients/utils.ts
|
|
2
|
+
import { AptosConfig, Network } from "@aptos-labs/ts-sdk";
|
|
3
|
+
var getAptosConfig = (config) => {
|
|
4
|
+
if (config.aptos) {
|
|
5
|
+
return new AptosConfig(config.aptos);
|
|
6
|
+
}
|
|
7
|
+
let aptosConfig;
|
|
8
|
+
switch (config.network) {
|
|
9
|
+
case "local":
|
|
10
|
+
aptosConfig = new AptosConfig({
|
|
11
|
+
network: Network.LOCAL
|
|
12
|
+
});
|
|
13
|
+
break;
|
|
14
|
+
case "shelbynet":
|
|
15
|
+
aptosConfig = new AptosConfig({
|
|
16
|
+
network: Network.SHELBYNET,
|
|
17
|
+
clientConfig: {
|
|
18
|
+
API_KEY: config.apiKey
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
break;
|
|
22
|
+
default:
|
|
23
|
+
throw new Error(`Unsupported network: ${config.network}`);
|
|
24
|
+
}
|
|
25
|
+
return aptosConfig;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
getAptosConfig
|
|
30
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/core/networks.ts
|
|
2
|
+
import { Network } from "@aptos-labs/ts-sdk";
|
|
3
|
+
var shelbyNetworks = [Network.LOCAL, Network.SHELBYNET];
|
|
4
|
+
var isShelbyNetwork = (network) => {
|
|
5
|
+
return shelbyNetworks.includes(network.toLowerCase());
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
shelbyNetworks,
|
|
10
|
+
isShelbyNetwork
|
|
11
|
+
};
|