@shelby-protocol/react 0.0.2

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +104 -0
  3. package/dist/index.cjs +2 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +2 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/mutations/index.d.ts +5 -0
  10. package/dist/mutations/index.d.ts.map +1 -0
  11. package/dist/mutations/useCommitBlobs.d.ts +50 -0
  12. package/dist/mutations/useCommitBlobs.d.ts.map +1 -0
  13. package/dist/mutations/useEncodeBlobs.d.ts +78 -0
  14. package/dist/mutations/useEncodeBlobs.d.ts.map +1 -0
  15. package/dist/mutations/useRegisterCommitments.d.ts +69 -0
  16. package/dist/mutations/useRegisterCommitments.d.ts.map +1 -0
  17. package/dist/mutations/useUploadBlobs.d.ts +79 -0
  18. package/dist/mutations/useUploadBlobs.d.ts.map +1 -0
  19. package/dist/queries/index.d.ts +3 -0
  20. package/dist/queries/index.d.ts.map +1 -0
  21. package/dist/queries/useAccountBlobs.d.ts +30 -0
  22. package/dist/queries/useAccountBlobs.d.ts.map +1 -0
  23. package/dist/queries/useBlobMetadata.d.ts +29 -0
  24. package/dist/queries/useBlobMetadata.d.ts.map +1 -0
  25. package/dist/types/mutations.d.ts +6 -0
  26. package/dist/types/mutations.d.ts.map +1 -0
  27. package/dist/types/queries.d.ts +6 -0
  28. package/dist/types/queries.d.ts.map +1 -0
  29. package/dist/types/signers.d.ts +9 -0
  30. package/dist/types/signers.d.ts.map +1 -0
  31. package/dist/types/walletAdapter.d.ts +3 -0
  32. package/dist/types/walletAdapter.d.ts.map +1 -0
  33. package/package.json +80 -0
  34. package/src/index.ts +2 -0
  35. package/src/mutations/index.ts +4 -0
  36. package/src/mutations/useCommitBlobs.tsx +83 -0
  37. package/src/mutations/useEncodeBlobs.tsx +122 -0
  38. package/src/mutations/useRegisterCommitments.tsx +129 -0
  39. package/src/mutations/useUploadBlobs.tsx +194 -0
  40. package/src/queries/index.ts +2 -0
  41. package/src/queries/useAccountBlobs.tsx +72 -0
  42. package/src/queries/useBlobMetadata.tsx +56 -0
  43. package/src/types/mutations.ts +16 -0
  44. package/src/types/queries.ts +16 -0
  45. package/src/types/signers.ts +11 -0
  46. package/src/types/walletAdapter.ts +4 -0
@@ -0,0 +1,194 @@
1
+ import { AccountAddress } from "@aptos-labs/ts-sdk";
2
+ import {
3
+ createBlobKey,
4
+ createDefaultErasureCodingProvider,
5
+ DEFAULT_CHUNKSET_SIZE_BYTES,
6
+ expectedTotalChunksets,
7
+ generateCommitments,
8
+ ShelbyBlobClient,
9
+ type UploadOptions,
10
+ } from "@shelby-protocol/sdk/browser";
11
+ import { useMutation } from "@tanstack/react-query";
12
+ import pLimit from "p-limit";
13
+ import type { UseMutationOptionsWithClient } from "../types/mutations";
14
+ import type { AccountSigner, Signer } from "../types/signers";
15
+
16
+ export type UseUploadBlobsVariables = {
17
+ /**
18
+ * The signer to use for the transaction.
19
+ *
20
+ * @see {@link Signer}
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * const signer = new Account.generate();
25
+ * uploadBlobs.mutate({
26
+ * signer,
27
+ * blobs: [
28
+ * { blobName: 'file1.txt', blobData: new Uint8Array([...]) },
29
+ * ],
30
+ * expirationMicros: Date.now() * 1000 + 86400000000,
31
+ * });
32
+ * ```
33
+ */
34
+ signer: Signer;
35
+ /**
36
+ * The blobs to upload.
37
+ */
38
+ blobs: {
39
+ blobName: string;
40
+ blobData: Uint8Array;
41
+ }[];
42
+ /**
43
+ * The expiration time of the blobs in microseconds.
44
+ */
45
+ expirationMicros: number;
46
+ /**
47
+ * Optional transaction building options.
48
+ */
49
+ options?: UploadOptions;
50
+ /**
51
+ * The maximum number of concurrent uploads.
52
+ * @default 3
53
+ */
54
+ maxConcurrentUploads?: number;
55
+ };
56
+
57
+ export type UseUploadBlobsOptions = UseMutationOptionsWithClient<
58
+ void,
59
+ Error,
60
+ UseUploadBlobsVariables
61
+ >;
62
+
63
+ /**
64
+ * Uploads blobs to the Shelby network.
65
+ *
66
+ * This mutation handles the complete blob upload process including:
67
+ * - Encoding blobs with erasure coding
68
+ * - Registering commitments on-chain (if not already registered)
69
+ * - Uploading blob data to the RPC endpoint
70
+ *
71
+ * It supports both account signers and wallet adapter signers, and includes
72
+ * logic to skip registration for blobs that already exist.
73
+ *
74
+ * @example
75
+ * ```tsx
76
+ * import { ShelbyClient } from "@shelby-protocol/sdk/browser";
77
+ * import { Network } from "@aptos-labs/ts-sdk";
78
+ * import { useUploadBlobs } from "@shelby-protocol/react";
79
+ *
80
+ * const shelbyClient = new ShelbyClient({ network: Network.SHELBYNET });
81
+ * const uploadBlobs = useUploadBlobs({
82
+ * client: shelbyClient,
83
+ * onSuccess: () => console.log('Upload complete'),
84
+ * });
85
+ *
86
+ * const signer = new Account.generate();
87
+ * uploadBlobs.mutate({
88
+ * signer,
89
+ * blobs: [
90
+ * { blobName: 'file1.txt', blobData: new Uint8Array([...]) },
91
+ * ],
92
+ * expirationMicros: Date.now() * 1000 + 86400000000,
93
+ * });
94
+ * ```
95
+ */
96
+ export function useUploadBlobs({
97
+ client: shelbyClient,
98
+ ...options
99
+ }: UseUploadBlobsOptions) {
100
+ return useMutation({
101
+ mutationFn: async ({
102
+ blobs,
103
+ expirationMicros,
104
+ options,
105
+ signer: signerOrFn,
106
+ maxConcurrentUploads = 3,
107
+ }: UseUploadBlobsVariables) => {
108
+ if (!("account" in signerOrFn)) {
109
+ const accountSigner: AccountSigner = signerOrFn;
110
+
111
+ await shelbyClient.batchUpload({
112
+ blobs: blobs.map(({ blobData, blobName }) => ({
113
+ blobData,
114
+ blobName,
115
+ })),
116
+ expirationMicros,
117
+ signer: accountSigner,
118
+ options,
119
+ });
120
+ } else {
121
+ const { account, signAndSubmitTransaction } = signerOrFn;
122
+
123
+ const chunksetSize =
124
+ options?.chunksetSizeBytes ?? DEFAULT_CHUNKSET_SIZE_BYTES;
125
+
126
+ const existingBlobs = await shelbyClient.coordination.getBlobs({
127
+ where: {
128
+ blob_name: {
129
+ _in: blobs.map((blob) =>
130
+ createBlobKey({ account, blobName: blob.blobName }),
131
+ ),
132
+ },
133
+ },
134
+ });
135
+
136
+ const blobsToRegister = blobs.filter(
137
+ (blob) =>
138
+ !existingBlobs.some(
139
+ (existingBlob) =>
140
+ existingBlob.name ===
141
+ createBlobKey({ account, blobName: blob.blobName }),
142
+ ),
143
+ );
144
+
145
+ if (blobsToRegister.length > 0) {
146
+ const provider = await createDefaultErasureCodingProvider();
147
+
148
+ const blobCommitments = await Promise.all(
149
+ blobsToRegister.map(async (blob) =>
150
+ generateCommitments(provider, blob.blobData),
151
+ ),
152
+ );
153
+
154
+ const pendingRegisterBlobTransaction = await signAndSubmitTransaction(
155
+ {
156
+ data: ShelbyBlobClient.createBatchRegisterBlobsPayload({
157
+ account: AccountAddress.from(account),
158
+ expirationMicros,
159
+ blobs: blobsToRegister.map((blob, index) => ({
160
+ blobName: blob.blobName,
161
+ blobSize: blob.blobData.length,
162
+ blobMerkleRoot: blobCommitments[index].blob_merkle_root,
163
+ numChunksets: expectedTotalChunksets(
164
+ blob.blobData.length,
165
+ chunksetSize,
166
+ ),
167
+ })),
168
+ }),
169
+ options: options?.build?.options,
170
+ },
171
+ );
172
+
173
+ await shelbyClient.coordination.aptos.waitForTransaction({
174
+ transactionHash: pendingRegisterBlobTransaction.hash,
175
+ });
176
+ }
177
+
178
+ const limit = pLimit(maxConcurrentUploads);
179
+ const uploadPromises = blobs.map((blob) =>
180
+ limit(() =>
181
+ shelbyClient.rpc.putBlob({
182
+ account,
183
+ blobName: blob.blobName,
184
+ blobData: blob.blobData,
185
+ }),
186
+ ),
187
+ );
188
+
189
+ await Promise.all(uploadPromises);
190
+ }
191
+ },
192
+ ...options,
193
+ });
194
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./useAccountBlobs";
2
+ export * from "./useBlobMetadata";
@@ -0,0 +1,72 @@
1
+ import type { Network } from "@aptos-labs/ts-sdk";
2
+ import type {
3
+ BlobMetadata,
4
+ ShelbyBlobClient,
5
+ } from "@shelby-protocol/sdk/browser";
6
+ import { useQuery } from "@tanstack/react-query";
7
+ import type { UseQueryOptionsWithClient } from "../types/queries";
8
+
9
+ export const getUseAccountBlobsQueryKey = (
10
+ params: Parameters<ShelbyBlobClient["getAccountBlobs"]>[0] & {
11
+ network: Network;
12
+ },
13
+ ) => [
14
+ "account-blobs",
15
+ params.network,
16
+ params.account.toString(),
17
+ params.pagination?.limit,
18
+ params.pagination?.offset,
19
+ params.orderBy,
20
+ params.where,
21
+ ];
22
+
23
+ export type UseAccountBlobsOptions = UseQueryOptionsWithClient<BlobMetadata[]> &
24
+ Parameters<ShelbyBlobClient["getAccountBlobs"]>[0];
25
+
26
+ /**
27
+ * Queries blobs associated with an account.
28
+ *
29
+ * This query fetches blob metadata for a specific account with support for
30
+ * pagination, filtering, and ordering.
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * import { ShelbyClient, Order_By} from "@shelby-protocol/sdk/browser";
35
+ * import { Network } from "@aptos-labs/ts-sdk";
36
+ * import { useAccountBlobs } from "@shelby-protocol/react";
37
+ *
38
+ * const shelbyClient = new ShelbyClient({ network: Network.SHELBYNET });
39
+ * const { data: blobs, isLoading } = useAccountBlobs({
40
+ * client: shelbyClient,
41
+ * account: '0x123...',
42
+ * pagination: { limit: 10, offset: 0 },
43
+ * orderBy: { updated_at: Order_By.Desc },
44
+ * });
45
+ * ```
46
+ */
47
+ export function useAccountBlobs({
48
+ account,
49
+ pagination,
50
+ orderBy,
51
+ where,
52
+ client: shelbyClient,
53
+ ...options
54
+ }: UseAccountBlobsOptions) {
55
+ return useQuery<BlobMetadata[]>({
56
+ queryKey: getUseAccountBlobsQueryKey({
57
+ network: shelbyClient.config.network,
58
+ account,
59
+ pagination,
60
+ orderBy,
61
+ where,
62
+ }),
63
+ queryFn: async () =>
64
+ await shelbyClient.coordination.getAccountBlobs({
65
+ account,
66
+ pagination,
67
+ orderBy,
68
+ where,
69
+ }),
70
+ ...options,
71
+ });
72
+ }
@@ -0,0 +1,56 @@
1
+ import type { Network } from "@aptos-labs/ts-sdk";
2
+ import type {
3
+ BlobMetadata,
4
+ ShelbyBlobClient,
5
+ } from "@shelby-protocol/sdk/browser";
6
+ import { useQuery } from "@tanstack/react-query";
7
+ import type { UseQueryOptionsWithClient } from "../types/queries";
8
+
9
+ export const getUseBlobMetadataQueryKey = (
10
+ params: Parameters<ShelbyBlobClient["getBlobMetadata"]>[0] & {
11
+ network: Network;
12
+ },
13
+ ) => ["blob-metadata", params.network, params.account.toString(), params.name];
14
+
15
+ export type UseBlobMetadataOptions =
16
+ UseQueryOptionsWithClient<BlobMetadata | null> &
17
+ Parameters<ShelbyBlobClient["getBlobMetadata"]>[0];
18
+
19
+ /**
20
+ * Queries the metadata for a specific blob.
21
+ *
22
+ * This query fetches the metadata for a single blob identified by account and blob name.
23
+ * Returns `null` if the blob is not found.
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * import { ShelbyClient } from "@shelby-protocol/sdk/browser";
28
+ * import { Network } from "@aptos-labs/ts-sdk";
29
+ * import { useBlobMetadata } from "@shelby-protocol/react";
30
+ *
31
+ * const shelbyClient = new ShelbyClient({ network: Network.SHELBYNET });
32
+ * const { data: metadata } = useBlobMetadata({
33
+ * client: shelbyClient,
34
+ * account: '0x123...',
35
+ * name: 'file1.txt',
36
+ * });
37
+ * ```
38
+ */
39
+ export function useBlobMetadata({
40
+ account,
41
+ name,
42
+ client: shelbyClient,
43
+ ...options
44
+ }: UseBlobMetadataOptions) {
45
+ return useQuery<BlobMetadata | null>({
46
+ queryKey: getUseBlobMetadataQueryKey({
47
+ network: shelbyClient.config.network,
48
+ account,
49
+ name,
50
+ }),
51
+ queryFn: async () =>
52
+ (await shelbyClient.coordination.getBlobMetadata({ account, name })) ??
53
+ null,
54
+ ...options,
55
+ });
56
+ }
@@ -0,0 +1,16 @@
1
+ import type { ShelbyClient } from "@shelby-protocol/sdk/browser";
2
+ import type {
3
+ DefaultError,
4
+ MutationKey,
5
+ UseMutationOptions,
6
+ } from "@tanstack/react-query";
7
+
8
+ export type UseMutationOptionsWithClient<
9
+ TMutationFnData = unknown,
10
+ TError = DefaultError,
11
+ TData = TMutationFnData,
12
+ TMutationKey extends MutationKey = MutationKey,
13
+ > = Omit<
14
+ UseMutationOptions<TMutationFnData, TError, TData, TMutationKey>,
15
+ "mutationFn"
16
+ > & { client: ShelbyClient };
@@ -0,0 +1,16 @@
1
+ import type { ShelbyClient } from "@shelby-protocol/sdk/browser";
2
+ import type {
3
+ DefaultError,
4
+ QueryKey,
5
+ UseQueryOptions,
6
+ } from "@tanstack/react-query";
7
+
8
+ export type UseQueryOptionsWithClient<
9
+ TQueryFnData = unknown,
10
+ TError = DefaultError,
11
+ TData = TQueryFnData,
12
+ TQueryKey extends QueryKey = QueryKey,
13
+ > = Omit<
14
+ UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
15
+ "queryFn" | "queryKey"
16
+ > & { client: ShelbyClient };
@@ -0,0 +1,11 @@
1
+ import type { Account, AccountAddressInput } from "@aptos-labs/ts-sdk";
2
+ import type { SignAndSubmitTransactionFn } from "./walletAdapter";
3
+
4
+ export type AccountSigner = Account;
5
+
6
+ export type WalletAdapterSigner = {
7
+ account: AccountAddressInput;
8
+ signAndSubmitTransaction: SignAndSubmitTransactionFn;
9
+ };
10
+
11
+ export type Signer = AccountSigner | WalletAdapterSigner;
@@ -0,0 +1,4 @@
1
+ import type { WalletContextState } from "@aptos-labs/wallet-adapter-react";
2
+
3
+ export type SignAndSubmitTransactionFn =
4
+ WalletContextState["signAndSubmitTransaction"];