@shelby-protocol/cli 0.0.20 → 0.0.21
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 +1735 -1445
- package/package.json +3 -3
package/bin/entry.js
CHANGED
|
@@ -505,157 +505,13 @@ import { Command } from "@commander-js/extra-typings";
|
|
|
505
505
|
|
|
506
506
|
// package.json
|
|
507
507
|
var name = "@shelby-protocol/cli";
|
|
508
|
-
var version = "0.0.
|
|
508
|
+
var version = "0.0.21";
|
|
509
509
|
|
|
510
510
|
// src/commands/account.tsx
|
|
511
511
|
import readline from "readline";
|
|
512
512
|
import { Account as Account3, AptosApiError as AptosApiError2, Ed25519PrivateKey as Ed25519PrivateKey4 } from "@aptos-labs/ts-sdk";
|
|
513
513
|
import { Option } from "@commander-js/extra-typings";
|
|
514
514
|
|
|
515
|
-
// ../../packages/sdk/dist/chunk-RBFWGDMY.mjs
|
|
516
|
-
import { AptosConfig, Network } from "@aptos-labs/ts-sdk";
|
|
517
|
-
var getAptosConfig = (config) => {
|
|
518
|
-
if (config.aptos) {
|
|
519
|
-
return new AptosConfig(config.aptos);
|
|
520
|
-
}
|
|
521
|
-
let aptosConfig;
|
|
522
|
-
switch (config.network) {
|
|
523
|
-
case "local":
|
|
524
|
-
aptosConfig = new AptosConfig({
|
|
525
|
-
network: Network.LOCAL
|
|
526
|
-
});
|
|
527
|
-
break;
|
|
528
|
-
case "shelbynet":
|
|
529
|
-
aptosConfig = new AptosConfig({
|
|
530
|
-
network: Network.SHELBYNET,
|
|
531
|
-
clientConfig: {
|
|
532
|
-
API_KEY: config.apiKey
|
|
533
|
-
}
|
|
534
|
-
});
|
|
535
|
-
break;
|
|
536
|
-
default:
|
|
537
|
-
throw new Error(`Unsupported network: ${config.network}`);
|
|
538
|
-
}
|
|
539
|
-
return aptosConfig;
|
|
540
|
-
};
|
|
541
|
-
|
|
542
|
-
// ../../packages/sdk/dist/chunk-EH4NYOCS.mjs
|
|
543
|
-
import { Network as Network2 } from "@aptos-labs/ts-sdk";
|
|
544
|
-
var NetworkToShelbyRPCBaseUrl = {
|
|
545
|
-
[Network2.SHELBYNET]: "https://api.shelbynet.shelby.xyz/shelby",
|
|
546
|
-
[Network2.DEVNET]: void 0,
|
|
547
|
-
[Network2.TESTNET]: void 0,
|
|
548
|
-
[Network2.MAINNET]: void 0,
|
|
549
|
-
[Network2.LOCAL]: void 0,
|
|
550
|
-
[Network2.CUSTOM]: void 0
|
|
551
|
-
};
|
|
552
|
-
var NetworkToShelbyBlobIndexerBaseUrl = {
|
|
553
|
-
[Network2.SHELBYNET]: "https://api.shelbynet.aptoslabs.com/nocode/v1/public/cmforrguw0042s601fn71f9l2/v1/graphql",
|
|
554
|
-
[Network2.DEVNET]: void 0,
|
|
555
|
-
[Network2.TESTNET]: void 0,
|
|
556
|
-
[Network2.MAINNET]: void 0,
|
|
557
|
-
[Network2.LOCAL]: void 0,
|
|
558
|
-
[Network2.CUSTOM]: void 0
|
|
559
|
-
};
|
|
560
|
-
var SHELBY_DEPLOYER = "0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5";
|
|
561
|
-
var MICROPAYMENTS_DEPLOYER = "0xb42ac038b6dae86f6171e28e297aab9555ce09909445ec579e4ffe6b8d4d63bf";
|
|
562
|
-
var SHELBYUSD_TOKEN_NAME = "ShelbyUSD";
|
|
563
|
-
var SHELBYUSD_FA_METADATA_ADDRESS = "0x1b18363a9f1fe5e6ebf247daba5cc1c18052bb232efdc4c50f556053922d98e1";
|
|
564
|
-
|
|
565
|
-
// ../../packages/sdk/dist/chunk-NEBSHEBE.mjs
|
|
566
|
-
import {
|
|
567
|
-
AccountAddress,
|
|
568
|
-
Aptos,
|
|
569
|
-
Hex
|
|
570
|
-
} from "@aptos-labs/ts-sdk";
|
|
571
|
-
|
|
572
|
-
// ../../packages/sdk/dist/chunk-4MG4XGY4.mjs
|
|
573
|
-
import {
|
|
574
|
-
AccountAuthenticator,
|
|
575
|
-
Deserializer,
|
|
576
|
-
Hex as Hex2,
|
|
577
|
-
MultiAgentTransaction,
|
|
578
|
-
Serializer
|
|
579
|
-
} from "@aptos-labs/ts-sdk";
|
|
580
|
-
var StaleChannelStateError = class _StaleChannelStateError extends Error {
|
|
581
|
-
/**
|
|
582
|
-
* The last valid micropayment stored by the server.
|
|
583
|
-
* Clients can use this to reset their local channel state.
|
|
584
|
-
*/
|
|
585
|
-
storedMicropayment;
|
|
586
|
-
constructor(storedMicropayment, message) {
|
|
587
|
-
super(
|
|
588
|
-
message ?? "Client has stale channel state. Use the returned micropayment to reset local state."
|
|
589
|
-
);
|
|
590
|
-
this.name = "StaleChannelStateError";
|
|
591
|
-
this.storedMicropayment = storedMicropayment;
|
|
592
|
-
}
|
|
593
|
-
/**
|
|
594
|
-
* Returns the stored micropayment as a base64-encoded string.
|
|
595
|
-
*/
|
|
596
|
-
toBase64() {
|
|
597
|
-
const bytes = this.storedMicropayment.bcsToBytes();
|
|
598
|
-
const binaryString = Array.from(
|
|
599
|
-
bytes,
|
|
600
|
-
(byte) => String.fromCharCode(byte)
|
|
601
|
-
).join("");
|
|
602
|
-
return btoa(binaryString);
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
* Creates a StaleChannelStateError from a base64-encoded micropayment string.
|
|
606
|
-
*/
|
|
607
|
-
static fromBase64(base64, message) {
|
|
608
|
-
const binaryString = atob(base64);
|
|
609
|
-
const bytes = Uint8Array.from(binaryString, (char) => char.charCodeAt(0));
|
|
610
|
-
const micropayment = SenderBuiltMicropayment.deserialize(bytes);
|
|
611
|
-
return new _StaleChannelStateError(micropayment, message);
|
|
612
|
-
}
|
|
613
|
-
};
|
|
614
|
-
var SenderBuiltMicropayment = class _SenderBuiltMicropayment {
|
|
615
|
-
/**
|
|
616
|
-
* The actual micropayment transaction. It is built with the receiver address as fee payer and also requires a signature from the receiver to submit.
|
|
617
|
-
*/
|
|
618
|
-
micropayment;
|
|
619
|
-
/**
|
|
620
|
-
* The sender's signature.
|
|
621
|
-
*/
|
|
622
|
-
senderSignature;
|
|
623
|
-
constructor(micropayment, senderSignature) {
|
|
624
|
-
this.micropayment = micropayment;
|
|
625
|
-
this.senderSignature = senderSignature;
|
|
626
|
-
}
|
|
627
|
-
serialize(serializer) {
|
|
628
|
-
this.micropayment.serialize(serializer);
|
|
629
|
-
this.senderSignature.serialize(serializer);
|
|
630
|
-
}
|
|
631
|
-
bcsToBytes() {
|
|
632
|
-
const serializer = new Serializer();
|
|
633
|
-
this.serialize(serializer);
|
|
634
|
-
return serializer.toUint8Array();
|
|
635
|
-
}
|
|
636
|
-
bcsToHex() {
|
|
637
|
-
return Hex2.fromHexInput(this.bcsToBytes());
|
|
638
|
-
}
|
|
639
|
-
toStringWithoutPrefix() {
|
|
640
|
-
return this.bcsToHex().toStringWithoutPrefix();
|
|
641
|
-
}
|
|
642
|
-
toString() {
|
|
643
|
-
return this.bcsToHex().toString();
|
|
644
|
-
}
|
|
645
|
-
/**
|
|
646
|
-
* Deserializes a SenderBuiltMicropayment from BCS bytes.
|
|
647
|
-
* @param bytes - The bytes to deserialize from (Uint8Array or hex string).
|
|
648
|
-
* @returns A new SenderBuiltMicropayment instance.
|
|
649
|
-
*/
|
|
650
|
-
static deserialize(bytes) {
|
|
651
|
-
const bytesArray = typeof bytes === "string" ? Hex2.fromHexInput(bytes).toUint8Array() : bytes;
|
|
652
|
-
const deserializer = new Deserializer(bytesArray);
|
|
653
|
-
const micropayment = MultiAgentTransaction.deserialize(deserializer);
|
|
654
|
-
const senderSignature = AccountAuthenticator.deserialize(deserializer);
|
|
655
|
-
return new _SenderBuiltMicropayment(micropayment, senderSignature);
|
|
656
|
-
}
|
|
657
|
-
};
|
|
658
|
-
|
|
659
515
|
// ../../node_modules/.pnpm/tslib@2.8.1/node_modules/tslib/tslib.es6.mjs
|
|
660
516
|
var __assign = function() {
|
|
661
517
|
__assign = Object.assign || function __assign2(t) {
|
|
@@ -3855,7 +3711,7 @@ var extras = {
|
|
|
3855
3711
|
gql["default"] = gql;
|
|
3856
3712
|
var lib_default = gql;
|
|
3857
3713
|
|
|
3858
|
-
// ../../packages/sdk/dist/chunk-
|
|
3714
|
+
// ../../packages/sdk/dist/chunk-KJ24NKPH.mjs
|
|
3859
3715
|
var GetBlobsDocument = lib_default`
|
|
3860
3716
|
query getBlobs($where: blobs_bool_exp, $orderBy: [blobs_order_by!], $limit: Int, $offset: Int) {
|
|
3861
3717
|
blobs(where: $where, order_by: $orderBy, limit: $limit, offset: $offset) {
|
|
@@ -3909,6 +3765,40 @@ var GetBlobActivitiesCountDocument = lib_default`
|
|
|
3909
3765
|
}
|
|
3910
3766
|
}
|
|
3911
3767
|
`;
|
|
3768
|
+
var GetPlacementGroupSlotsDocument = lib_default`
|
|
3769
|
+
query getPlacementGroupSlots($where: placement_group_slots_bool_exp, $orderBy: [placement_group_slots_order_by!], $limit: Int, $offset: Int) {
|
|
3770
|
+
placement_group_slots(
|
|
3771
|
+
where: $where
|
|
3772
|
+
order_by: $orderBy
|
|
3773
|
+
limit: $limit
|
|
3774
|
+
offset: $offset
|
|
3775
|
+
) {
|
|
3776
|
+
placement_group
|
|
3777
|
+
slot_index
|
|
3778
|
+
storage_provider
|
|
3779
|
+
status
|
|
3780
|
+
updated_at
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
`;
|
|
3784
|
+
var GetPlacementGroupSlotsCountDocument = lib_default`
|
|
3785
|
+
query getPlacementGroupSlotsCount($where: placement_group_slots_bool_exp) {
|
|
3786
|
+
placement_group_slots_aggregate(where: $where) {
|
|
3787
|
+
aggregate {
|
|
3788
|
+
count
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3791
|
+
}
|
|
3792
|
+
`;
|
|
3793
|
+
var GetProcessorStatusDocument = lib_default`
|
|
3794
|
+
query getProcessorStatus {
|
|
3795
|
+
processor_status {
|
|
3796
|
+
last_success_version
|
|
3797
|
+
last_transaction_timestamp
|
|
3798
|
+
last_updated
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3801
|
+
`;
|
|
3912
3802
|
var defaultWrapper = (action, _operationName, _operationType, _variables) => action();
|
|
3913
3803
|
function getSdk(client, withWrapper = defaultWrapper) {
|
|
3914
3804
|
return {
|
|
@@ -3923,12 +3813,77 @@ function getSdk(client, withWrapper = defaultWrapper) {
|
|
|
3923
3813
|
},
|
|
3924
3814
|
getBlobActivitiesCount(variables, requestHeaders, signal) {
|
|
3925
3815
|
return withWrapper((wrappedRequestHeaders) => client.request({ document: GetBlobActivitiesCountDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "getBlobActivitiesCount", "query", variables);
|
|
3816
|
+
},
|
|
3817
|
+
getPlacementGroupSlots(variables, requestHeaders, signal) {
|
|
3818
|
+
return withWrapper((wrappedRequestHeaders) => client.request({ document: GetPlacementGroupSlotsDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "getPlacementGroupSlots", "query", variables);
|
|
3819
|
+
},
|
|
3820
|
+
getPlacementGroupSlotsCount(variables, requestHeaders, signal) {
|
|
3821
|
+
return withWrapper((wrappedRequestHeaders) => client.request({ document: GetPlacementGroupSlotsCountDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "getPlacementGroupSlotsCount", "query", variables);
|
|
3822
|
+
},
|
|
3823
|
+
getProcessorStatus(variables, requestHeaders, signal) {
|
|
3824
|
+
return withWrapper((wrappedRequestHeaders) => client.request({ document: GetProcessorStatusDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "getProcessorStatus", "query", variables);
|
|
3926
3825
|
}
|
|
3927
3826
|
};
|
|
3928
3827
|
}
|
|
3929
3828
|
|
|
3930
|
-
// ../../packages/sdk/dist/chunk-
|
|
3931
|
-
import {
|
|
3829
|
+
// ../../packages/sdk/dist/chunk-AABBONAF.mjs
|
|
3830
|
+
import { AptosConfig } from "@aptos-labs/ts-sdk";
|
|
3831
|
+
var getAptosConfig = (config) => {
|
|
3832
|
+
const baseFaucetConfig = config.faucet?.authToken ? { AUTH_TOKEN: config.faucet.authToken } : void 0;
|
|
3833
|
+
if (config.aptos) {
|
|
3834
|
+
return new AptosConfig({
|
|
3835
|
+
// Spread user's aptos config first
|
|
3836
|
+
...config.aptos,
|
|
3837
|
+
// Network from top-level is authoritative - cannot be overridden
|
|
3838
|
+
network: config.network,
|
|
3839
|
+
// Merge clientConfig with API_KEY default
|
|
3840
|
+
clientConfig: {
|
|
3841
|
+
API_KEY: config.apiKey,
|
|
3842
|
+
...config.aptos.clientConfig
|
|
3843
|
+
},
|
|
3844
|
+
// Merge faucetConfig: aptos config first, then base authToken (authoritative)
|
|
3845
|
+
faucetConfig: {
|
|
3846
|
+
...config.aptos.faucetConfig,
|
|
3847
|
+
...baseFaucetConfig
|
|
3848
|
+
}
|
|
3849
|
+
});
|
|
3850
|
+
}
|
|
3851
|
+
return new AptosConfig({
|
|
3852
|
+
network: config.network,
|
|
3853
|
+
clientConfig: {
|
|
3854
|
+
API_KEY: config.apiKey
|
|
3855
|
+
},
|
|
3856
|
+
faucetConfig: baseFaucetConfig
|
|
3857
|
+
});
|
|
3858
|
+
};
|
|
3859
|
+
|
|
3860
|
+
// ../../packages/sdk/dist/chunk-FLLOQZVD.mjs
|
|
3861
|
+
import { Network } from "@aptos-labs/ts-sdk";
|
|
3862
|
+
var NetworkToShelbyRPCBaseUrl = {
|
|
3863
|
+
[Network.SHELBYNET]: "https://api.shelbynet.shelby.xyz/shelby",
|
|
3864
|
+
[Network.NETNA]: void 0,
|
|
3865
|
+
[Network.DEVNET]: void 0,
|
|
3866
|
+
[Network.TESTNET]: void 0,
|
|
3867
|
+
[Network.MAINNET]: void 0,
|
|
3868
|
+
[Network.LOCAL]: void 0,
|
|
3869
|
+
[Network.CUSTOM]: void 0
|
|
3870
|
+
};
|
|
3871
|
+
var NetworkToShelbyBlobIndexerBaseUrl = {
|
|
3872
|
+
[Network.SHELBYNET]: "https://api.shelbynet.aptoslabs.com/nocode/v1/public/cmforrguw0042s601fn71f9l2/v1/graphql",
|
|
3873
|
+
[Network.NETNA]: void 0,
|
|
3874
|
+
[Network.DEVNET]: void 0,
|
|
3875
|
+
[Network.TESTNET]: void 0,
|
|
3876
|
+
[Network.MAINNET]: void 0,
|
|
3877
|
+
[Network.LOCAL]: void 0,
|
|
3878
|
+
[Network.CUSTOM]: void 0
|
|
3879
|
+
};
|
|
3880
|
+
var SHELBY_DEPLOYER = "0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5";
|
|
3881
|
+
var MICROPAYMENTS_DEPLOYER = "0xb42ac038b6dae86f6171e28e297aab9555ce09909445ec579e4ffe6b8d4d63bf";
|
|
3882
|
+
var SHELBYUSD_TOKEN_NAME = "ShelbyUSD";
|
|
3883
|
+
var SHELBYUSD_FA_METADATA_ADDRESS = "0x1b18363a9f1fe5e6ebf247daba5cc1c18052bb232efdc4c50f556053922d98e1";
|
|
3884
|
+
|
|
3885
|
+
// ../../packages/sdk/dist/chunk-3ZL3FSNA.mjs
|
|
3886
|
+
import { Network as Network2 } from "@aptos-labs/ts-sdk";
|
|
3932
3887
|
|
|
3933
3888
|
// ../../node_modules/.pnpm/graphql-request@7.2.0_graphql@16.11.0/node_modules/graphql-request/build/legacy/classes/ClientError.js
|
|
3934
3889
|
var ClientError = class _ClientError extends Error {
|
|
@@ -4442,21 +4397,21 @@ var parseRequestArgs = (documentOrOptions, variables, requestHeaders) => {
|
|
|
4442
4397
|
};
|
|
4443
4398
|
};
|
|
4444
4399
|
|
|
4445
|
-
// ../../packages/sdk/dist/chunk-
|
|
4400
|
+
// ../../packages/sdk/dist/chunk-3ZL3FSNA.mjs
|
|
4446
4401
|
function createShelbyIndexerClient(baseUrl, options) {
|
|
4447
4402
|
const graphqlClient = new GraphQLClient(baseUrl, options);
|
|
4448
4403
|
return getSdk(graphqlClient);
|
|
4449
4404
|
}
|
|
4450
4405
|
function getShelbyIndexerClient(config) {
|
|
4451
|
-
const aptosConfig =
|
|
4406
|
+
const aptosConfig = getAptosConfig(config);
|
|
4452
4407
|
let { apiKey: indexerApiKey, baseUrl } = config.indexer ?? {};
|
|
4453
4408
|
if (!baseUrl) {
|
|
4454
4409
|
switch (aptosConfig?.network) {
|
|
4455
4410
|
// TODO: Add endpoints for core networks
|
|
4456
|
-
case
|
|
4457
|
-
case
|
|
4458
|
-
case
|
|
4459
|
-
case
|
|
4411
|
+
case Network2.MAINNET:
|
|
4412
|
+
case Network2.TESTNET:
|
|
4413
|
+
case Network2.DEVNET:
|
|
4414
|
+
case Network2.SHELBYNET:
|
|
4460
4415
|
baseUrl = NetworkToShelbyBlobIndexerBaseUrl[aptosConfig.network];
|
|
4461
4416
|
break;
|
|
4462
4417
|
}
|
|
@@ -4475,96 +4430,14 @@ function getShelbyIndexerClient(config) {
|
|
|
4475
4430
|
});
|
|
4476
4431
|
}
|
|
4477
4432
|
|
|
4478
|
-
// ../../packages/sdk/dist/chunk-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
/* ChunkSet10MiB_Chunk1MiB */
|
|
4483
|
-
]: {
|
|
4484
|
-
// 1MiB
|
|
4485
|
-
chunkSizeBytes: 1 * 1024 * 1024,
|
|
4486
|
-
// 10MiB
|
|
4487
|
-
chunksetSizeBytes: 10 * 1024 * 1024
|
|
4488
|
-
}
|
|
4489
|
-
};
|
|
4490
|
-
var DEFAULT_CHUNK_SIZE_BYTES = CHUNK_SIZE_PARAMS[
|
|
4491
|
-
"ChunkSet10MiB_Chunk1MiB"
|
|
4492
|
-
/* ChunkSet10MiB_Chunk1MiB */
|
|
4493
|
-
].chunkSizeBytes;
|
|
4494
|
-
var DEFAULT_CHUNKSET_SIZE_BYTES = CHUNK_SIZE_PARAMS[
|
|
4495
|
-
"ChunkSet10MiB_Chunk1MiB"
|
|
4496
|
-
/* ChunkSet10MiB_Chunk1MiB */
|
|
4497
|
-
].chunksetSizeBytes;
|
|
4498
|
-
var ERASURE_CODE_AND_CHUNK_MAPPING = {
|
|
4499
|
-
[
|
|
4500
|
-
"ClayCode_16Total_10Data_13Helper"
|
|
4501
|
-
/* ClayCode_16Total_10Data_13Helper */
|
|
4502
|
-
]: {
|
|
4503
|
-
...CHUNK_SIZE_PARAMS.ChunkSet10MiB_Chunk1MiB
|
|
4504
|
-
}
|
|
4505
|
-
};
|
|
4506
|
-
|
|
4507
|
-
// ../../packages/sdk/dist/chunk-LZSIZJYR.mjs
|
|
4508
|
-
var ERASURE_CODE_PARAMS = {
|
|
4509
|
-
[
|
|
4510
|
-
"ClayCode_16Total_10Data_13Helper"
|
|
4511
|
-
/* ClayCode_16Total_10Data_13Helper */
|
|
4512
|
-
]: {
|
|
4513
|
-
// total chunks (data + parity)
|
|
4514
|
-
erasure_n: 16,
|
|
4515
|
-
// data chunks
|
|
4516
|
-
erasure_k: 10,
|
|
4517
|
-
// helper nodes
|
|
4518
|
-
erasure_d: 13
|
|
4519
|
-
}
|
|
4433
|
+
// ../../packages/sdk/dist/chunk-OTBLZL2S.mjs
|
|
4434
|
+
import { AccountAddress } from "@aptos-labs/ts-sdk";
|
|
4435
|
+
var createBlobKey = (params) => {
|
|
4436
|
+
return `@${AccountAddress.from(params.account).toStringLongWithoutPrefix()}/${params.blobName}`;
|
|
4520
4437
|
};
|
|
4521
|
-
var DEFAULT_ERASURE_N = ERASURE_CODE_PARAMS[
|
|
4522
|
-
"ClayCode_16Total_10Data_13Helper"
|
|
4523
|
-
/* ClayCode_16Total_10Data_13Helper */
|
|
4524
|
-
].erasure_n;
|
|
4525
|
-
var DEFAULT_ERASURE_K = ERASURE_CODE_PARAMS[
|
|
4526
|
-
"ClayCode_16Total_10Data_13Helper"
|
|
4527
|
-
/* ClayCode_16Total_10Data_13Helper */
|
|
4528
|
-
].erasure_k;
|
|
4529
|
-
var DEFAULT_ERASURE_D = ERASURE_CODE_PARAMS[
|
|
4530
|
-
"ClayCode_16Total_10Data_13Helper"
|
|
4531
|
-
/* ClayCode_16Total_10Data_13Helper */
|
|
4532
|
-
].erasure_d;
|
|
4533
|
-
var DEFAULT_ERASURE_M = DEFAULT_ERASURE_N - DEFAULT_ERASURE_K;
|
|
4534
|
-
|
|
4535
|
-
// ../../packages/sdk/dist/chunk-W5NRGZEP.mjs
|
|
4536
|
-
import { AccountAddress as AccountAddress2 } from "@aptos-labs/ts-sdk";
|
|
4537
|
-
import { z } from "zod";
|
|
4538
|
-
var BlobNameSchema = z.string().min(1, "Blob name path parameter cannot be empty.").max(1024, "Blob name cannot exceed 1024 characters.").refine((name2) => !name2.endsWith("/"), {
|
|
4539
|
-
message: "Blob name cannot end with a slash"
|
|
4540
|
-
});
|
|
4541
|
-
|
|
4542
|
-
// ../../packages/sdk/dist/chunk-I6NG5GNL.mjs
|
|
4543
|
-
function sleep(ms) {
|
|
4544
|
-
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
4545
|
-
}
|
|
4546
|
-
|
|
4547
|
-
// ../../packages/sdk/dist/chunk-IE6LYVIA.mjs
|
|
4548
|
-
import { z as z2 } from "zod";
|
|
4549
|
-
var StartMultipartUploadResponseSchema = z2.object({
|
|
4550
|
-
uploadId: z2.string()
|
|
4551
|
-
});
|
|
4552
|
-
var UploadPartResponseSchema = z2.object({
|
|
4553
|
-
success: z2.literal(true)
|
|
4554
|
-
});
|
|
4555
|
-
var CompleteMultipartUploadResponseSchema = z2.object({
|
|
4556
|
-
success: z2.literal(true)
|
|
4557
|
-
});
|
|
4558
|
-
var RPCErrorResponseSchema = z2.object({
|
|
4559
|
-
error: z2.string()
|
|
4560
|
-
});
|
|
4561
|
-
var StaleMicropaymentErrorResponseSchema = z2.object({
|
|
4562
|
-
error: z2.string().optional(),
|
|
4563
|
-
storedMicropayment: z2.string().optional()
|
|
4564
|
-
});
|
|
4565
4438
|
|
|
4566
4439
|
// ../../packages/sdk/dist/chunk-4JZO2D7T.mjs
|
|
4567
|
-
import { Hex
|
|
4440
|
+
import { Hex } from "@aptos-labs/ts-sdk";
|
|
4568
4441
|
async function* readInChunks(input, chunkSize) {
|
|
4569
4442
|
let idx = 0;
|
|
4570
4443
|
if (isReadableStream(input)) {
|
|
@@ -4624,7 +4497,7 @@ function zeroPadBytes(buffer, desiredLength) {
|
|
|
4624
4497
|
return paddedBuffer;
|
|
4625
4498
|
}
|
|
4626
4499
|
async function concatHashes(parts) {
|
|
4627
|
-
const chunks = parts.map((part) =>
|
|
4500
|
+
const chunks = parts.map((part) => Hex.fromHexInput(part).toUint8Array());
|
|
4628
4501
|
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
|
|
4629
4502
|
const combined = new Uint8Array(totalLength);
|
|
4630
4503
|
let offset = 0;
|
|
@@ -4632,7 +4505,7 @@ async function concatHashes(parts) {
|
|
|
4632
4505
|
combined.set(chunk, offset);
|
|
4633
4506
|
offset += chunk.byteLength;
|
|
4634
4507
|
}
|
|
4635
|
-
return
|
|
4508
|
+
return Hex.fromHexInput(
|
|
4636
4509
|
new Uint8Array(await crypto.subtle.digest("SHA-256", combined))
|
|
4637
4510
|
);
|
|
4638
4511
|
}
|
|
@@ -4653,1237 +4526,1544 @@ function getBlobNameSuffix(blobName) {
|
|
|
4653
4526
|
return parts.slice(1).join("/") || "";
|
|
4654
4527
|
}
|
|
4655
4528
|
|
|
4656
|
-
// ../../packages/sdk/dist/chunk-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
indexer;
|
|
4667
|
-
/**
|
|
4668
|
-
* Creates a new ShelbyRPCClient for interacting with Shelby RPC nodes.
|
|
4669
|
-
* This client handles blob storage operations including upload and download.
|
|
4670
|
-
*
|
|
4671
|
-
* @param config - The client configuration object.
|
|
4672
|
-
* @param config.network - The Shelby network to use.
|
|
4673
|
-
*
|
|
4674
|
-
* @example
|
|
4675
|
-
* ```typescript
|
|
4676
|
-
* const client = new ShelbyRPCClient({
|
|
4677
|
-
* network: Network.SHELBYNET,
|
|
4678
|
-
* apiKey: "AG-***",
|
|
4679
|
-
* });
|
|
4680
|
-
* ```
|
|
4681
|
-
*/
|
|
4682
|
-
constructor(config) {
|
|
4683
|
-
this.baseUrl = config.rpc?.baseUrl ?? NetworkToShelbyRPCBaseUrl.shelbynet;
|
|
4684
|
-
this.apiKey = config.apiKey ?? config.rpc?.apiKey;
|
|
4685
|
-
this.rpcConfig = config.rpc ?? {};
|
|
4686
|
-
this.indexer = getShelbyIndexerClient(config);
|
|
4529
|
+
// ../../packages/sdk/dist/chunk-67F5YZ25.mjs
|
|
4530
|
+
var CHUNK_SIZE_PARAMS = {
|
|
4531
|
+
[
|
|
4532
|
+
"ChunkSet10MiB_Chunk1MiB"
|
|
4533
|
+
/* ChunkSet10MiB_Chunk1MiB */
|
|
4534
|
+
]: {
|
|
4535
|
+
// 1MiB
|
|
4536
|
+
chunkSizeBytes: 1 * 1024 * 1024,
|
|
4537
|
+
// 10MiB
|
|
4538
|
+
chunksetSizeBytes: 10 * 1024 * 1024
|
|
4687
4539
|
}
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
}
|
|
4704
|
-
);
|
|
4705
|
-
if (partResponse.ok) return;
|
|
4706
|
-
if (i < nRetries - 1) {
|
|
4707
|
-
const delay = 2 ** i * 100;
|
|
4708
|
-
await sleep(delay);
|
|
4709
|
-
}
|
|
4710
|
-
}
|
|
4711
|
-
throw new Error(`Failed to upload part ${partIdx}.`);
|
|
4540
|
+
};
|
|
4541
|
+
var DEFAULT_CHUNK_SIZE_BYTES = CHUNK_SIZE_PARAMS[
|
|
4542
|
+
"ChunkSet10MiB_Chunk1MiB"
|
|
4543
|
+
/* ChunkSet10MiB_Chunk1MiB */
|
|
4544
|
+
].chunkSizeBytes;
|
|
4545
|
+
var DEFAULT_CHUNKSET_SIZE_BYTES = CHUNK_SIZE_PARAMS[
|
|
4546
|
+
"ChunkSet10MiB_Chunk1MiB"
|
|
4547
|
+
/* ChunkSet10MiB_Chunk1MiB */
|
|
4548
|
+
].chunksetSizeBytes;
|
|
4549
|
+
var ERASURE_CODE_AND_CHUNK_MAPPING = {
|
|
4550
|
+
[
|
|
4551
|
+
"ClayCode_16Total_10Data_13Helper"
|
|
4552
|
+
/* ClayCode_16Total_10Data_13Helper */
|
|
4553
|
+
]: {
|
|
4554
|
+
...CHUNK_SIZE_PARAMS.ChunkSet10MiB_Chunk1MiB
|
|
4712
4555
|
}
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4556
|
+
};
|
|
4557
|
+
|
|
4558
|
+
// ../../packages/sdk/dist/chunk-LZSIZJYR.mjs
|
|
4559
|
+
var ERASURE_CODE_PARAMS = {
|
|
4560
|
+
[
|
|
4561
|
+
"ClayCode_16Total_10Data_13Helper"
|
|
4562
|
+
/* ClayCode_16Total_10Data_13Helper */
|
|
4563
|
+
]: {
|
|
4564
|
+
// total chunks (data + parity)
|
|
4565
|
+
erasure_n: 16,
|
|
4566
|
+
// data chunks
|
|
4567
|
+
erasure_k: 10,
|
|
4568
|
+
// helper nodes
|
|
4569
|
+
erasure_d: 13
|
|
4570
|
+
}
|
|
4571
|
+
};
|
|
4572
|
+
var DEFAULT_ERASURE_N = ERASURE_CODE_PARAMS[
|
|
4573
|
+
"ClayCode_16Total_10Data_13Helper"
|
|
4574
|
+
/* ClayCode_16Total_10Data_13Helper */
|
|
4575
|
+
].erasure_n;
|
|
4576
|
+
var DEFAULT_ERASURE_K = ERASURE_CODE_PARAMS[
|
|
4577
|
+
"ClayCode_16Total_10Data_13Helper"
|
|
4578
|
+
/* ClayCode_16Total_10Data_13Helper */
|
|
4579
|
+
].erasure_k;
|
|
4580
|
+
var DEFAULT_ERASURE_D = ERASURE_CODE_PARAMS[
|
|
4581
|
+
"ClayCode_16Total_10Data_13Helper"
|
|
4582
|
+
/* ClayCode_16Total_10Data_13Helper */
|
|
4583
|
+
].erasure_d;
|
|
4584
|
+
var DEFAULT_ERASURE_M = DEFAULT_ERASURE_N - DEFAULT_ERASURE_K;
|
|
4585
|
+
|
|
4586
|
+
// ../../packages/sdk/dist/chunk-RLRI2533.mjs
|
|
4587
|
+
import { Hex as Hex2 } from "@aptos-labs/ts-sdk";
|
|
4588
|
+
import { z } from "zod";
|
|
4589
|
+
var COMMITMENT_SCHEMA_VERSION = "1.3";
|
|
4590
|
+
var ChunksetCommitmentSchema = z.object({
|
|
4591
|
+
// Chunkset root (vector commitment of child chunks)
|
|
4592
|
+
chunkset_root: z.string(),
|
|
4593
|
+
// the size is known statically from the current configuration
|
|
4594
|
+
chunk_commitments: z.array(z.string())
|
|
4595
|
+
}).refine(
|
|
4596
|
+
(data) => {
|
|
4597
|
+
return data.chunk_commitments.length === DEFAULT_ERASURE_K + DEFAULT_ERASURE_M;
|
|
4598
|
+
},
|
|
4599
|
+
{
|
|
4600
|
+
message: `Chunkset must have exactly ${DEFAULT_ERASURE_K + DEFAULT_ERASURE_M} chunks (ERASURE_K + ERASURE_M = ${DEFAULT_ERASURE_K} + ${DEFAULT_ERASURE_M})`,
|
|
4601
|
+
path: ["chunk_commitments"]
|
|
4602
|
+
}
|
|
4603
|
+
);
|
|
4604
|
+
function expectedTotalChunksets(rawSize, chunksetSize = DEFAULT_CHUNKSET_SIZE_BYTES) {
|
|
4605
|
+
if (chunksetSize <= 0) {
|
|
4606
|
+
throw new Error("chunksetSize must be positive");
|
|
4607
|
+
}
|
|
4608
|
+
if (rawSize === 0) return 1;
|
|
4609
|
+
return Math.ceil(rawSize / chunksetSize);
|
|
4610
|
+
}
|
|
4611
|
+
var BlobCommitmentsSchema = z.object({
|
|
4612
|
+
schema_version: z.string(),
|
|
4613
|
+
raw_data_size: z.number(),
|
|
4614
|
+
// FIXME I am not sure about this being here, or if it should be somewhere else
|
|
4615
|
+
blob_merkle_root: z.string(),
|
|
4616
|
+
chunkset_commitments: z.array(ChunksetCommitmentSchema)
|
|
4617
|
+
}).refine(
|
|
4618
|
+
(data) => {
|
|
4619
|
+
return expectedTotalChunksets(data.raw_data_size) === data.chunkset_commitments.length;
|
|
4620
|
+
},
|
|
4621
|
+
{
|
|
4622
|
+
message: "Total chunkset count mismatches with raw data size",
|
|
4623
|
+
// FIXME put more details in here
|
|
4624
|
+
path: ["chunkset_commitments"]
|
|
4625
|
+
}
|
|
4626
|
+
);
|
|
4627
|
+
async function generateMerkleRoot(leafHashes) {
|
|
4628
|
+
if (!leafHashes.length) {
|
|
4629
|
+
throw new Error(
|
|
4630
|
+
"An empty array cannot be used to construct a Merkle tree."
|
|
4728
4631
|
);
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
`Failed to start multipart upload! status: ${startResponse.status}, body: ${errorBodyText}`
|
|
4737
|
-
);
|
|
4632
|
+
}
|
|
4633
|
+
const zeroArray = new Uint8Array(leafHashes[0].toUint8Array().length);
|
|
4634
|
+
const zeroBytes = Hex2.fromHexInput(zeroArray);
|
|
4635
|
+
let currentLeaves = leafHashes;
|
|
4636
|
+
while (currentLeaves.length > 1) {
|
|
4637
|
+
if (currentLeaves.length % 2 !== 0) {
|
|
4638
|
+
currentLeaves.push(zeroBytes);
|
|
4738
4639
|
}
|
|
4739
|
-
const
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
await this.#uploadPart(uploadId, partIdx, partData);
|
|
4748
|
-
onProgress?.({
|
|
4749
|
-
partIdx,
|
|
4750
|
-
totalParts,
|
|
4751
|
-
partBytes: partData.length,
|
|
4752
|
-
uploadedBytes: end,
|
|
4753
|
-
totalBytes: blobData.length
|
|
4754
|
-
});
|
|
4640
|
+
const nextLeaves = [];
|
|
4641
|
+
for (let i = 0; i < currentLeaves.length; i += 2) {
|
|
4642
|
+
nextLeaves.push(
|
|
4643
|
+
await concatHashes([
|
|
4644
|
+
currentLeaves[i].toUint8Array(),
|
|
4645
|
+
currentLeaves[i + 1].toUint8Array()
|
|
4646
|
+
])
|
|
4647
|
+
);
|
|
4755
4648
|
}
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4649
|
+
currentLeaves = nextLeaves;
|
|
4650
|
+
}
|
|
4651
|
+
return currentLeaves[0];
|
|
4652
|
+
}
|
|
4653
|
+
async function generateChunksetCommitments(shouldPad, chunksetIdx, chunksetData, expectedChunksetSize, provider, onChunk) {
|
|
4654
|
+
const { erasure_n } = provider.config;
|
|
4655
|
+
const chunksetPayload = shouldPad ? zeroPadBytes(chunksetData, expectedChunksetSize) : validatePrePaddedChunkset(
|
|
4656
|
+
chunksetData,
|
|
4657
|
+
expectedChunksetSize,
|
|
4658
|
+
chunksetIdx
|
|
4659
|
+
);
|
|
4660
|
+
const { chunks } = provider.encode(chunksetPayload);
|
|
4661
|
+
if (chunks.length !== erasure_n) {
|
|
4662
|
+
throw new Error(
|
|
4663
|
+
`Erasure provider produced ${chunks.length} chunks, expected ${erasure_n}.`
|
|
4768
4664
|
);
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
throw new Error(
|
|
4776
|
-
`Failed to complete multipart upload! status: ${completeResponse.status}, body: ${errorBodyText}`
|
|
4777
|
-
);
|
|
4665
|
+
}
|
|
4666
|
+
const chunkRoots = provider.getChunkMerkleRoots();
|
|
4667
|
+
let chunkIdx = 0;
|
|
4668
|
+
for (const chunkData of chunks) {
|
|
4669
|
+
if (onChunk !== void 0) {
|
|
4670
|
+
await onChunk(chunksetIdx, chunkIdx, chunkData);
|
|
4778
4671
|
}
|
|
4672
|
+
chunkIdx += 1;
|
|
4779
4673
|
}
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
params.onProgress
|
|
4674
|
+
const a = await generateMerkleRoot(
|
|
4675
|
+
chunkRoots.map((a2) => Hex2.fromHexInput(a2))
|
|
4676
|
+
);
|
|
4677
|
+
const entry = {
|
|
4678
|
+
chunkset_root: a.toString(),
|
|
4679
|
+
chunk_commitments: chunkRoots.map(
|
|
4680
|
+
(chunk) => Hex2.fromHexInput(chunk).toString()
|
|
4681
|
+
)
|
|
4682
|
+
};
|
|
4683
|
+
return { h: a, entry };
|
|
4684
|
+
}
|
|
4685
|
+
async function generateCommitments(provider, fullData, onChunk, options) {
|
|
4686
|
+
const expectedChunksetSize = DEFAULT_CHUNKSET_SIZE_BYTES;
|
|
4687
|
+
const shouldPad = options?.pad ?? true;
|
|
4688
|
+
const chunksetCommitments = [];
|
|
4689
|
+
const chunksetCommitmentHashes = [];
|
|
4690
|
+
let rawDataSize = 0;
|
|
4691
|
+
const chunksetGen = readInChunks(fullData, expectedChunksetSize);
|
|
4692
|
+
for await (const [chunksetIdx, chunksetData] of chunksetGen) {
|
|
4693
|
+
rawDataSize += chunksetData.length;
|
|
4694
|
+
const { h, entry } = await generateChunksetCommitments(
|
|
4695
|
+
shouldPad,
|
|
4696
|
+
chunksetIdx,
|
|
4697
|
+
chunksetData,
|
|
4698
|
+
expectedChunksetSize,
|
|
4699
|
+
provider,
|
|
4700
|
+
onChunk
|
|
4808
4701
|
);
|
|
4702
|
+
chunksetCommitments.push(entry);
|
|
4703
|
+
chunksetCommitmentHashes.push(h);
|
|
4809
4704
|
}
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4705
|
+
if (rawDataSize === 0) {
|
|
4706
|
+
const zeroChunkset = new Uint8Array(expectedChunksetSize);
|
|
4707
|
+
const { h, entry } = await generateChunksetCommitments(
|
|
4708
|
+
shouldPad,
|
|
4709
|
+
0,
|
|
4710
|
+
zeroChunkset,
|
|
4711
|
+
expectedChunksetSize,
|
|
4712
|
+
provider,
|
|
4713
|
+
onChunk
|
|
4714
|
+
);
|
|
4715
|
+
chunksetCommitments.push(entry);
|
|
4716
|
+
chunksetCommitmentHashes.push(h);
|
|
4717
|
+
}
|
|
4718
|
+
return {
|
|
4719
|
+
schema_version: COMMITMENT_SCHEMA_VERSION,
|
|
4720
|
+
raw_data_size: rawDataSize,
|
|
4721
|
+
blob_merkle_root: (await generateMerkleRoot(chunksetCommitmentHashes)).toString(),
|
|
4722
|
+
chunkset_commitments: chunksetCommitments
|
|
4723
|
+
};
|
|
4724
|
+
}
|
|
4725
|
+
function validatePrePaddedChunkset(chunkset, expectedSize, chunksetIdx) {
|
|
4726
|
+
if (chunkset.byteLength !== expectedSize) {
|
|
4727
|
+
throw new Error(
|
|
4728
|
+
`Chunkset ${chunksetIdx} has size ${chunkset.byteLength} bytes but expected ${expectedSize} bytes. Enable padding or supply pre-padded data before calling generateCommitments.`
|
|
4729
|
+
);
|
|
4730
|
+
}
|
|
4731
|
+
return chunkset;
|
|
4732
|
+
}
|
|
4733
|
+
|
|
4734
|
+
// ../../packages/sdk/dist/chunk-AGRRYZWV.mjs
|
|
4735
|
+
import {
|
|
4736
|
+
AccountAddress as AccountAddress2,
|
|
4737
|
+
Aptos,
|
|
4738
|
+
Hex as Hex3,
|
|
4739
|
+
U32
|
|
4740
|
+
} from "@aptos-labs/ts-sdk";
|
|
4741
|
+
var MissingTransactionSubmitterError = class extends Error {
|
|
4742
|
+
constructor() {
|
|
4743
|
+
super(
|
|
4744
|
+
"USD sponsorship (usdSponsor) requires a transaction submitter to be configured. The sponsored transaction is a multi-agent transaction that must be co-signed by the sponsor. Configure a transaction submitter via aptos.pluginSettings.TRANSACTION_SUBMITTER that routes transactions to a service (like a gas station) capable of providing the sponsor's signature."
|
|
4745
|
+
);
|
|
4746
|
+
this.name = "MissingTransactionSubmitterError";
|
|
4747
|
+
}
|
|
4748
|
+
};
|
|
4749
|
+
var ShelbyBlobClient = class _ShelbyBlobClient {
|
|
4750
|
+
aptos;
|
|
4751
|
+
deployer;
|
|
4752
|
+
indexer;
|
|
4753
|
+
defaultOptions;
|
|
4754
|
+
/**
|
|
4755
|
+
* The ShelbyBlobClient is used to interact with the Shelby contract on the Aptos blockchain. This
|
|
4756
|
+
* includes functions for registering blob commitments and retrieving blob metadata.
|
|
4823
4757
|
*
|
|
4824
|
-
* @
|
|
4825
|
-
* @
|
|
4758
|
+
* @param config - The client configuration object.
|
|
4759
|
+
* @param config.network - The Shelby network to use.
|
|
4760
|
+
* @param defaultOptions - Optional default options for blob operations.
|
|
4826
4761
|
*
|
|
4827
4762
|
* @example
|
|
4828
4763
|
* ```typescript
|
|
4829
|
-
*
|
|
4830
|
-
*
|
|
4831
|
-
*
|
|
4832
|
-
*
|
|
4764
|
+
* const blobClient = new ShelbyBlobClient({
|
|
4765
|
+
* aptos: {
|
|
4766
|
+
* network: Network.SHELBYNET,
|
|
4767
|
+
* clientConfig: {
|
|
4768
|
+
* API_KEY: "AG-***",
|
|
4769
|
+
* },
|
|
4770
|
+
* },
|
|
4833
4771
|
* });
|
|
4772
|
+
* ```
|
|
4834
4773
|
*
|
|
4835
|
-
*
|
|
4836
|
-
*
|
|
4837
|
-
*
|
|
4838
|
-
*
|
|
4839
|
-
*
|
|
4840
|
-
*
|
|
4774
|
+
* @example
|
|
4775
|
+
* ```typescript
|
|
4776
|
+
* // With default options for USD sponsorship
|
|
4777
|
+
* const blobClient = new ShelbyBlobClient(
|
|
4778
|
+
* {
|
|
4779
|
+
* network: Network.SHELBYNET,
|
|
4780
|
+
* aptos: {
|
|
4781
|
+
* pluginSettings: {
|
|
4782
|
+
* TRANSACTION_SUBMITTER: myGasStationSubmitter,
|
|
4783
|
+
* },
|
|
4784
|
+
* },
|
|
4785
|
+
* },
|
|
4786
|
+
* {
|
|
4787
|
+
* usdSponsor: { feePayerAddress: sponsorAddress },
|
|
4788
|
+
* }
|
|
4789
|
+
* );
|
|
4790
|
+
* ```
|
|
4791
|
+
*/
|
|
4792
|
+
constructor(config, defaultOptions) {
|
|
4793
|
+
this.aptos = new Aptos(getAptosConfig(config));
|
|
4794
|
+
this.deployer = config.deployer ?? AccountAddress2.fromString(SHELBY_DEPLOYER);
|
|
4795
|
+
this.indexer = getShelbyIndexerClient(config);
|
|
4796
|
+
this.defaultOptions = defaultOptions ?? {};
|
|
4797
|
+
}
|
|
4798
|
+
/**
|
|
4799
|
+
* Merges method-level options with default options, giving precedence to method-level values.
|
|
4800
|
+
*/
|
|
4801
|
+
mergeOptions(options) {
|
|
4802
|
+
return {
|
|
4803
|
+
build: options?.build ?? this.defaultOptions.build,
|
|
4804
|
+
submit: options?.submit ?? this.defaultOptions.submit,
|
|
4805
|
+
usdSponsor: options?.usdSponsor ?? this.defaultOptions.usdSponsor,
|
|
4806
|
+
chunksetSizeBytes: options?.chunksetSizeBytes ?? this.defaultOptions.chunksetSizeBytes
|
|
4807
|
+
};
|
|
4808
|
+
}
|
|
4809
|
+
/**
|
|
4810
|
+
* Validates that if USD sponsorship is requested, a transaction submitter is
|
|
4811
|
+
* configured as well. Checks both the client-level and method-level transaction
|
|
4812
|
+
* submitter configurations. Throws MissingTransactionSubmitterError if usdSponsor is
|
|
4813
|
+
* provided without a transaction submitter.
|
|
4814
|
+
*/
|
|
4815
|
+
validateUsdSponsorConfig(usdSponsor, submit) {
|
|
4816
|
+
if (!usdSponsor) {
|
|
4817
|
+
return;
|
|
4818
|
+
}
|
|
4819
|
+
const hasClientSubmitter = this.aptos.config.getTransactionSubmitter();
|
|
4820
|
+
const hasMethodSubmitter = submit?.transactionSubmitter !== void 0 && submit?.transactionSubmitter !== null;
|
|
4821
|
+
if (!hasClientSubmitter && !hasMethodSubmitter) {
|
|
4822
|
+
throw new MissingTransactionSubmitterError();
|
|
4823
|
+
}
|
|
4824
|
+
}
|
|
4825
|
+
/**
|
|
4826
|
+
* Retrieves the blob metadata from the blockchain. If it does not exist,
|
|
4827
|
+
* returns `undefined`.
|
|
4841
4828
|
*
|
|
4842
|
-
*
|
|
4843
|
-
*
|
|
4844
|
-
*
|
|
4845
|
-
*
|
|
4846
|
-
*
|
|
4829
|
+
* @param params.account - The account namespace the blob is stored in (e.g. "0x1")
|
|
4830
|
+
* @param params.name - The name of the blob (e.g. "foo/bar")
|
|
4831
|
+
* @returns The blob metadata.
|
|
4832
|
+
*
|
|
4833
|
+
* @example
|
|
4834
|
+
* ```typescript
|
|
4835
|
+
* const metadata = await client.getBlobMetadata({
|
|
4836
|
+
* account: AccountAddress.fromString("0x1"),
|
|
4837
|
+
* name: "foo/bar.txt",
|
|
4847
4838
|
* });
|
|
4848
4839
|
* ```
|
|
4849
4840
|
*/
|
|
4850
|
-
async
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
if (end === void 0) {
|
|
4862
|
-
headers.set("Range", `bytes=${start}-`);
|
|
4863
|
-
} else {
|
|
4864
|
-
if (end < start) {
|
|
4865
|
-
throw new Error("Range end cannot be less than start.");
|
|
4841
|
+
async getBlobMetadata(params) {
|
|
4842
|
+
try {
|
|
4843
|
+
const rawMetadata = await this.aptos.view({
|
|
4844
|
+
payload: {
|
|
4845
|
+
function: `${this.deployer.toString()}::blob_metadata::get_blob_metadata`,
|
|
4846
|
+
functionArguments: [
|
|
4847
|
+
createBlobKey({
|
|
4848
|
+
account: params.account,
|
|
4849
|
+
blobName: params.name
|
|
4850
|
+
})
|
|
4851
|
+
]
|
|
4866
4852
|
}
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
if (this.apiKey) {
|
|
4871
|
-
headers.set("Authorization", `Bearer ${this.apiKey}`);
|
|
4872
|
-
}
|
|
4873
|
-
if (params.micropayment) {
|
|
4874
|
-
const bytes = params.micropayment.bcsToBytes();
|
|
4875
|
-
const binaryString = Array.from(
|
|
4876
|
-
bytes,
|
|
4877
|
-
(byte) => String.fromCharCode(byte)
|
|
4878
|
-
).join("");
|
|
4879
|
-
headers.set(MICROPAYMENT_HEADER, btoa(binaryString));
|
|
4880
|
-
}
|
|
4881
|
-
const response = await fetch(url, { headers });
|
|
4882
|
-
if (response.status === 409) {
|
|
4883
|
-
let json;
|
|
4884
|
-
try {
|
|
4885
|
-
json = await response.json();
|
|
4886
|
-
} catch {
|
|
4887
|
-
throw new Error(
|
|
4888
|
-
`Failed to download blob: ${response.status} ${response.statusText}`
|
|
4889
|
-
);
|
|
4853
|
+
});
|
|
4854
|
+
if (!rawMetadata?.[0]?.vec?.[0]) {
|
|
4855
|
+
return void 0;
|
|
4890
4856
|
}
|
|
4891
|
-
const
|
|
4892
|
-
|
|
4857
|
+
const metadata = rawMetadata[0].vec[0];
|
|
4858
|
+
let encoding;
|
|
4859
|
+
if (metadata.encoding.__variant__ === "ClayCode_16Total_10Data_13Helper") {
|
|
4860
|
+
encoding = {
|
|
4861
|
+
variant: "clay",
|
|
4862
|
+
...ERASURE_CODE_PARAMS[metadata.encoding.__variant__],
|
|
4863
|
+
...ERASURE_CODE_AND_CHUNK_MAPPING[metadata.encoding.__variant__]
|
|
4864
|
+
};
|
|
4865
|
+
} else {
|
|
4893
4866
|
throw new Error(
|
|
4894
|
-
|
|
4867
|
+
"Could not parse encoding from Shelby Smart Contract, this SDK is out of date."
|
|
4895
4868
|
);
|
|
4896
4869
|
}
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4870
|
+
return {
|
|
4871
|
+
blobMerkleRoot: Hex3.fromHexInput(
|
|
4872
|
+
metadata.blob_commitment
|
|
4873
|
+
).toUint8Array(),
|
|
4874
|
+
owner: AccountAddress2.fromString(metadata.owner),
|
|
4875
|
+
name: params.name,
|
|
4876
|
+
blobNameSuffix: getBlobNameSuffix(params.name),
|
|
4877
|
+
size: Number(metadata.blob_size),
|
|
4878
|
+
encoding,
|
|
4879
|
+
expirationMicros: Number(metadata.expiration_micros),
|
|
4880
|
+
creationMicros: Number(metadata.creation_micros),
|
|
4881
|
+
sliceAddress: AccountAddress2.fromString(metadata.slice.inner),
|
|
4882
|
+
isWritten: metadata.is_written
|
|
4883
|
+
};
|
|
4884
|
+
} catch (error) {
|
|
4885
|
+
if (error instanceof Error && // Depending on the network, the error message may show up differently.
|
|
4886
|
+
(error.message?.includes("sub_status: Some(404)") || error.message?.includes("EBLOB_NOT_FOUND"))) {
|
|
4887
|
+
return void 0;
|
|
4903
4888
|
}
|
|
4904
|
-
throw
|
|
4905
|
-
errorBody.error ?? `Failed to download blob: ${response.status} ${response.statusText}`
|
|
4906
|
-
);
|
|
4907
|
-
}
|
|
4908
|
-
if (!response.ok) {
|
|
4909
|
-
throw new Error(
|
|
4910
|
-
`Failed to download blob: ${response.status} ${response.statusText}`
|
|
4911
|
-
);
|
|
4912
|
-
}
|
|
4913
|
-
if (!response.body) {
|
|
4914
|
-
throw new Error("Response body is null");
|
|
4915
|
-
}
|
|
4916
|
-
const contentLengthHeader = response.headers.get("content-length");
|
|
4917
|
-
if (contentLengthHeader === null) {
|
|
4918
|
-
throw new Error(
|
|
4919
|
-
"Response did not have content-length header, which is required"
|
|
4920
|
-
);
|
|
4921
|
-
}
|
|
4922
|
-
const expectedContentLength = Number.parseInt(contentLengthHeader, 10);
|
|
4923
|
-
if (Number.isNaN(expectedContentLength)) {
|
|
4924
|
-
throw new Error(
|
|
4925
|
-
`Invalid content-length header received: ${contentLengthHeader}`
|
|
4926
|
-
);
|
|
4889
|
+
throw error;
|
|
4927
4890
|
}
|
|
4928
|
-
const validatingStream = new ReadableStream({
|
|
4929
|
-
start(controller) {
|
|
4930
|
-
const maybeReader = response.body?.getReader();
|
|
4931
|
-
if (!maybeReader) {
|
|
4932
|
-
controller.error(new Error("Response body reader is unavailable"));
|
|
4933
|
-
return;
|
|
4934
|
-
}
|
|
4935
|
-
const reader = maybeReader;
|
|
4936
|
-
let bytesReceived = 0;
|
|
4937
|
-
function pump() {
|
|
4938
|
-
return reader.read().then(({ done, value }) => {
|
|
4939
|
-
if (done) {
|
|
4940
|
-
if (bytesReceived !== expectedContentLength) {
|
|
4941
|
-
controller.error(
|
|
4942
|
-
new Error(
|
|
4943
|
-
`Downloaded data size (${bytesReceived} bytes) does not match content-length header (${expectedContentLength} bytes). This might indicate a partial or corrupted download.`
|
|
4944
|
-
)
|
|
4945
|
-
);
|
|
4946
|
-
return;
|
|
4947
|
-
}
|
|
4948
|
-
controller.close();
|
|
4949
|
-
return;
|
|
4950
|
-
}
|
|
4951
|
-
bytesReceived += value.byteLength;
|
|
4952
|
-
controller.enqueue(value);
|
|
4953
|
-
return pump();
|
|
4954
|
-
}).catch((error) => {
|
|
4955
|
-
controller.error(error);
|
|
4956
|
-
});
|
|
4957
|
-
}
|
|
4958
|
-
return pump();
|
|
4959
|
-
}
|
|
4960
|
-
});
|
|
4961
|
-
return {
|
|
4962
|
-
account: AccountAddress3.from(params.account),
|
|
4963
|
-
name: params.blobName,
|
|
4964
|
-
readable: validatingStream,
|
|
4965
|
-
contentLength: expectedContentLength
|
|
4966
|
-
};
|
|
4967
4891
|
}
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
return
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
if (chunksetSize <= 0) {
|
|
4996
|
-
throw new Error("chunksetSize must be positive");
|
|
4892
|
+
/**
|
|
4893
|
+
* Retrieves all the blobs and their metadata for an account from the
|
|
4894
|
+
* blockchain.
|
|
4895
|
+
*
|
|
4896
|
+
* @param params.account - The account namespace the blobs are stored in (e.g. "0x1")
|
|
4897
|
+
* @param params.pagination (optional) - The pagination options.
|
|
4898
|
+
* @param params.orderBy (optional) - The order by clause to sort the blobs by.
|
|
4899
|
+
* @returns The blob metadata for all the blobs for the account.
|
|
4900
|
+
*
|
|
4901
|
+
* @example
|
|
4902
|
+
* ```typescript
|
|
4903
|
+
* // BlobMetadata[]
|
|
4904
|
+
* const blobs = await client.getAccountBlobs({
|
|
4905
|
+
* account: AccountAddress.fromString("0x1"),
|
|
4906
|
+
* });
|
|
4907
|
+
* ```
|
|
4908
|
+
*/
|
|
4909
|
+
getAccountBlobs(params) {
|
|
4910
|
+
const { where, ...rest } = params;
|
|
4911
|
+
return this.getBlobs({
|
|
4912
|
+
where: {
|
|
4913
|
+
...where,
|
|
4914
|
+
owner: { _eq: AccountAddress2.from(params.account).toString() }
|
|
4915
|
+
},
|
|
4916
|
+
pagination: rest.pagination,
|
|
4917
|
+
orderBy: rest.orderBy
|
|
4918
|
+
});
|
|
4997
4919
|
}
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
4920
|
+
/**
|
|
4921
|
+
* Retrieves blobs and their metadata from the blockchain.
|
|
4922
|
+
*
|
|
4923
|
+
* @param params.where (optional) - The where clause to filter the blobs by.
|
|
4924
|
+
* @param params.pagination (optional) - The pagination options.
|
|
4925
|
+
* @param params.orderBy (optional) - The order by clause to sort the blobs by.
|
|
4926
|
+
* @returns The blob metadata for all the blobs that match the where clause.
|
|
4927
|
+
*
|
|
4928
|
+
* @example
|
|
4929
|
+
* ```typescript
|
|
4930
|
+
* // BlobMetadata[]
|
|
4931
|
+
* const blobs = await client.getBlobs({
|
|
4932
|
+
* where: { owner: { _eq: AccountAddress.fromString("0x1").toString() } },
|
|
4933
|
+
* });
|
|
4934
|
+
* ```
|
|
4935
|
+
*/
|
|
4936
|
+
async getBlobs(params = {}) {
|
|
4937
|
+
const { limit, offset } = params.pagination ?? {};
|
|
4938
|
+
const { orderBy, where } = params;
|
|
4939
|
+
const currentMicros = String(Date.now() * 1e3);
|
|
4940
|
+
const defaultActiveFilter = {
|
|
4941
|
+
expires_at: { _gte: currentMicros },
|
|
4942
|
+
is_deleted: { _eq: "0" }
|
|
4943
|
+
};
|
|
4944
|
+
const finalWhere = where !== void 0 ? { ...defaultActiveFilter, ...where } : defaultActiveFilter;
|
|
4945
|
+
const { blobs } = await this.indexer.getBlobs({
|
|
4946
|
+
where: finalWhere,
|
|
4947
|
+
limit,
|
|
4948
|
+
offset,
|
|
4949
|
+
orderBy
|
|
4950
|
+
});
|
|
4951
|
+
return blobs.map(
|
|
4952
|
+
(blob) => ({
|
|
4953
|
+
owner: AccountAddress2.from(blob.owner),
|
|
4954
|
+
name: blob.blob_name,
|
|
4955
|
+
blobNameSuffix: getBlobNameSuffix(blob.blob_name),
|
|
4956
|
+
blobMerkleRoot: Hex3.fromHexInput(blob.blob_commitment).toUint8Array(),
|
|
4957
|
+
size: Number(blob.size),
|
|
4958
|
+
// TODO: Add encoding when supported in NCI
|
|
4959
|
+
encoding: {
|
|
4960
|
+
variant: "clay",
|
|
4961
|
+
...ERASURE_CODE_PARAMS.ClayCode_16Total_10Data_13Helper,
|
|
4962
|
+
...ERASURE_CODE_AND_CHUNK_MAPPING.ClayCode_16Total_10Data_13Helper
|
|
4963
|
+
},
|
|
4964
|
+
expirationMicros: Number(blob.expires_at),
|
|
4965
|
+
creationMicros: Number(blob.created_at),
|
|
4966
|
+
sliceAddress: AccountAddress2.from(blob.slice_address),
|
|
4967
|
+
isWritten: Boolean(Number(blob.is_written)),
|
|
4968
|
+
isDeleted: Boolean(Number(blob.is_deleted))
|
|
4969
|
+
})
|
|
4970
|
+
);
|
|
5015
4971
|
}
|
|
5016
|
-
)
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
4972
|
+
async getBlobActivities(params) {
|
|
4973
|
+
const { limit, offset } = params.pagination ?? {};
|
|
4974
|
+
const { orderBy, where } = params;
|
|
4975
|
+
const { blob_activities } = await this.indexer.getBlobActivities({
|
|
4976
|
+
where,
|
|
4977
|
+
limit,
|
|
4978
|
+
offset,
|
|
4979
|
+
orderBy
|
|
4980
|
+
});
|
|
4981
|
+
const activityTypeMapping = {
|
|
4982
|
+
[`${this.deployer.toStringLong()}::blob_metadata::BlobRegisteredEvent`]: "register_blob",
|
|
4983
|
+
[`${this.deployer.toStringLong()}::blob_metadata::BlobDeletedEvent`]: "delete_blob",
|
|
4984
|
+
[`${this.deployer.toStringLong()}::blob_metadata::BlobExpirationExtendedEvent`]: "extend_blob_expiration",
|
|
4985
|
+
[`${this.deployer.toStringLong()}::blob_metadata::BlobWrittenEvent`]: "write_blob"
|
|
4986
|
+
};
|
|
4987
|
+
return blob_activities.map(
|
|
4988
|
+
(activity) => ({
|
|
4989
|
+
blobName: activity.blob_name,
|
|
4990
|
+
accountAddress: AccountAddress2.from(
|
|
4991
|
+
activity.blob_name.substring(1, 65)
|
|
4992
|
+
),
|
|
4993
|
+
type: activityTypeMapping[activity.event_type] ?? "unknown",
|
|
4994
|
+
eventType: activity.event_type,
|
|
4995
|
+
eventIndex: Number(activity.event_index),
|
|
4996
|
+
transactionHash: activity.transaction_hash,
|
|
4997
|
+
// Using Number here in JS is technically not okay because txn version can be
|
|
4998
|
+
// as large as u64::MAX, but it should be fine for a long while.
|
|
4999
|
+
transactionVersion: Number(activity.transaction_version),
|
|
5000
|
+
timestamp: `${activity.timestamp}Z`
|
|
5001
|
+
})
|
|
5021
5002
|
);
|
|
5022
5003
|
}
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
}
|
|
5039
|
-
currentLeaves = nextLeaves;
|
|
5004
|
+
/**
|
|
5005
|
+
* Retrieves the total number of blobs from the blockchain.
|
|
5006
|
+
*
|
|
5007
|
+
* @param params.where (optional) - The where clause to filter the blobs by.
|
|
5008
|
+
* @returns The total number of blobs.
|
|
5009
|
+
*
|
|
5010
|
+
* @example
|
|
5011
|
+
* ```typescript
|
|
5012
|
+
* const count = await client.getBlobsCount();
|
|
5013
|
+
* ```
|
|
5014
|
+
*/
|
|
5015
|
+
async getBlobsCount(params) {
|
|
5016
|
+
const { where } = params;
|
|
5017
|
+
const { blobs_aggregate } = await this.indexer.getBlobsCount({ where });
|
|
5018
|
+
return blobs_aggregate?.aggregate?.count ?? 0;
|
|
5040
5019
|
}
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
);
|
|
5020
|
+
/**
|
|
5021
|
+
* Retrieves the total number of blob activities from the blockchain.
|
|
5022
|
+
*
|
|
5023
|
+
* @param params.where (optional) - The where clause to filter the blob activities by.
|
|
5024
|
+
* @returns The total number of blob activities.
|
|
5025
|
+
*
|
|
5026
|
+
* @example
|
|
5027
|
+
* ```typescript
|
|
5028
|
+
* const count = await client.getBlobActivitiesCount();
|
|
5029
|
+
* ```
|
|
5030
|
+
*/
|
|
5031
|
+
async getBlobActivitiesCount(params) {
|
|
5032
|
+
const { where } = params;
|
|
5033
|
+
const { blob_activities_aggregate } = await this.indexer.getBlobActivitiesCount({ where });
|
|
5034
|
+
return blob_activities_aggregate?.aggregate?.count ?? 0;
|
|
5055
5035
|
}
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5036
|
+
/**
|
|
5037
|
+
* Registers a blob on the blockchain by writing its merkle root and metadata.
|
|
5038
|
+
*
|
|
5039
|
+
* @param params.account - The account that is signing and paying for the transaction.
|
|
5040
|
+
* @param params.blobName - The name/path of the blob (e.g. "foo/bar.txt").
|
|
5041
|
+
* @param params.blobMerkleRoot - The merkle root of the blob commitments.
|
|
5042
|
+
* @param params.size - The size of the blob in bytes.
|
|
5043
|
+
* @param params.expirationMicros - The expiration time of the blob in microseconds.
|
|
5044
|
+
* @param params.options - Optional transaction building options.
|
|
5045
|
+
* @param params.options.chunksetSizeBytes - Custom chunkset size (defaults to DEFAULT_CHUNKSET_SIZE_BYTES).
|
|
5046
|
+
* @param params.options.build - Additional Aptos transaction building options.
|
|
5047
|
+
*
|
|
5048
|
+
* @returns An object containing the pending transaction.
|
|
5049
|
+
*
|
|
5050
|
+
* @example
|
|
5051
|
+
* ```typescript
|
|
5052
|
+
* const provider = await ClayErasureCodingProvider.create();
|
|
5053
|
+
* const blobCommitments = await generateCommitments(provider, data);
|
|
5054
|
+
*
|
|
5055
|
+
* const { transaction } = await client.registerBlob({
|
|
5056
|
+
* account: signer,
|
|
5057
|
+
* blobName: "foo/bar.txt",
|
|
5058
|
+
* blobMerkleRoot: blobCommitments.blob_merkle_root,
|
|
5059
|
+
* size: data.length,
|
|
5060
|
+
* expirationMicros: Date.now() * 1000 + 3600_000_000, // 1 hour from now in microseconds
|
|
5061
|
+
* });
|
|
5062
|
+
* ```
|
|
5063
|
+
*/
|
|
5064
|
+
async registerBlob(params) {
|
|
5065
|
+
const options = this.mergeOptions(params.options);
|
|
5066
|
+
this.validateUsdSponsorConfig(options.usdSponsor, options.submit);
|
|
5067
|
+
const chunksetSize = options.chunksetSizeBytes ?? DEFAULT_CHUNKSET_SIZE_BYTES;
|
|
5068
|
+
const buildArgs = {
|
|
5069
|
+
...options.build,
|
|
5070
|
+
data: _ShelbyBlobClient.createRegisterBlobPayload({
|
|
5071
|
+
deployer: this.deployer,
|
|
5072
|
+
account: params.account.accountAddress,
|
|
5073
|
+
blobName: params.blobName,
|
|
5074
|
+
blobSize: params.size,
|
|
5075
|
+
blobMerkleRoot: params.blobMerkleRoot,
|
|
5076
|
+
numChunksets: expectedTotalChunksets(params.size, chunksetSize),
|
|
5077
|
+
expirationMicros: params.expirationMicros,
|
|
5078
|
+
useSponsoredUsdVariant: options.usdSponsor !== void 0
|
|
5079
|
+
}),
|
|
5080
|
+
sender: params.account.accountAddress
|
|
5081
|
+
};
|
|
5082
|
+
const transaction = options.usdSponsor ? await this.aptos.transaction.build.multiAgent({
|
|
5083
|
+
...buildArgs,
|
|
5084
|
+
secondarySignerAddresses: [options.usdSponsor.feePayerAddress]
|
|
5085
|
+
}) : await this.aptos.transaction.build.simple(buildArgs);
|
|
5086
|
+
return {
|
|
5087
|
+
transaction: await this.aptos.signAndSubmitTransaction({
|
|
5088
|
+
signer: params.account,
|
|
5089
|
+
transaction,
|
|
5090
|
+
...options.submit
|
|
5091
|
+
})
|
|
5092
|
+
};
|
|
5063
5093
|
}
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
+
/**
|
|
5095
|
+
* Deletes a blob on the blockchain.
|
|
5096
|
+
*
|
|
5097
|
+
* @param params.account - The account that is signing and paying for the transaction.
|
|
5098
|
+
* @param params.blobName - The name/path of the blob (e.g. "foo/bar.txt").
|
|
5099
|
+
* @param params.options - Optional transaction building options.
|
|
5100
|
+
*
|
|
5101
|
+
* @returns An object containing the pending transaction.
|
|
5102
|
+
*
|
|
5103
|
+
* @example
|
|
5104
|
+
* ```typescript
|
|
5105
|
+
*
|
|
5106
|
+
* const { transaction } = await client.deleteBlob({
|
|
5107
|
+
* account: signer,
|
|
5108
|
+
* blobName: "foo/bar.txt",
|
|
5109
|
+
* });
|
|
5110
|
+
* ```
|
|
5111
|
+
*/
|
|
5112
|
+
async deleteBlob(params) {
|
|
5113
|
+
const transaction = await this.aptos.transaction.build.simple({
|
|
5114
|
+
...params.options,
|
|
5115
|
+
data: _ShelbyBlobClient.createDeleteBlobPayload({
|
|
5116
|
+
deployer: this.deployer,
|
|
5117
|
+
blobName: params.blobName
|
|
5118
|
+
}),
|
|
5119
|
+
sender: params.account.accountAddress
|
|
5120
|
+
});
|
|
5121
|
+
return {
|
|
5122
|
+
transaction: await this.aptos.signAndSubmitTransaction({
|
|
5123
|
+
signer: params.account,
|
|
5124
|
+
transaction
|
|
5125
|
+
})
|
|
5126
|
+
};
|
|
5094
5127
|
}
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5128
|
+
/**
|
|
5129
|
+
* Deletes multiple blobs on the blockchain in a single atomic transaction.
|
|
5130
|
+
*
|
|
5131
|
+
* **Note:** This function requires the `delete_multiple_blobs` entry function
|
|
5132
|
+
* which will be deployed to the smart contract on 2026-02-04. Using this
|
|
5133
|
+
* function before that date will result in a transaction failure.
|
|
5134
|
+
*
|
|
5135
|
+
* This operation is atomic: if any blob deletion fails (e.g., blob not found),
|
|
5136
|
+
* the entire transaction fails and no blobs are deleted.
|
|
5137
|
+
*
|
|
5138
|
+
* @param params.account - The account that is signing and paying for the transaction.
|
|
5139
|
+
* @param params.blobNames - Array of blob name suffixes without the account address prefix
|
|
5140
|
+
* (e.g. ["foo/bar.txt", "baz.txt"], NOT ["0x1/foo/bar.txt"]). The account address
|
|
5141
|
+
* prefix is automatically derived from the signer.
|
|
5142
|
+
* @param params.options - Optional transaction building options.
|
|
5143
|
+
*
|
|
5144
|
+
* @returns An object containing the pending transaction.
|
|
5145
|
+
*
|
|
5146
|
+
* @example
|
|
5147
|
+
* ```typescript
|
|
5148
|
+
*
|
|
5149
|
+
* const { transaction } = await client.deleteMultipleBlobs({
|
|
5150
|
+
* account: signer,
|
|
5151
|
+
* blobNames: ["foo/bar.txt", "baz.txt"],
|
|
5152
|
+
* });
|
|
5153
|
+
* ```
|
|
5154
|
+
*/
|
|
5155
|
+
async deleteMultipleBlobs(params) {
|
|
5156
|
+
const transaction = await this.aptos.transaction.build.simple({
|
|
5157
|
+
...params.options,
|
|
5158
|
+
data: _ShelbyBlobClient.createDeleteMultipleBlobsPayload({
|
|
5159
|
+
deployer: this.deployer,
|
|
5160
|
+
blobNames: params.blobNames
|
|
5161
|
+
}),
|
|
5162
|
+
sender: params.account.accountAddress
|
|
5163
|
+
});
|
|
5164
|
+
return {
|
|
5165
|
+
transaction: await this.aptos.signAndSubmitTransaction({
|
|
5166
|
+
signer: params.account,
|
|
5167
|
+
transaction
|
|
5168
|
+
})
|
|
5169
|
+
};
|
|
5107
5170
|
}
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5171
|
+
/**
|
|
5172
|
+
* Acks the blob chunksets on-chain. If each chunkset meets the necessary threshold, the entire blob will be marked as written.
|
|
5173
|
+
*
|
|
5174
|
+
* @param params.account - The account that is signing the transaction.
|
|
5175
|
+
* @param params.blobOwner - The account that owns the blob.
|
|
5176
|
+
* @param params.blobName - The name of the blob (e.g. "foo/bar")
|
|
5177
|
+
* @param params.creationMicros - The creation time of the blob in microseconds.
|
|
5178
|
+
* @param params.chunksetIdx - The index of the chunkset being acknowledged.
|
|
5179
|
+
* @param params.storageProviderChunksetAcks - The signatures
|
|
5180
|
+
* @param params.options - Additional options for transaction building and encoding.
|
|
5181
|
+
*
|
|
5182
|
+
* @returns The blob commitments and the pending transaction.
|
|
5183
|
+
*
|
|
5184
|
+
* @example
|
|
5185
|
+
* ```typescript
|
|
5186
|
+
* const { transaction } = await client.addChunksetAcknowledgements({
|
|
5187
|
+
* account: signer,
|
|
5188
|
+
* blobOwner: owner,
|
|
5189
|
+
* blobName: "foo/bar.txt",
|
|
5190
|
+
* creationMicros, // Taken from the blob metadata at registration time.
|
|
5191
|
+
* chunksetIdx,
|
|
5192
|
+
* storageProviderAcks: An array of StorageProviderAck types, each having the slot index and signature from the SP.
|
|
5193
|
+
* });
|
|
5194
|
+
* ```
|
|
5195
|
+
*/
|
|
5196
|
+
async addChunksetAcknowledgements(params) {
|
|
5197
|
+
const transaction = await this.aptos.transaction.build.simple({
|
|
5198
|
+
...params.options?.build,
|
|
5199
|
+
data: _ShelbyBlobClient.createChunksetAcknowledgementsPayload({
|
|
5200
|
+
blobOwner: params.blobOwner,
|
|
5201
|
+
blobName: params.blobName,
|
|
5202
|
+
creationMicros: params.creationMicros,
|
|
5203
|
+
chunksetIdx: params.chunksetIdx,
|
|
5204
|
+
storageProviderAcks: params.storageProviderAcks
|
|
5205
|
+
}),
|
|
5206
|
+
sender: params.account.accountAddress
|
|
5207
|
+
});
|
|
5208
|
+
return {
|
|
5209
|
+
transaction: await this.aptos.signAndSubmitTransaction({
|
|
5210
|
+
signer: params.account,
|
|
5211
|
+
transaction
|
|
5212
|
+
})
|
|
5213
|
+
};
|
|
5120
5214
|
}
|
|
5121
|
-
return chunkset;
|
|
5122
|
-
}
|
|
5123
|
-
|
|
5124
|
-
// ../../packages/sdk/dist/chunk-JWVMZ2Y7.mjs
|
|
5125
|
-
import {
|
|
5126
|
-
AccountAddress as AccountAddress5,
|
|
5127
|
-
Aptos as Aptos2,
|
|
5128
|
-
AptosConfig as AptosConfig2,
|
|
5129
|
-
Hex as Hex5,
|
|
5130
|
-
MoveVector,
|
|
5131
|
-
U32
|
|
5132
|
-
} from "@aptos-labs/ts-sdk";
|
|
5133
|
-
var ShelbyBlobClient = class _ShelbyBlobClient {
|
|
5134
|
-
aptos;
|
|
5135
|
-
deployer;
|
|
5136
|
-
indexer;
|
|
5137
5215
|
/**
|
|
5138
|
-
*
|
|
5139
|
-
* includes functions for registering blob commitments and retrieving blob metadata.
|
|
5216
|
+
* Registers multiple blobs on the blockchain by writing their merkle roots and metadata.
|
|
5140
5217
|
*
|
|
5141
|
-
* @param
|
|
5142
|
-
* @param
|
|
5218
|
+
* @param params.account - The account that is signing and paying for the transaction.
|
|
5219
|
+
* @param params.expirationMicros - The expiration time of the blobs in microseconds.
|
|
5220
|
+
* @param params.blobs - The blobs to register.
|
|
5221
|
+
* @param params.blobs.blobName - The name/path of the blob (e.g. "foo/bar.txt").
|
|
5222
|
+
* @param params.blobs.blobSize - The size of the blob in bytes.
|
|
5223
|
+
* @param params.blobs.blobMerkleRoot - The merkle root of the blob commitments as a hex string.
|
|
5224
|
+
* @param params.options - Optional transaction building options.
|
|
5225
|
+
* @param params.options.chunksetSizeBytes - Custom chunkset size (defaults to DEFAULT_CHUNKSET_SIZE_BYTES).
|
|
5226
|
+
* @param params.options.build - Additional Aptos transaction building options.
|
|
5227
|
+
*
|
|
5228
|
+
* @returns An object containing the pending transaction.
|
|
5143
5229
|
*
|
|
5144
5230
|
* @example
|
|
5145
5231
|
* ```typescript
|
|
5146
|
-
* const
|
|
5147
|
-
*
|
|
5148
|
-
*
|
|
5149
|
-
*
|
|
5150
|
-
*
|
|
5232
|
+
* const provider = await ClayErasureCodingProvider.create();
|
|
5233
|
+
* const blobCommitments = await generateCommitments(provider, data);
|
|
5234
|
+
*
|
|
5235
|
+
* const { transaction } = await client.batchRegisterBlobs({
|
|
5236
|
+
* account: signer,
|
|
5237
|
+
* expirationMicros: Date.now() * 1000 + 3600_000_000, // 1 hour from now in microseconds
|
|
5238
|
+
* blobs: [
|
|
5239
|
+
* {
|
|
5240
|
+
* blobName: "foo/bar.txt",
|
|
5241
|
+
* blobSize: data.length,
|
|
5242
|
+
* blobMerkleRoot: blobCommitments.blob_merkle_root,
|
|
5151
5243
|
* },
|
|
5152
|
-
*
|
|
5244
|
+
* ],
|
|
5153
5245
|
* });
|
|
5154
5246
|
* ```
|
|
5155
5247
|
*/
|
|
5156
|
-
|
|
5157
|
-
const
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5248
|
+
async batchRegisterBlobs(params) {
|
|
5249
|
+
const options = this.mergeOptions(params.options);
|
|
5250
|
+
this.validateUsdSponsorConfig(options.usdSponsor, options.submit);
|
|
5251
|
+
const chunksetSize = options.chunksetSizeBytes ?? DEFAULT_CHUNKSET_SIZE_BYTES;
|
|
5252
|
+
const buildArgs = {
|
|
5253
|
+
...options.build,
|
|
5254
|
+
sender: params.account.accountAddress,
|
|
5255
|
+
data: _ShelbyBlobClient.createBatchRegisterBlobsPayload({
|
|
5256
|
+
deployer: this.deployer,
|
|
5257
|
+
account: params.account.accountAddress,
|
|
5258
|
+
expirationMicros: params.expirationMicros,
|
|
5259
|
+
blobs: params.blobs.map((blob) => ({
|
|
5260
|
+
blobName: blob.blobName,
|
|
5261
|
+
blobSize: blob.blobSize,
|
|
5262
|
+
blobMerkleRoot: blob.blobMerkleRoot,
|
|
5263
|
+
numChunksets: expectedTotalChunksets(blob.blobSize, chunksetSize)
|
|
5264
|
+
})),
|
|
5265
|
+
useSponsoredUsdVariant: options.usdSponsor !== void 0
|
|
5266
|
+
})
|
|
5267
|
+
};
|
|
5268
|
+
const transaction = options.usdSponsor ? await this.aptos.transaction.build.multiAgent({
|
|
5269
|
+
...buildArgs,
|
|
5270
|
+
secondarySignerAddresses: [options.usdSponsor.feePayerAddress]
|
|
5271
|
+
}) : await this.aptos.transaction.build.simple(buildArgs);
|
|
5272
|
+
return {
|
|
5273
|
+
transaction: await this.aptos.signAndSubmitTransaction({
|
|
5274
|
+
signer: params.account,
|
|
5275
|
+
transaction,
|
|
5276
|
+
...options.submit
|
|
5277
|
+
})
|
|
5278
|
+
};
|
|
5279
|
+
}
|
|
5280
|
+
/**
|
|
5281
|
+
* Creates a transaction payload to register a blob on the blockchain.
|
|
5282
|
+
* This is a static helper method for constructing the Move function call payload.
|
|
5283
|
+
*
|
|
5284
|
+
* @param params.deployer - Optional deployer account address. Defaults to SHELBY_DEPLOYER.
|
|
5285
|
+
* @param params.account - The account that will own the blob.
|
|
5286
|
+
* @param params.blobName - The name/path of the blob (e.g. "foo/bar.txt").
|
|
5287
|
+
* @param params.blobSize - The size of the blob in bytes.
|
|
5288
|
+
* @param params.blobMerkleRoot - The merkle root of the blob commitments as a hex string.
|
|
5289
|
+
* @param params.expirationMicros - The expiration time of the blob in microseconds.
|
|
5290
|
+
* @param params.numChunksets - The total number of chunksets in the blob.
|
|
5291
|
+
*
|
|
5292
|
+
* @returns An Aptos transaction payload data object for the register_blob Move function.
|
|
5293
|
+
*
|
|
5294
|
+
* @see https://github.com/shelby/shelby/blob/e08e84742cf2b80ad8bb7227deb3013398076d53/move/shelby_contract/sources/global_metadata.move#L357
|
|
5295
|
+
*/
|
|
5296
|
+
static createRegisterBlobPayload(params) {
|
|
5297
|
+
const functionName = params.useSponsoredUsdVariant ? "register_blob_with_sponsor" : "register_blob";
|
|
5298
|
+
return {
|
|
5299
|
+
function: `${(params.deployer ?? SHELBY_DEPLOYER).toString()}::blob_metadata::${functionName}`,
|
|
5300
|
+
functionArguments: [
|
|
5301
|
+
params.blobName,
|
|
5302
|
+
params.expirationMicros,
|
|
5303
|
+
Hex3.fromHexString(params.blobMerkleRoot).toUint8Array(),
|
|
5304
|
+
params.numChunksets,
|
|
5305
|
+
params.blobSize,
|
|
5306
|
+
// TODO
|
|
5307
|
+
0,
|
|
5308
|
+
// payment tier
|
|
5309
|
+
0
|
|
5310
|
+
// encoding
|
|
5311
|
+
]
|
|
5312
|
+
};
|
|
5313
|
+
}
|
|
5314
|
+
/**
|
|
5315
|
+
* Creates a transaction payload to register multiple blobs on the blockchain.
|
|
5316
|
+
* This is a static helper method for constructing the Move function call payload.
|
|
5317
|
+
*
|
|
5318
|
+
* @param params.deployer - Optional deployer account address. Defaults to SHELBY_DEPLOYER.
|
|
5319
|
+
* @param params.account - The account that will own the blobs.
|
|
5320
|
+
* @param params.expirationMicros - The expiration time of the blobs in microseconds.
|
|
5321
|
+
* @param params.blobs - The blobs to register.
|
|
5322
|
+
* @param params.blobs.blobName - The name/path of the blob (e.g. "foo/bar.txt").
|
|
5323
|
+
* @param params.blobs.blobSize - The size of the blob in bytes.
|
|
5324
|
+
* @param params.blobs.blobMerkleRoot - The merkle root of the blob commitments as a hex string.
|
|
5325
|
+
* @param params.blobs.numChunksets - The total number of chunksets in the blob.
|
|
5326
|
+
*
|
|
5327
|
+
* @returns An Aptos transaction payload data object for the register_multiple_blobs Move function.
|
|
5328
|
+
*
|
|
5329
|
+
* @see https://github.com/shelby/shelby/blob/e08e84742cf2b80ad8bb7227deb3013398076d53/move/shelby_contract/sources/global_metadata.move#L357
|
|
5330
|
+
*/
|
|
5331
|
+
static createBatchRegisterBlobsPayload(params) {
|
|
5332
|
+
const functionName = params.useSponsoredUsdVariant ? "register_multiple_blobs_with_sponsor" : "register_multiple_blobs";
|
|
5333
|
+
const blobNames = [];
|
|
5334
|
+
const blobMerkleRoots = [];
|
|
5335
|
+
const blobNumChunksets = [];
|
|
5336
|
+
const blobSizes = [];
|
|
5337
|
+
params.blobs.forEach((blob) => {
|
|
5338
|
+
blobNames.push(blob.blobName);
|
|
5339
|
+
blobMerkleRoots.push(
|
|
5340
|
+
Hex3.fromHexString(blob.blobMerkleRoot).toUint8Array()
|
|
5341
|
+
);
|
|
5342
|
+
blobNumChunksets.push(blob.numChunksets);
|
|
5343
|
+
blobSizes.push(blob.blobSize);
|
|
5165
5344
|
});
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5345
|
+
return {
|
|
5346
|
+
function: `${(params.deployer ?? SHELBY_DEPLOYER).toString()}::blob_metadata::${functionName}`,
|
|
5347
|
+
functionArguments: [
|
|
5348
|
+
blobNames,
|
|
5349
|
+
params.expirationMicros,
|
|
5350
|
+
blobMerkleRoots,
|
|
5351
|
+
blobNumChunksets,
|
|
5352
|
+
blobSizes,
|
|
5353
|
+
// TODO
|
|
5354
|
+
0,
|
|
5355
|
+
0
|
|
5356
|
+
]
|
|
5357
|
+
};
|
|
5169
5358
|
}
|
|
5170
5359
|
/**
|
|
5171
|
-
*
|
|
5172
|
-
*
|
|
5360
|
+
* Creates a transaction payload to delete a blob on the blockchain.
|
|
5361
|
+
* This is a static helper method for constructing the Move function call payload.
|
|
5173
5362
|
*
|
|
5174
|
-
* @param params.
|
|
5175
|
-
* @param params.
|
|
5176
|
-
* @returns The blob metadata.
|
|
5363
|
+
* @param params.deployer - Optional deployer account address. Defaults to SHELBY_DEPLOYER.
|
|
5364
|
+
* @param params.blobName - The blob name (e.g. "bar.txt", without the account address prefix).
|
|
5177
5365
|
*
|
|
5178
|
-
* @
|
|
5179
|
-
*
|
|
5180
|
-
*
|
|
5181
|
-
* account: AccountAddress.fromString("0x1"),
|
|
5182
|
-
* name: "foo/bar.txt",
|
|
5183
|
-
* });
|
|
5184
|
-
* ```
|
|
5366
|
+
* @returns An Aptos transaction payload data object for the delete_blob Move function.
|
|
5367
|
+
*
|
|
5368
|
+
* @see https://github.com/shelby/shelby/blob/64e9d7b4f0005e586faeb1e4085c79159234b6b6/move/shelby_contract/sources/global_metadata.move#L616
|
|
5185
5369
|
*/
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
functionArguments: [
|
|
5192
|
-
createBlobKey({
|
|
5193
|
-
account: params.account,
|
|
5194
|
-
blobName: params.name
|
|
5195
|
-
})
|
|
5196
|
-
]
|
|
5197
|
-
}
|
|
5198
|
-
});
|
|
5199
|
-
if (!rawMetadata?.[0]?.vec?.[0]) {
|
|
5200
|
-
return void 0;
|
|
5201
|
-
}
|
|
5202
|
-
const metadata = rawMetadata[0].vec[0];
|
|
5203
|
-
let encoding;
|
|
5204
|
-
if (metadata.encoding.__variant__ === "ClayCode_16Total_10Data_13Helper") {
|
|
5205
|
-
encoding = {
|
|
5206
|
-
variant: "clay",
|
|
5207
|
-
...ERASURE_CODE_PARAMS[metadata.encoding.__variant__],
|
|
5208
|
-
...ERASURE_CODE_AND_CHUNK_MAPPING[metadata.encoding.__variant__]
|
|
5209
|
-
};
|
|
5210
|
-
} else {
|
|
5211
|
-
throw new Error(
|
|
5212
|
-
"Could not parse encoding from Shelby Smart Contract, this SDK is out of date."
|
|
5213
|
-
);
|
|
5214
|
-
}
|
|
5215
|
-
return {
|
|
5216
|
-
blobMerkleRoot: Hex5.fromHexInput(
|
|
5217
|
-
metadata.blob_commitment
|
|
5218
|
-
).toUint8Array(),
|
|
5219
|
-
owner: AccountAddress5.fromString(metadata.owner),
|
|
5220
|
-
name: params.name,
|
|
5221
|
-
blobNameSuffix: getBlobNameSuffix(params.name),
|
|
5222
|
-
size: Number(metadata.blob_size),
|
|
5223
|
-
encoding,
|
|
5224
|
-
expirationMicros: Number(metadata.expiration_micros),
|
|
5225
|
-
creationMicros: Number(metadata.creation_micros),
|
|
5226
|
-
sliceAddress: AccountAddress5.fromString(metadata.slice.inner),
|
|
5227
|
-
isWritten: metadata.is_written
|
|
5228
|
-
};
|
|
5229
|
-
} catch (error) {
|
|
5230
|
-
if (error instanceof Error && // Depending on the network, the error message may show up differently.
|
|
5231
|
-
(error.message?.includes("sub_status: Some(404)") || error.message?.includes("EBLOB_NOT_FOUND"))) {
|
|
5232
|
-
return void 0;
|
|
5233
|
-
}
|
|
5234
|
-
throw error;
|
|
5235
|
-
}
|
|
5370
|
+
static createDeleteBlobPayload(params) {
|
|
5371
|
+
return {
|
|
5372
|
+
function: `${(params.deployer ?? SHELBY_DEPLOYER).toString()}::blob_metadata::delete_blob`,
|
|
5373
|
+
functionArguments: [params.blobName]
|
|
5374
|
+
};
|
|
5236
5375
|
}
|
|
5237
5376
|
/**
|
|
5238
|
-
*
|
|
5239
|
-
*
|
|
5377
|
+
* Creates a transaction payload to delete multiple blobs on the blockchain.
|
|
5378
|
+
* This is a static helper method for constructing the Move function call payload.
|
|
5240
5379
|
*
|
|
5241
|
-
*
|
|
5242
|
-
*
|
|
5243
|
-
*
|
|
5244
|
-
* @returns The blob metadata for all the blobs for the account.
|
|
5380
|
+
* **Note:** This function requires the `delete_multiple_blobs` entry function
|
|
5381
|
+
* which will be deployed to the smart contract on 2026-02-04. Using this
|
|
5382
|
+
* function before that date will result in a transaction failure.
|
|
5245
5383
|
*
|
|
5246
|
-
*
|
|
5247
|
-
*
|
|
5248
|
-
* // BlobMetadata[]
|
|
5249
|
-
* const blobs = await client.getAccountBlobs({
|
|
5250
|
-
* account: AccountAddress.fromString("0x1"),
|
|
5251
|
-
* });
|
|
5252
|
-
* ```
|
|
5253
|
-
*/
|
|
5254
|
-
getAccountBlobs(params) {
|
|
5255
|
-
const { where, ...rest } = params;
|
|
5256
|
-
return this.getBlobs({
|
|
5257
|
-
where: {
|
|
5258
|
-
...where ?? {},
|
|
5259
|
-
owner: { _eq: AccountAddress5.from(params.account).toString() }
|
|
5260
|
-
},
|
|
5261
|
-
pagination: rest.pagination,
|
|
5262
|
-
orderBy: rest.orderBy
|
|
5263
|
-
});
|
|
5264
|
-
}
|
|
5265
|
-
/**
|
|
5266
|
-
* Retrieves blobs and their metadata from the blockchain.
|
|
5384
|
+
* This operation is atomic: if any blob deletion fails (e.g., blob not found),
|
|
5385
|
+
* the entire transaction fails and no blobs are deleted.
|
|
5267
5386
|
*
|
|
5268
|
-
* @param params.
|
|
5269
|
-
* @param params.
|
|
5270
|
-
*
|
|
5271
|
-
*
|
|
5387
|
+
* @param params.deployer - Optional deployer account address. Defaults to SHELBY_DEPLOYER.
|
|
5388
|
+
* @param params.blobNames - Array of blob name suffixes without the account address prefix
|
|
5389
|
+
* (e.g. ["foo/bar.txt", "baz.txt"], NOT ["0x1/foo/bar.txt"]). The account address
|
|
5390
|
+
* prefix is automatically derived from the transaction sender.
|
|
5272
5391
|
*
|
|
5273
|
-
* @
|
|
5274
|
-
*
|
|
5275
|
-
*
|
|
5276
|
-
* const blobs = await client.getBlobs({
|
|
5277
|
-
* where: { owner: { _eq: AccountAddress.fromString("0x1").toString() } },
|
|
5278
|
-
* });
|
|
5279
|
-
* ```
|
|
5392
|
+
* @returns An Aptos transaction payload data object for the delete_multiple_blobs Move function.
|
|
5393
|
+
*
|
|
5394
|
+
* @see https://github.com/shelby/shelby/blob/main/move/shelby_contract/sources/blob_metadata.move
|
|
5280
5395
|
*/
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
const defaultActiveFilter = {
|
|
5286
|
-
expires_at: { _gte: currentMicros },
|
|
5287
|
-
is_deleted: { _eq: "0" }
|
|
5396
|
+
static createDeleteMultipleBlobsPayload(params) {
|
|
5397
|
+
return {
|
|
5398
|
+
function: `${(params.deployer ?? SHELBY_DEPLOYER).toString()}::blob_metadata::delete_multiple_blobs`,
|
|
5399
|
+
functionArguments: [params.blobNames]
|
|
5288
5400
|
};
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5401
|
+
}
|
|
5402
|
+
static createChunksetAcknowledgementsPayload(params) {
|
|
5403
|
+
const ackBitMask = params.storageProviderAcks.reduce(
|
|
5404
|
+
(acc, ack) => acc | 1 << ack.slot,
|
|
5405
|
+
0
|
|
5406
|
+
);
|
|
5407
|
+
return {
|
|
5408
|
+
function: `${SHELBY_DEPLOYER}::blob_metadata::add_chunkset_acknowledgements`,
|
|
5409
|
+
functionArguments: [
|
|
5410
|
+
createBlobKey({
|
|
5411
|
+
account: params.blobOwner,
|
|
5412
|
+
blobName: params.blobName
|
|
5413
|
+
}),
|
|
5414
|
+
params.chunksetIdx,
|
|
5415
|
+
params.creationMicros,
|
|
5416
|
+
new U32(Number(ackBitMask)),
|
|
5417
|
+
params.storageProviderAcks.map((ack) => ack.signature)
|
|
5418
|
+
]
|
|
5419
|
+
};
|
|
5420
|
+
}
|
|
5421
|
+
};
|
|
5422
|
+
|
|
5423
|
+
// ../../packages/sdk/dist/chunk-UCDAABAS.mjs
|
|
5424
|
+
import {
|
|
5425
|
+
createDecoder,
|
|
5426
|
+
createEncoder
|
|
5427
|
+
} from "@shelby-protocol/clay-codes";
|
|
5428
|
+
function getTotalChunks(config) {
|
|
5429
|
+
return config.erasure_n;
|
|
5430
|
+
}
|
|
5431
|
+
var ClayErasureCodingProvider = class _ClayErasureCodingProvider {
|
|
5432
|
+
config;
|
|
5433
|
+
encoderCache;
|
|
5434
|
+
decoderCache;
|
|
5435
|
+
lastFunction;
|
|
5436
|
+
constructor(config) {
|
|
5437
|
+
this.config = config;
|
|
5438
|
+
this.lastFunction = "none";
|
|
5439
|
+
}
|
|
5440
|
+
/**
|
|
5441
|
+
* Static factory method to create an initialized ClayErasureCodingProvider
|
|
5442
|
+
*/
|
|
5443
|
+
static async create(options) {
|
|
5444
|
+
const config = buildClayConfig({
|
|
5445
|
+
erasure_n: options?.erasure_n ?? DEFAULT_ERASURE_N,
|
|
5446
|
+
erasure_k: options?.erasure_k ?? DEFAULT_ERASURE_K,
|
|
5447
|
+
erasure_d: options?.erasure_d ?? DEFAULT_ERASURE_D,
|
|
5448
|
+
chunkSizeBytes: options?.chunkSizeBytes ?? DEFAULT_CHUNK_SIZE_BYTES
|
|
5295
5449
|
});
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
sliceAddress: AccountAddress5.from(blob.slice_address),
|
|
5312
|
-
isWritten: Boolean(Number(blob.is_written))
|
|
5450
|
+
const provider = new _ClayErasureCodingProvider(config);
|
|
5451
|
+
[provider.encoderCache, provider.decoderCache] = await Promise.all([
|
|
5452
|
+
createEncoder({
|
|
5453
|
+
n: getTotalChunks(config),
|
|
5454
|
+
k: config.erasure_k,
|
|
5455
|
+
d: config.erasure_d,
|
|
5456
|
+
chunkSizeBytes: config.chunkSizeBytes
|
|
5457
|
+
}),
|
|
5458
|
+
createDecoder({
|
|
5459
|
+
n: getTotalChunks(config),
|
|
5460
|
+
k: config.erasure_k,
|
|
5461
|
+
d: config.erasure_d,
|
|
5462
|
+
chunkSizeBytes: config.chunkSizeBytes,
|
|
5463
|
+
erasedChunksMask: 0
|
|
5464
|
+
// No chunks erased initially; will be reconfigured on decode
|
|
5313
5465
|
})
|
|
5314
|
-
);
|
|
5466
|
+
]);
|
|
5467
|
+
return provider;
|
|
5468
|
+
}
|
|
5469
|
+
encode(data) {
|
|
5470
|
+
const { erasure_k, chunkSizeBytes } = this.config;
|
|
5471
|
+
if (!this.encoderCache) {
|
|
5472
|
+
throw new Error("Encoder cache is missing");
|
|
5473
|
+
}
|
|
5474
|
+
const systematicCapacity = erasure_k * chunkSizeBytes;
|
|
5475
|
+
if (data.byteLength > systematicCapacity) {
|
|
5476
|
+
throw new Error(
|
|
5477
|
+
`Data size ${data.byteLength} bytes exceeds systematic capacity ${systematicCapacity} bytes (erasure_k=${erasure_k} * chunkSizeBytes=${chunkSizeBytes}).`
|
|
5478
|
+
);
|
|
5479
|
+
}
|
|
5480
|
+
if (this.requiresPadding(data.length)) {
|
|
5481
|
+
throw new Error(
|
|
5482
|
+
`Data size ${data.length} bytes does not match systematic capacity ${systematicCapacity} bytes (erasure_k=${erasure_k} * chunkSizeBytes=${chunkSizeBytes}). Provide pre-padded data before encoding.`
|
|
5483
|
+
);
|
|
5484
|
+
}
|
|
5485
|
+
this.lastFunction = "encoded";
|
|
5486
|
+
return this.encoderCache.erasureCode(data);
|
|
5487
|
+
}
|
|
5488
|
+
decode(available, config) {
|
|
5489
|
+
if (!this.decoderCache) {
|
|
5490
|
+
throw new Error("Decoder cache is missing");
|
|
5491
|
+
}
|
|
5492
|
+
const { erasure_k, chunkSizeBytes } = this.config;
|
|
5493
|
+
if (available.length < erasure_k) {
|
|
5494
|
+
throw new Error(
|
|
5495
|
+
`Insufficient available chunks: need at least ${erasure_k}, received ${available.length}.`
|
|
5496
|
+
);
|
|
5497
|
+
}
|
|
5498
|
+
for (let i = 0; i < available.length; i++) {
|
|
5499
|
+
const chunk = available[i];
|
|
5500
|
+
if (chunk.length !== chunkSizeBytes) {
|
|
5501
|
+
throw new Error(
|
|
5502
|
+
`Chunk ${i} size ${chunk.length} bytes does not match expected chunkSizeBytes ${chunkSizeBytes}.`
|
|
5503
|
+
);
|
|
5504
|
+
}
|
|
5505
|
+
}
|
|
5506
|
+
this.lastFunction = "decoded";
|
|
5507
|
+
return this.decoderCache.decode(available, config);
|
|
5315
5508
|
}
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
orderBy
|
|
5324
|
-
});
|
|
5325
|
-
const activityTypeMapping = {
|
|
5326
|
-
[`${this.deployer.toStringLong()}::blob_metadata::BlobRegisteredEvent`]: "register_blob",
|
|
5327
|
-
[`${this.deployer.toStringLong()}::blob_metadata::BlobDeletedEvent`]: "delete_blob",
|
|
5328
|
-
[`${this.deployer.toStringLong()}::blob_metadata::BlobExpirationExtendedEvent`]: "extend_blob_expiration",
|
|
5329
|
-
[`${this.deployer.toStringLong()}::blob_metadata::BlobWrittenEvent`]: "write_blob"
|
|
5330
|
-
};
|
|
5331
|
-
return blob_activities.map(
|
|
5332
|
-
(activity) => ({
|
|
5333
|
-
blobName: activity.blob_name,
|
|
5334
|
-
accountAddress: AccountAddress5.from(
|
|
5335
|
-
activity.blob_name.substring(1, 65)
|
|
5336
|
-
),
|
|
5337
|
-
type: activityTypeMapping[activity.event_type] ?? "unknown",
|
|
5338
|
-
eventType: activity.event_type,
|
|
5339
|
-
eventIndex: activity.event_index,
|
|
5340
|
-
transactionHash: activity.transaction_hash,
|
|
5341
|
-
transactionVersion: activity.transaction_version,
|
|
5342
|
-
timestamp: activity.timestamp
|
|
5343
|
-
})
|
|
5509
|
+
getChunkMerkleRoots() {
|
|
5510
|
+
if (this.decoderCache && this.lastFunction === "decoded")
|
|
5511
|
+
return this.decoderCache.getChunkMerkleRoots();
|
|
5512
|
+
if (this.encoderCache && this.lastFunction === "encoded")
|
|
5513
|
+
return this.encoderCache.getChunkMerkleRoots();
|
|
5514
|
+
throw new Error(
|
|
5515
|
+
"You must call encode or decode before calling getChunkMerkleRoots"
|
|
5344
5516
|
);
|
|
5345
5517
|
}
|
|
5346
5518
|
/**
|
|
5347
|
-
*
|
|
5519
|
+
* Determines if data can be erasure coded as-is or requires padding.
|
|
5348
5520
|
*
|
|
5349
|
-
*
|
|
5350
|
-
*
|
|
5521
|
+
* Data can be erasure coded without padding if its size exactly matches
|
|
5522
|
+
* the total systematic data capacity (k * chunkSizeBytes).
|
|
5351
5523
|
*
|
|
5352
|
-
* @
|
|
5353
|
-
*
|
|
5354
|
-
* const count = await client.getBlobsCount();
|
|
5355
|
-
* ```
|
|
5524
|
+
* @param dataSize - Size of the data in bytes
|
|
5525
|
+
* @returns true if data needs padding, false if it can be coded as-is
|
|
5356
5526
|
*/
|
|
5357
|
-
|
|
5358
|
-
const {
|
|
5359
|
-
const
|
|
5360
|
-
return
|
|
5527
|
+
requiresPadding(dataSize) {
|
|
5528
|
+
const { erasure_k, chunkSizeBytes } = this.config;
|
|
5529
|
+
const systematicCapacity = erasure_k * chunkSizeBytes;
|
|
5530
|
+
return dataSize !== systematicCapacity;
|
|
5361
5531
|
}
|
|
5532
|
+
};
|
|
5533
|
+
function buildClayConfig(input) {
|
|
5534
|
+
const { erasure_n, erasure_k, erasure_d, chunkSizeBytes } = input;
|
|
5535
|
+
if (erasure_n <= 0)
|
|
5536
|
+
throw new Error("erasure_n (total number of chunks) must be > 0");
|
|
5537
|
+
if (erasure_k <= 0)
|
|
5538
|
+
throw new Error("erasure_k (number of data chunks) must be > 0");
|
|
5539
|
+
if (erasure_k >= erasure_n)
|
|
5540
|
+
throw new Error(
|
|
5541
|
+
`erasure_k (${erasure_k}) must be < erasure_n (${erasure_n})`
|
|
5542
|
+
);
|
|
5543
|
+
if (erasure_d <= erasure_k)
|
|
5544
|
+
throw new Error(
|
|
5545
|
+
`erasure_d (${erasure_d}) must be > erasure_k (${erasure_k})`
|
|
5546
|
+
);
|
|
5547
|
+
if (erasure_d >= erasure_n)
|
|
5548
|
+
throw new Error(
|
|
5549
|
+
`erasure_d (${erasure_d}) must be < erasure_n (${erasure_n})`
|
|
5550
|
+
);
|
|
5551
|
+
if (chunkSizeBytes <= 0) throw new Error("chunkSizeBytes must be > 0");
|
|
5552
|
+
return {
|
|
5553
|
+
erasure_n,
|
|
5554
|
+
erasure_k,
|
|
5555
|
+
erasure_d,
|
|
5556
|
+
chunkSizeBytes
|
|
5557
|
+
};
|
|
5558
|
+
}
|
|
5559
|
+
|
|
5560
|
+
// ../../packages/sdk/dist/chunk-4MG4XGY4.mjs
|
|
5561
|
+
import {
|
|
5562
|
+
AccountAuthenticator,
|
|
5563
|
+
Deserializer,
|
|
5564
|
+
Hex as Hex4,
|
|
5565
|
+
MultiAgentTransaction,
|
|
5566
|
+
Serializer
|
|
5567
|
+
} from "@aptos-labs/ts-sdk";
|
|
5568
|
+
var StaleChannelStateError = class _StaleChannelStateError extends Error {
|
|
5362
5569
|
/**
|
|
5363
|
-
*
|
|
5364
|
-
*
|
|
5365
|
-
* @param params.where (optional) - The where clause to filter the blob activities by.
|
|
5366
|
-
* @returns The total number of blob activities.
|
|
5367
|
-
*
|
|
5368
|
-
* @example
|
|
5369
|
-
* ```typescript
|
|
5370
|
-
* const count = await client.getBlobActivitiesCount();
|
|
5371
|
-
* ```
|
|
5570
|
+
* The last valid micropayment stored by the server.
|
|
5571
|
+
* Clients can use this to reset their local channel state.
|
|
5372
5572
|
*/
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5573
|
+
storedMicropayment;
|
|
5574
|
+
constructor(storedMicropayment, message) {
|
|
5575
|
+
super(
|
|
5576
|
+
message ?? "Client has stale channel state. Use the returned micropayment to reset local state."
|
|
5577
|
+
);
|
|
5578
|
+
this.name = "StaleChannelStateError";
|
|
5579
|
+
this.storedMicropayment = storedMicropayment;
|
|
5377
5580
|
}
|
|
5378
5581
|
/**
|
|
5379
|
-
*
|
|
5380
|
-
*
|
|
5381
|
-
* @param params.account - The account that is signing and paying for the transaction.
|
|
5382
|
-
* @param params.blobName - The name/path of the blob (e.g. "foo/bar.txt").
|
|
5383
|
-
* @param params.blobMerkleRoot - The merkle root of the blob commitments.
|
|
5384
|
-
* @param params.size - The size of the blob in bytes.
|
|
5385
|
-
* @param params.expirationMicros - The expiration time of the blob in microseconds.
|
|
5386
|
-
* @param params.options - Optional transaction building options.
|
|
5387
|
-
* @param params.options.chunksetSizeBytes - Custom chunkset size (defaults to DEFAULT_CHUNKSET_SIZE_BYTES).
|
|
5388
|
-
* @param params.options.build - Additional Aptos transaction building options.
|
|
5389
|
-
*
|
|
5390
|
-
* @returns An object containing the pending transaction.
|
|
5391
|
-
*
|
|
5392
|
-
* @example
|
|
5393
|
-
* ```typescript
|
|
5394
|
-
* const provider = await ClayErasureCodingProvider.create();
|
|
5395
|
-
* const blobCommitments = await generateCommitments(provider, data);
|
|
5396
|
-
*
|
|
5397
|
-
* const { transaction } = await client.registerBlob({
|
|
5398
|
-
* account: signer,
|
|
5399
|
-
* blobName: "foo/bar.txt",
|
|
5400
|
-
* blobMerkleRoot: blobCommitments.blob_merkle_root,
|
|
5401
|
-
* size: data.length,
|
|
5402
|
-
* expirationMicros: Date.now() * 1000 + 3600_000_000, // 1 hour from now in microseconds
|
|
5403
|
-
* });
|
|
5404
|
-
* ```
|
|
5582
|
+
* Returns the stored micropayment as a base64-encoded string.
|
|
5405
5583
|
*/
|
|
5406
|
-
|
|
5407
|
-
const
|
|
5408
|
-
const
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
blobName: params.blobName,
|
|
5414
|
-
blobSize: params.size,
|
|
5415
|
-
blobMerkleRoot: params.blobMerkleRoot,
|
|
5416
|
-
numChunksets: expectedTotalChunksets(params.size, chunksetSize),
|
|
5417
|
-
expirationMicros: params.expirationMicros
|
|
5418
|
-
}),
|
|
5419
|
-
sender: params.account.accountAddress
|
|
5420
|
-
});
|
|
5421
|
-
return {
|
|
5422
|
-
transaction: await this.aptos.signAndSubmitTransaction({
|
|
5423
|
-
signer: params.account,
|
|
5424
|
-
transaction
|
|
5425
|
-
})
|
|
5426
|
-
};
|
|
5584
|
+
toBase64() {
|
|
5585
|
+
const bytes = this.storedMicropayment.bcsToBytes();
|
|
5586
|
+
const binaryString = Array.from(
|
|
5587
|
+
bytes,
|
|
5588
|
+
(byte) => String.fromCharCode(byte)
|
|
5589
|
+
).join("");
|
|
5590
|
+
return btoa(binaryString);
|
|
5427
5591
|
}
|
|
5428
5592
|
/**
|
|
5429
|
-
*
|
|
5430
|
-
*
|
|
5431
|
-
* @param params.account - The account that is signing and paying for the transaction.
|
|
5432
|
-
* @param params.blobName - The name/path of the blob (e.g. "foo/bar.txt").
|
|
5433
|
-
* @param params.options - Optional transaction building options.
|
|
5434
|
-
*
|
|
5435
|
-
* @returns An object containing the pending transaction.
|
|
5436
|
-
*
|
|
5437
|
-
* @example
|
|
5438
|
-
* ```typescript
|
|
5439
|
-
*
|
|
5440
|
-
* const { transaction } = await client.deleteBlob({
|
|
5441
|
-
* account: signer,
|
|
5442
|
-
* blobName: "foo/bar.txt",
|
|
5443
|
-
* });
|
|
5444
|
-
* ```
|
|
5593
|
+
* Creates a StaleChannelStateError from a base64-encoded micropayment string.
|
|
5445
5594
|
*/
|
|
5446
|
-
|
|
5447
|
-
const
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
blobName: params.blobName
|
|
5452
|
-
}),
|
|
5453
|
-
sender: params.account.accountAddress
|
|
5454
|
-
});
|
|
5455
|
-
return {
|
|
5456
|
-
transaction: await this.aptos.signAndSubmitTransaction({
|
|
5457
|
-
signer: params.account,
|
|
5458
|
-
transaction
|
|
5459
|
-
})
|
|
5460
|
-
};
|
|
5595
|
+
static fromBase64(base64, message) {
|
|
5596
|
+
const binaryString = atob(base64);
|
|
5597
|
+
const bytes = Uint8Array.from(binaryString, (char) => char.charCodeAt(0));
|
|
5598
|
+
const micropayment = SenderBuiltMicropayment.deserialize(bytes);
|
|
5599
|
+
return new _StaleChannelStateError(micropayment, message);
|
|
5461
5600
|
}
|
|
5601
|
+
};
|
|
5602
|
+
var SenderBuiltMicropayment = class _SenderBuiltMicropayment {
|
|
5462
5603
|
/**
|
|
5463
|
-
*
|
|
5464
|
-
*
|
|
5465
|
-
* **Note:** This function requires the `delete_multiple_blobs` entry function
|
|
5466
|
-
* which will be deployed to the smart contract on 2026-02-04. Using this
|
|
5467
|
-
* function before that date will result in a transaction failure.
|
|
5468
|
-
*
|
|
5469
|
-
* This operation is atomic: if any blob deletion fails (e.g., blob not found),
|
|
5470
|
-
* the entire transaction fails and no blobs are deleted.
|
|
5471
|
-
*
|
|
5472
|
-
* @param params.account - The account that is signing and paying for the transaction.
|
|
5473
|
-
* @param params.blobNames - Array of blob name suffixes without the account address prefix
|
|
5474
|
-
* (e.g. ["foo/bar.txt", "baz.txt"], NOT ["0x1/foo/bar.txt"]). The account address
|
|
5475
|
-
* prefix is automatically derived from the signer.
|
|
5476
|
-
* @param params.options - Optional transaction building options.
|
|
5477
|
-
*
|
|
5478
|
-
* @returns An object containing the pending transaction.
|
|
5479
|
-
*
|
|
5480
|
-
* @example
|
|
5481
|
-
* ```typescript
|
|
5482
|
-
*
|
|
5483
|
-
* const { transaction } = await client.deleteMultipleBlobs({
|
|
5484
|
-
* account: signer,
|
|
5485
|
-
* blobNames: ["foo/bar.txt", "baz.txt"],
|
|
5486
|
-
* });
|
|
5487
|
-
* ```
|
|
5604
|
+
* The actual micropayment transaction. It is built with the receiver address as fee payer and also requires a signature from the receiver to submit.
|
|
5488
5605
|
*/
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5606
|
+
micropayment;
|
|
5607
|
+
/**
|
|
5608
|
+
* The sender's signature.
|
|
5609
|
+
*/
|
|
5610
|
+
senderSignature;
|
|
5611
|
+
constructor(micropayment, senderSignature) {
|
|
5612
|
+
this.micropayment = micropayment;
|
|
5613
|
+
this.senderSignature = senderSignature;
|
|
5614
|
+
}
|
|
5615
|
+
serialize(serializer) {
|
|
5616
|
+
this.micropayment.serialize(serializer);
|
|
5617
|
+
this.senderSignature.serialize(serializer);
|
|
5618
|
+
}
|
|
5619
|
+
bcsToBytes() {
|
|
5620
|
+
const serializer = new Serializer();
|
|
5621
|
+
this.serialize(serializer);
|
|
5622
|
+
return serializer.toUint8Array();
|
|
5623
|
+
}
|
|
5624
|
+
bcsToHex() {
|
|
5625
|
+
return Hex4.fromHexInput(this.bcsToBytes());
|
|
5626
|
+
}
|
|
5627
|
+
toStringWithoutPrefix() {
|
|
5628
|
+
return this.bcsToHex().toStringWithoutPrefix();
|
|
5629
|
+
}
|
|
5630
|
+
toString() {
|
|
5631
|
+
return this.bcsToHex().toString();
|
|
5504
5632
|
}
|
|
5505
5633
|
/**
|
|
5506
|
-
*
|
|
5507
|
-
*
|
|
5508
|
-
* @
|
|
5509
|
-
* @param params.blobOwner - The account that owns the blob.
|
|
5510
|
-
* @param params.blobName - The name of the blob (e.g. "foo/bar")
|
|
5511
|
-
* @param params.creationMicros - The creation time of the blob in microseconds.
|
|
5512
|
-
* @param params.chunksetIdx - The index of the chunkset being acknowledged.
|
|
5513
|
-
* @param params.storageProviderChunksetAcks - The signatures
|
|
5514
|
-
* @param params.options - Additional options for transaction building and encoding.
|
|
5515
|
-
*
|
|
5516
|
-
* @returns The blob commitments and the pending transaction.
|
|
5517
|
-
*
|
|
5518
|
-
* @example
|
|
5519
|
-
* ```typescript
|
|
5520
|
-
* const { transaction } = await client.addChunksetAcknowledgements({
|
|
5521
|
-
* account: signer,
|
|
5522
|
-
* blobOwner: owner,
|
|
5523
|
-
* blobName: "foo/bar.txt",
|
|
5524
|
-
* creationMicros, // Taken from the blob metadata at registration time.
|
|
5525
|
-
* chunksetIdx,
|
|
5526
|
-
* storageProviderAcks: An array of StorageProviderAck types, each having the slot index and signature from the SP.
|
|
5527
|
-
* });
|
|
5528
|
-
* ```
|
|
5634
|
+
* Deserializes a SenderBuiltMicropayment from BCS bytes.
|
|
5635
|
+
* @param bytes - The bytes to deserialize from (Uint8Array or hex string).
|
|
5636
|
+
* @returns A new SenderBuiltMicropayment instance.
|
|
5529
5637
|
*/
|
|
5530
|
-
|
|
5531
|
-
const
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5638
|
+
static deserialize(bytes) {
|
|
5639
|
+
const bytesArray = typeof bytes === "string" ? Hex4.fromHexInput(bytes).toUint8Array() : bytes;
|
|
5640
|
+
const deserializer = new Deserializer(bytesArray);
|
|
5641
|
+
const micropayment = MultiAgentTransaction.deserialize(deserializer);
|
|
5642
|
+
const senderSignature = AccountAuthenticator.deserialize(deserializer);
|
|
5643
|
+
return new _SenderBuiltMicropayment(micropayment, senderSignature);
|
|
5644
|
+
}
|
|
5645
|
+
};
|
|
5646
|
+
|
|
5647
|
+
// ../../packages/sdk/dist/chunk-W5NRGZEP.mjs
|
|
5648
|
+
import { AccountAddress as AccountAddress3 } from "@aptos-labs/ts-sdk";
|
|
5649
|
+
import { z as z2 } from "zod";
|
|
5650
|
+
var BlobNameSchema = z2.string().min(1, "Blob name path parameter cannot be empty.").max(1024, "Blob name cannot exceed 1024 characters.").refine((name2) => !name2.endsWith("/"), {
|
|
5651
|
+
message: "Blob name cannot end with a slash"
|
|
5652
|
+
});
|
|
5653
|
+
|
|
5654
|
+
// ../../packages/sdk/dist/chunk-I6NG5GNL.mjs
|
|
5655
|
+
function sleep(ms) {
|
|
5656
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
5657
|
+
}
|
|
5658
|
+
|
|
5659
|
+
// ../../packages/sdk/dist/chunk-IE6LYVIA.mjs
|
|
5660
|
+
import { z as z3 } from "zod";
|
|
5661
|
+
var StartMultipartUploadResponseSchema = z3.object({
|
|
5662
|
+
uploadId: z3.string()
|
|
5663
|
+
});
|
|
5664
|
+
var UploadPartResponseSchema = z3.object({
|
|
5665
|
+
success: z3.literal(true)
|
|
5666
|
+
});
|
|
5667
|
+
var CompleteMultipartUploadResponseSchema = z3.object({
|
|
5668
|
+
success: z3.literal(true)
|
|
5669
|
+
});
|
|
5670
|
+
var RPCErrorResponseSchema = z3.object({
|
|
5671
|
+
error: z3.string()
|
|
5672
|
+
});
|
|
5673
|
+
var StaleMicropaymentErrorResponseSchema = z3.object({
|
|
5674
|
+
error: z3.string().optional(),
|
|
5675
|
+
storedMicropayment: z3.string().optional()
|
|
5676
|
+
});
|
|
5677
|
+
|
|
5678
|
+
// ../../packages/sdk/dist/chunk-ZAM2EUVN.mjs
|
|
5679
|
+
import { AccountAddress as AccountAddress4 } from "@aptos-labs/ts-sdk";
|
|
5680
|
+
var MICROPAYMENT_HEADER = "X-Shelby-Micropayment";
|
|
5681
|
+
function encodeURIComponentKeepSlashes(str) {
|
|
5682
|
+
return encodeURIComponent(str).replace(/%2F/g, "/");
|
|
5683
|
+
}
|
|
5684
|
+
function validateTotalBytes(totalBytes) {
|
|
5685
|
+
if (!Number.isInteger(totalBytes) || totalBytes < 0) {
|
|
5686
|
+
throw new Error("totalBytes must be a non-negative integer");
|
|
5687
|
+
}
|
|
5688
|
+
}
|
|
5689
|
+
function getErrorCode(error) {
|
|
5690
|
+
if (typeof error === "object" && error !== null && "code" in error && typeof error.code === "string") {
|
|
5691
|
+
return error.code;
|
|
5692
|
+
}
|
|
5693
|
+
if (error instanceof Error) {
|
|
5694
|
+
const match = error.message.match(/\bE[A-Z0-9_]+\b/);
|
|
5695
|
+
return match?.[0];
|
|
5548
5696
|
}
|
|
5697
|
+
return void 0;
|
|
5698
|
+
}
|
|
5699
|
+
var ShelbyRPCClient = class {
|
|
5700
|
+
baseUrl;
|
|
5701
|
+
apiKey;
|
|
5702
|
+
rpcConfig;
|
|
5703
|
+
indexer;
|
|
5549
5704
|
/**
|
|
5550
|
-
*
|
|
5551
|
-
*
|
|
5552
|
-
* @param params.account - The account that is signing and paying for the transaction.
|
|
5553
|
-
* @param params.expirationMicros - The expiration time of the blobs in microseconds.
|
|
5554
|
-
* @param params.blobs - The blobs to register.
|
|
5555
|
-
* @param params.blobs.blobName - The name/path of the blob (e.g. "foo/bar.txt").
|
|
5556
|
-
* @param params.blobs.blobSize - The size of the blob in bytes.
|
|
5557
|
-
* @param params.blobs.blobMerkleRoot - The merkle root of the blob commitments as a hex string.
|
|
5558
|
-
* @param params.options - Optional transaction building options.
|
|
5559
|
-
* @param params.options.chunksetSizeBytes - Custom chunkset size (defaults to DEFAULT_CHUNKSET_SIZE_BYTES).
|
|
5560
|
-
* @param params.options.build - Additional Aptos transaction building options.
|
|
5705
|
+
* Creates a new ShelbyRPCClient for interacting with Shelby RPC nodes.
|
|
5706
|
+
* This client handles blob storage operations including upload and download.
|
|
5561
5707
|
*
|
|
5562
|
-
* @
|
|
5708
|
+
* @param config - The client configuration object.
|
|
5709
|
+
* @param config.network - The Shelby network to use.
|
|
5563
5710
|
*
|
|
5564
5711
|
* @example
|
|
5565
5712
|
* ```typescript
|
|
5566
|
-
* const
|
|
5567
|
-
*
|
|
5568
|
-
*
|
|
5569
|
-
* const { transaction } = await client.batchRegisterBlobs({
|
|
5570
|
-
* account: signer,
|
|
5571
|
-
* expirationMicros: Date.now() * 1000 + 3600_000_000, // 1 hour from now in microseconds
|
|
5572
|
-
* blobs: [
|
|
5573
|
-
* {
|
|
5574
|
-
* blobName: "foo/bar.txt",
|
|
5575
|
-
* blobSize: data.length,
|
|
5576
|
-
* blobMerkleRoot: blobCommitments.blob_merkle_root,
|
|
5577
|
-
* },
|
|
5578
|
-
* ],
|
|
5713
|
+
* const client = new ShelbyRPCClient({
|
|
5714
|
+
* network: Network.SHELBYNET,
|
|
5715
|
+
* apiKey: "AG-***",
|
|
5579
5716
|
* });
|
|
5580
5717
|
* ```
|
|
5581
5718
|
*/
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
data: _ShelbyBlobClient.createBatchRegisterBlobsPayload({
|
|
5588
|
-
deployer: this.deployer,
|
|
5589
|
-
account: params.account.accountAddress,
|
|
5590
|
-
expirationMicros: params.expirationMicros,
|
|
5591
|
-
blobs: params.blobs.map((blob) => ({
|
|
5592
|
-
blobName: blob.blobName,
|
|
5593
|
-
blobSize: blob.blobSize,
|
|
5594
|
-
blobMerkleRoot: blob.blobMerkleRoot,
|
|
5595
|
-
numChunksets: expectedTotalChunksets(blob.blobSize, chunksetSize)
|
|
5596
|
-
}))
|
|
5597
|
-
})
|
|
5598
|
-
});
|
|
5599
|
-
return {
|
|
5600
|
-
transaction: await this.aptos.signAndSubmitTransaction({
|
|
5601
|
-
signer: params.account,
|
|
5602
|
-
transaction
|
|
5603
|
-
})
|
|
5604
|
-
};
|
|
5719
|
+
constructor(config) {
|
|
5720
|
+
this.baseUrl = config.rpc?.baseUrl ?? NetworkToShelbyRPCBaseUrl.shelbynet;
|
|
5721
|
+
this.apiKey = config.apiKey ?? config.rpc?.apiKey;
|
|
5722
|
+
this.rpcConfig = config.rpc ?? {};
|
|
5723
|
+
this.indexer = getShelbyIndexerClient(config);
|
|
5605
5724
|
}
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5725
|
+
async #uploadPart(uploadId, partIdx, partData) {
|
|
5726
|
+
const nRetries = 5;
|
|
5727
|
+
let lastResponse;
|
|
5728
|
+
let lastError;
|
|
5729
|
+
const partUrl = buildRequestUrl(
|
|
5730
|
+
`/v1/multipart-uploads/${uploadId}/parts/${partIdx}`,
|
|
5731
|
+
this.baseUrl
|
|
5732
|
+
);
|
|
5733
|
+
for (let i = 0; i < nRetries; ++i) {
|
|
5734
|
+
try {
|
|
5735
|
+
lastResponse = await fetch(partUrl, {
|
|
5736
|
+
method: "PUT",
|
|
5737
|
+
headers: {
|
|
5738
|
+
"Content-Type": "application/octet-stream",
|
|
5739
|
+
...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
|
|
5740
|
+
},
|
|
5741
|
+
body: partData
|
|
5742
|
+
});
|
|
5743
|
+
lastError = void 0;
|
|
5744
|
+
} catch (error) {
|
|
5745
|
+
lastError = error;
|
|
5746
|
+
if (i < nRetries - 1) {
|
|
5747
|
+
const delay = 2 ** i * 100;
|
|
5748
|
+
await sleep(delay);
|
|
5749
|
+
continue;
|
|
5750
|
+
}
|
|
5751
|
+
break;
|
|
5752
|
+
}
|
|
5753
|
+
if (lastResponse.ok) return;
|
|
5754
|
+
if (i < nRetries - 1) {
|
|
5755
|
+
const delay = 2 ** i * 100;
|
|
5756
|
+
await sleep(delay);
|
|
5757
|
+
}
|
|
5758
|
+
}
|
|
5759
|
+
if (lastError !== void 0) {
|
|
5760
|
+
const errorCode = getErrorCode(lastError);
|
|
5761
|
+
const errorMessage = lastError instanceof Error ? lastError.message : String(lastError);
|
|
5762
|
+
throw new Error(
|
|
5763
|
+
`Failed to upload part ${partIdx} for multipart upload ${uploadId} after ${nRetries} attempts. The connection to the Shelby RPC endpoint was interrupted while sending data${errorCode ? ` (${errorCode})` : ""}. Endpoint: ${partUrl.toString()}, partBytes: ${partData.length}. Last error: ${errorMessage}`,
|
|
5764
|
+
{ cause: lastError }
|
|
5765
|
+
);
|
|
5766
|
+
}
|
|
5767
|
+
const errorBody = await lastResponse?.text().catch(() => "");
|
|
5768
|
+
throw new Error(
|
|
5769
|
+
`Failed to upload part ${partIdx} for multipart upload ${uploadId} after ${nRetries} attempts. status: ${lastResponse?.status}, body: ${errorBody}`
|
|
5770
|
+
);
|
|
5638
5771
|
}
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5772
|
+
async #putBlobMultipart(account, blobName, blobData, totalBytes, partSize = 5 * 1024 * 1024, onProgress) {
|
|
5773
|
+
validateTotalBytes(totalBytes);
|
|
5774
|
+
const startResponse = await fetch(
|
|
5775
|
+
buildRequestUrl("/v1/multipart-uploads", this.baseUrl),
|
|
5776
|
+
{
|
|
5777
|
+
method: "POST",
|
|
5778
|
+
headers: {
|
|
5779
|
+
"Content-Type": "application/json",
|
|
5780
|
+
...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
|
|
5781
|
+
},
|
|
5782
|
+
body: JSON.stringify({
|
|
5783
|
+
rawAccount: account.toString(),
|
|
5784
|
+
rawBlobName: blobName,
|
|
5785
|
+
rawPartSize: partSize
|
|
5786
|
+
})
|
|
5787
|
+
}
|
|
5788
|
+
);
|
|
5789
|
+
if (!startResponse.ok) {
|
|
5790
|
+
let errorBodyText = "Could not read error body";
|
|
5791
|
+
try {
|
|
5792
|
+
errorBodyText = await startResponse.text();
|
|
5793
|
+
} catch (_e) {
|
|
5794
|
+
}
|
|
5795
|
+
throw new Error(
|
|
5796
|
+
`Failed to start multipart upload! status: ${startResponse.status}, body: ${errorBodyText}`
|
|
5797
|
+
);
|
|
5798
|
+
}
|
|
5799
|
+
const { uploadId } = StartMultipartUploadResponseSchema.parse(
|
|
5800
|
+
await startResponse.json()
|
|
5801
|
+
);
|
|
5802
|
+
const totalParts = Math.ceil(totalBytes / partSize);
|
|
5803
|
+
let uploadedBytes = 0;
|
|
5804
|
+
for await (const [partIdx, partData] of readInChunks(blobData, partSize)) {
|
|
5805
|
+
await this.#uploadPart(uploadId, partIdx, partData);
|
|
5806
|
+
uploadedBytes += partData.length;
|
|
5807
|
+
onProgress?.({
|
|
5808
|
+
phase: "uploading",
|
|
5809
|
+
partIdx,
|
|
5810
|
+
totalParts,
|
|
5811
|
+
partBytes: partData.length,
|
|
5812
|
+
uploadedBytes,
|
|
5813
|
+
totalBytes
|
|
5814
|
+
});
|
|
5815
|
+
}
|
|
5816
|
+
if (uploadedBytes !== totalBytes) {
|
|
5817
|
+
throw new Error(
|
|
5818
|
+
`Uploaded bytes (${uploadedBytes}) did not match declared totalBytes (${totalBytes})`
|
|
5819
|
+
);
|
|
5820
|
+
}
|
|
5821
|
+
const finalPartIdx = totalParts > 0 ? totalParts - 1 : 0;
|
|
5822
|
+
onProgress?.({
|
|
5823
|
+
phase: "finalizing",
|
|
5824
|
+
partIdx: finalPartIdx,
|
|
5825
|
+
totalParts,
|
|
5826
|
+
// no part uploaded in this phase
|
|
5827
|
+
partBytes: 0,
|
|
5828
|
+
uploadedBytes: totalBytes,
|
|
5829
|
+
totalBytes
|
|
5666
5830
|
});
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5831
|
+
const completeResponse = await fetch(
|
|
5832
|
+
buildRequestUrl(
|
|
5833
|
+
`/v1/multipart-uploads/${uploadId}/complete`,
|
|
5834
|
+
this.baseUrl
|
|
5835
|
+
),
|
|
5836
|
+
{
|
|
5837
|
+
method: "POST",
|
|
5838
|
+
headers: {
|
|
5839
|
+
"Content-Type": "application/json",
|
|
5840
|
+
...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
|
|
5841
|
+
}
|
|
5842
|
+
}
|
|
5843
|
+
);
|
|
5844
|
+
if (!completeResponse.ok) {
|
|
5845
|
+
let errorBodyText = "Could not read error body";
|
|
5846
|
+
try {
|
|
5847
|
+
errorBodyText = await completeResponse.text();
|
|
5848
|
+
} catch (_e) {
|
|
5849
|
+
}
|
|
5850
|
+
throw new Error(
|
|
5851
|
+
`Failed to complete multipart upload! status: ${completeResponse.status}, body: ${errorBodyText}`
|
|
5852
|
+
);
|
|
5853
|
+
}
|
|
5680
5854
|
}
|
|
5681
5855
|
/**
|
|
5682
|
-
*
|
|
5683
|
-
* This
|
|
5856
|
+
* Uploads blob data to the Shelby RPC node for storage by storage providers.
|
|
5857
|
+
* This method should be called after blob commitments have been registered on the blockchain.
|
|
5858
|
+
* Uses multipart upload for efficient handling of large files.
|
|
5684
5859
|
*
|
|
5685
|
-
* @param params.
|
|
5686
|
-
* @param params.blobName - The blob
|
|
5860
|
+
* @param params.account - The account that owns the blob.
|
|
5861
|
+
* @param params.blobName - The name/path of the blob (e.g. "folder/file.txt").
|
|
5862
|
+
* @param params.blobData - The raw blob data as a Uint8Array or ReadableStream.
|
|
5863
|
+
* @param params.totalBytes - Total byte length. Required for streams; optional for Uint8Array.
|
|
5687
5864
|
*
|
|
5688
|
-
* @
|
|
5865
|
+
* @example
|
|
5866
|
+
* ```typescript
|
|
5867
|
+
* const blobData = new TextEncoder().encode("Hello, world!");
|
|
5689
5868
|
*
|
|
5690
|
-
*
|
|
5869
|
+
* await client.putBlob({
|
|
5870
|
+
* account: AccountAddress.from("0x1"),
|
|
5871
|
+
* blobName: "greetings/hello.txt",
|
|
5872
|
+
* blobData,
|
|
5873
|
+
* });
|
|
5874
|
+
* ```
|
|
5691
5875
|
*/
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5876
|
+
async putBlob(params) {
|
|
5877
|
+
BlobNameSchema.parse(params.blobName);
|
|
5878
|
+
let totalBytes;
|
|
5879
|
+
if (params.blobData instanceof Uint8Array) {
|
|
5880
|
+
totalBytes = params.totalBytes ?? params.blobData.length;
|
|
5881
|
+
if (totalBytes !== params.blobData.length) {
|
|
5882
|
+
throw new Error(
|
|
5883
|
+
"totalBytes must match blobData.length when blobData is a Uint8Array"
|
|
5884
|
+
);
|
|
5885
|
+
}
|
|
5886
|
+
} else {
|
|
5887
|
+
if (params.totalBytes === void 0) {
|
|
5888
|
+
throw new Error(
|
|
5889
|
+
"totalBytes is required when blobData is a ReadableStream"
|
|
5890
|
+
);
|
|
5891
|
+
}
|
|
5892
|
+
totalBytes = params.totalBytes;
|
|
5893
|
+
}
|
|
5894
|
+
validateTotalBytes(totalBytes);
|
|
5895
|
+
await this.#putBlobMultipart(
|
|
5896
|
+
params.account,
|
|
5897
|
+
params.blobName,
|
|
5898
|
+
params.blobData,
|
|
5899
|
+
totalBytes,
|
|
5900
|
+
void 0,
|
|
5901
|
+
params.onProgress
|
|
5902
|
+
);
|
|
5697
5903
|
}
|
|
5698
5904
|
/**
|
|
5699
|
-
*
|
|
5700
|
-
*
|
|
5905
|
+
* Downloads a blob from the Shelby RPC node.
|
|
5906
|
+
* Returns a streaming response with validation to ensure data integrity.
|
|
5701
5907
|
*
|
|
5702
|
-
*
|
|
5703
|
-
*
|
|
5704
|
-
*
|
|
5908
|
+
* @param params.account - The account that owns the blob.
|
|
5909
|
+
* @param params.blobName - The name/path of the blob (e.g. "folder/file.txt").
|
|
5910
|
+
* @param params.range - Optional byte range for partial downloads.
|
|
5911
|
+
* @param params.range.start - Starting byte position (inclusive).
|
|
5912
|
+
* @param params.range.end - Ending byte position (inclusive, optional).
|
|
5913
|
+
* @param params.micropayment - Optional micropayment to attach to the request.
|
|
5705
5914
|
*
|
|
5706
|
-
*
|
|
5707
|
-
* the entire transaction fails and no blobs are deleted.
|
|
5915
|
+
* @returns A ShelbyBlob object containing the account, name, readable stream, and content length.
|
|
5708
5916
|
*
|
|
5709
|
-
* @
|
|
5710
|
-
* @
|
|
5711
|
-
* (e.g. ["foo/bar.txt", "baz.txt"], NOT ["0x1/foo/bar.txt"]). The account address
|
|
5712
|
-
* prefix is automatically derived from the transaction sender.
|
|
5917
|
+
* @throws Error if the download fails or content length doesn't match.
|
|
5918
|
+
* @throws StaleChannelStateError if the micropayment is stale (server has newer state).
|
|
5713
5919
|
*
|
|
5714
|
-
* @
|
|
5920
|
+
* @example
|
|
5921
|
+
* ```typescript
|
|
5922
|
+
* // Download entire blob
|
|
5923
|
+
* const blob = await client.getBlob({
|
|
5924
|
+
* account: AccountAddress.from("0x1"),
|
|
5925
|
+
* blobName: "documents/report.pdf"
|
|
5926
|
+
* });
|
|
5715
5927
|
*
|
|
5716
|
-
*
|
|
5928
|
+
* // Download partial content (bytes 100-199)
|
|
5929
|
+
* const partial = await client.getBlob({
|
|
5930
|
+
* account: AccountAddress.from("0x1"),
|
|
5931
|
+
* blobName: "large-file.bin",
|
|
5932
|
+
* range: { start: 100, end: 199 }
|
|
5933
|
+
* });
|
|
5934
|
+
*
|
|
5935
|
+
* // Download with micropayment
|
|
5936
|
+
* const blob = await client.getBlob({
|
|
5937
|
+
* account: AccountAddress.from("0x1"),
|
|
5938
|
+
* blobName: "documents/report.pdf",
|
|
5939
|
+
* micropayment: senderBuiltMicropayment
|
|
5940
|
+
* });
|
|
5941
|
+
* ```
|
|
5717
5942
|
*/
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
const ackBitMask = params.storageProviderAcks.reduce(
|
|
5726
|
-
(acc, ack) => acc | 1 << ack.slot,
|
|
5727
|
-
0
|
|
5943
|
+
async getBlob(params) {
|
|
5944
|
+
BlobNameSchema.parse(params.blobName);
|
|
5945
|
+
const url = buildRequestUrl(
|
|
5946
|
+
`/v1/blobs/${params.account.toString()}/${encodeURIComponentKeepSlashes(
|
|
5947
|
+
params.blobName
|
|
5948
|
+
)}`,
|
|
5949
|
+
this.baseUrl
|
|
5728
5950
|
);
|
|
5729
|
-
const
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
signatures
|
|
5741
|
-
]
|
|
5742
|
-
};
|
|
5743
|
-
}
|
|
5744
|
-
};
|
|
5745
|
-
|
|
5746
|
-
// ../../packages/sdk/dist/chunk-UCDAABAS.mjs
|
|
5747
|
-
import {
|
|
5748
|
-
createDecoder,
|
|
5749
|
-
createEncoder
|
|
5750
|
-
} from "@shelby-protocol/clay-codes";
|
|
5751
|
-
function getTotalChunks(config) {
|
|
5752
|
-
return config.erasure_n;
|
|
5753
|
-
}
|
|
5754
|
-
var ClayErasureCodingProvider = class _ClayErasureCodingProvider {
|
|
5755
|
-
config;
|
|
5756
|
-
encoderCache;
|
|
5757
|
-
decoderCache;
|
|
5758
|
-
lastFunction;
|
|
5759
|
-
constructor(config) {
|
|
5760
|
-
this.config = config;
|
|
5761
|
-
this.lastFunction = "none";
|
|
5762
|
-
}
|
|
5763
|
-
/**
|
|
5764
|
-
* Static factory method to create an initialized ClayErasureCodingProvider
|
|
5765
|
-
*/
|
|
5766
|
-
static async create(options) {
|
|
5767
|
-
const config = buildClayConfig({
|
|
5768
|
-
erasure_n: options?.erasure_n ?? DEFAULT_ERASURE_N,
|
|
5769
|
-
erasure_k: options?.erasure_k ?? DEFAULT_ERASURE_K,
|
|
5770
|
-
erasure_d: options?.erasure_d ?? DEFAULT_ERASURE_D,
|
|
5771
|
-
chunkSizeBytes: options?.chunkSizeBytes ?? DEFAULT_CHUNK_SIZE_BYTES
|
|
5772
|
-
});
|
|
5773
|
-
const provider = new _ClayErasureCodingProvider(config);
|
|
5774
|
-
[provider.encoderCache, provider.decoderCache] = await Promise.all([
|
|
5775
|
-
createEncoder({
|
|
5776
|
-
n: getTotalChunks(config),
|
|
5777
|
-
k: config.erasure_k,
|
|
5778
|
-
d: config.erasure_d,
|
|
5779
|
-
chunkSizeBytes: config.chunkSizeBytes
|
|
5780
|
-
}),
|
|
5781
|
-
createDecoder({
|
|
5782
|
-
n: getTotalChunks(config),
|
|
5783
|
-
k: config.erasure_k,
|
|
5784
|
-
d: config.erasure_d,
|
|
5785
|
-
chunkSizeBytes: config.chunkSizeBytes,
|
|
5786
|
-
erasedChunksMask: 0
|
|
5787
|
-
// No chunks erased initially; will be reconfigured on decode
|
|
5788
|
-
})
|
|
5789
|
-
]);
|
|
5790
|
-
return provider;
|
|
5791
|
-
}
|
|
5792
|
-
encode(data) {
|
|
5793
|
-
const { erasure_k, chunkSizeBytes } = this.config;
|
|
5794
|
-
if (!this.encoderCache) {
|
|
5795
|
-
throw new Error("Encoder cache is missing");
|
|
5951
|
+
const headers = new Headers();
|
|
5952
|
+
if (params.range !== void 0) {
|
|
5953
|
+
const { start, end } = params.range;
|
|
5954
|
+
if (end === void 0) {
|
|
5955
|
+
headers.set("Range", `bytes=${start}-`);
|
|
5956
|
+
} else {
|
|
5957
|
+
if (end < start) {
|
|
5958
|
+
throw new Error("Range end cannot be less than start.");
|
|
5959
|
+
}
|
|
5960
|
+
headers.set("Range", `bytes=${start}-${end}`);
|
|
5961
|
+
}
|
|
5796
5962
|
}
|
|
5797
|
-
|
|
5798
|
-
|
|
5963
|
+
if (this.apiKey) {
|
|
5964
|
+
headers.set("Authorization", `Bearer ${this.apiKey}`);
|
|
5965
|
+
}
|
|
5966
|
+
if (params.micropayment) {
|
|
5967
|
+
const bytes = params.micropayment.bcsToBytes();
|
|
5968
|
+
const binaryString = Array.from(
|
|
5969
|
+
bytes,
|
|
5970
|
+
(byte) => String.fromCharCode(byte)
|
|
5971
|
+
).join("");
|
|
5972
|
+
headers.set(MICROPAYMENT_HEADER, btoa(binaryString));
|
|
5973
|
+
}
|
|
5974
|
+
const response = await fetch(url, { headers });
|
|
5975
|
+
if (response.status === 409) {
|
|
5976
|
+
let json;
|
|
5977
|
+
try {
|
|
5978
|
+
json = await response.json();
|
|
5979
|
+
} catch {
|
|
5980
|
+
throw new Error(
|
|
5981
|
+
`Failed to download blob: ${response.status} ${response.statusText}`
|
|
5982
|
+
);
|
|
5983
|
+
}
|
|
5984
|
+
const parseResult = StaleMicropaymentErrorResponseSchema.safeParse(json);
|
|
5985
|
+
if (!parseResult.success) {
|
|
5986
|
+
throw new Error(
|
|
5987
|
+
`Failed to download blob: ${response.status} ${response.statusText}`
|
|
5988
|
+
);
|
|
5989
|
+
}
|
|
5990
|
+
const errorBody = parseResult.data;
|
|
5991
|
+
if (errorBody.storedMicropayment) {
|
|
5992
|
+
throw StaleChannelStateError.fromBase64(
|
|
5993
|
+
errorBody.storedMicropayment,
|
|
5994
|
+
errorBody.error
|
|
5995
|
+
);
|
|
5996
|
+
}
|
|
5799
5997
|
throw new Error(
|
|
5800
|
-
|
|
5998
|
+
errorBody.error ?? `Failed to download blob: ${response.status} ${response.statusText}`
|
|
5801
5999
|
);
|
|
5802
6000
|
}
|
|
5803
|
-
if (
|
|
6001
|
+
if (!response.ok) {
|
|
5804
6002
|
throw new Error(
|
|
5805
|
-
`
|
|
6003
|
+
`Failed to download blob: ${response.status} ${response.statusText}`
|
|
5806
6004
|
);
|
|
5807
6005
|
}
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
}
|
|
5811
|
-
decode(available, config) {
|
|
5812
|
-
if (!this.decoderCache) {
|
|
5813
|
-
throw new Error("Decoder cache is missing");
|
|
6006
|
+
if (!response.body) {
|
|
6007
|
+
throw new Error("Response body is null");
|
|
5814
6008
|
}
|
|
5815
|
-
const
|
|
5816
|
-
if (
|
|
6009
|
+
const contentLengthHeader = response.headers.get("content-length");
|
|
6010
|
+
if (contentLengthHeader === null) {
|
|
5817
6011
|
throw new Error(
|
|
5818
|
-
|
|
6012
|
+
"Response did not have content-length header, which is required"
|
|
5819
6013
|
);
|
|
5820
6014
|
}
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
);
|
|
5827
|
-
}
|
|
6015
|
+
const expectedContentLength = Number.parseInt(contentLengthHeader, 10);
|
|
6016
|
+
if (Number.isNaN(expectedContentLength)) {
|
|
6017
|
+
throw new Error(
|
|
6018
|
+
`Invalid content-length header received: ${contentLengthHeader}`
|
|
6019
|
+
);
|
|
5828
6020
|
}
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
6021
|
+
const validatingStream = new ReadableStream({
|
|
6022
|
+
start(controller) {
|
|
6023
|
+
const maybeReader = response.body?.getReader();
|
|
6024
|
+
if (!maybeReader) {
|
|
6025
|
+
controller.error(new Error("Response body reader is unavailable"));
|
|
6026
|
+
return;
|
|
6027
|
+
}
|
|
6028
|
+
const reader = maybeReader;
|
|
6029
|
+
let bytesReceived = 0;
|
|
6030
|
+
function pump() {
|
|
6031
|
+
return reader.read().then(({ done, value }) => {
|
|
6032
|
+
if (done) {
|
|
6033
|
+
if (bytesReceived !== expectedContentLength) {
|
|
6034
|
+
controller.error(
|
|
6035
|
+
new Error(
|
|
6036
|
+
`Downloaded data size (${bytesReceived} bytes) does not match content-length header (${expectedContentLength} bytes). This might indicate a partial or corrupted download.`
|
|
6037
|
+
)
|
|
6038
|
+
);
|
|
6039
|
+
return;
|
|
6040
|
+
}
|
|
6041
|
+
controller.close();
|
|
6042
|
+
return;
|
|
6043
|
+
}
|
|
6044
|
+
bytesReceived += value.byteLength;
|
|
6045
|
+
controller.enqueue(value);
|
|
6046
|
+
return pump();
|
|
6047
|
+
}).catch((error) => {
|
|
6048
|
+
controller.error(error);
|
|
6049
|
+
});
|
|
6050
|
+
}
|
|
6051
|
+
return pump();
|
|
6052
|
+
}
|
|
6053
|
+
});
|
|
6054
|
+
return {
|
|
6055
|
+
account: AccountAddress4.from(params.account),
|
|
6056
|
+
name: params.blobName,
|
|
6057
|
+
readable: validatingStream,
|
|
6058
|
+
contentLength: expectedContentLength
|
|
6059
|
+
};
|
|
5854
6060
|
}
|
|
5855
6061
|
};
|
|
5856
|
-
function buildClayConfig(input) {
|
|
5857
|
-
const { erasure_n, erasure_k, erasure_d, chunkSizeBytes } = input;
|
|
5858
|
-
if (erasure_n <= 0)
|
|
5859
|
-
throw new Error("erasure_n (total number of chunks) must be > 0");
|
|
5860
|
-
if (erasure_k <= 0)
|
|
5861
|
-
throw new Error("erasure_k (number of data chunks) must be > 0");
|
|
5862
|
-
if (erasure_k >= erasure_n)
|
|
5863
|
-
throw new Error(
|
|
5864
|
-
`erasure_k (${erasure_k}) must be < erasure_n (${erasure_n})`
|
|
5865
|
-
);
|
|
5866
|
-
if (erasure_d <= erasure_k)
|
|
5867
|
-
throw new Error(
|
|
5868
|
-
`erasure_d (${erasure_d}) must be > erasure_k (${erasure_k})`
|
|
5869
|
-
);
|
|
5870
|
-
if (erasure_d >= erasure_n)
|
|
5871
|
-
throw new Error(
|
|
5872
|
-
`erasure_d (${erasure_d}) must be < erasure_n (${erasure_n})`
|
|
5873
|
-
);
|
|
5874
|
-
if (chunkSizeBytes <= 0) throw new Error("chunkSizeBytes must be > 0");
|
|
5875
|
-
return {
|
|
5876
|
-
erasure_n,
|
|
5877
|
-
erasure_k,
|
|
5878
|
-
erasure_d,
|
|
5879
|
-
chunkSizeBytes
|
|
5880
|
-
};
|
|
5881
|
-
}
|
|
5882
6062
|
|
|
5883
|
-
// ../../packages/sdk/dist/chunk-
|
|
6063
|
+
// ../../packages/sdk/dist/chunk-W6YL46DT.mjs
|
|
5884
6064
|
import {
|
|
5885
|
-
AccountAddress as
|
|
5886
|
-
Aptos as
|
|
6065
|
+
AccountAddress as AccountAddress5,
|
|
6066
|
+
Aptos as Aptos2,
|
|
5887
6067
|
DEFAULT_TXN_TIMEOUT_SEC,
|
|
5888
6068
|
TransactionResponseType
|
|
5889
6069
|
} from "@aptos-labs/ts-sdk";
|
|
@@ -6025,7 +6205,7 @@ function validateConcurrency(concurrency) {
|
|
|
6025
6205
|
}
|
|
6026
6206
|
}
|
|
6027
6207
|
|
|
6028
|
-
// ../../packages/sdk/dist/chunk-
|
|
6208
|
+
// ../../packages/sdk/dist/chunk-W6YL46DT.mjs
|
|
6029
6209
|
var ShelbyClient = class {
|
|
6030
6210
|
/**
|
|
6031
6211
|
* The coordination client is used to interact with the Aptos blockchain which handles the commitments
|
|
@@ -6081,7 +6261,7 @@ var ShelbyClient = class {
|
|
|
6081
6261
|
*/
|
|
6082
6262
|
constructor(config, provider) {
|
|
6083
6263
|
this.config = config;
|
|
6084
|
-
this.aptos = new
|
|
6264
|
+
this.aptos = new Aptos2(getAptosConfig(config));
|
|
6085
6265
|
this.coordination = new ShelbyBlobClient(config);
|
|
6086
6266
|
this.rpc = new ShelbyRPCClient(config);
|
|
6087
6267
|
this._provider = provider;
|
|
@@ -6107,6 +6287,11 @@ var ShelbyClient = class {
|
|
|
6107
6287
|
* This method handles the complete upload flow including commitment generation,
|
|
6108
6288
|
* blockchain registration, and storage upload.
|
|
6109
6289
|
*
|
|
6290
|
+
* Note: This method accepts only `Uint8Array` and buffers the entire blob in memory.
|
|
6291
|
+
* For streaming uploads of large files (e.g. >2 GiB), orchestrate the steps manually
|
|
6292
|
+
* using `generateCommitments()`, `coordination.registerBlob()`, and `rpc.putBlob()`
|
|
6293
|
+
* with a `ReadableStream`.
|
|
6294
|
+
*
|
|
6110
6295
|
* @param params.blobData - The raw data to upload as a Uint8Array.
|
|
6111
6296
|
* @param params.signer - The account that signs and pays for the transaction.
|
|
6112
6297
|
* @param params.blobName - The name/path of the blob (e.g. "folder/file.txt").
|
|
@@ -6161,6 +6346,11 @@ var ShelbyClient = class {
|
|
|
6161
6346
|
* This method handles the complete upload flow including commitment generation,
|
|
6162
6347
|
* blockchain registration, and storage upload.
|
|
6163
6348
|
*
|
|
6349
|
+
* Note: This method accepts only `Uint8Array` and buffers each blob in memory.
|
|
6350
|
+
* For streaming uploads of large files, orchestrate the steps manually using
|
|
6351
|
+
* `generateCommitments()`, `coordination.registerBlob()`, and `rpc.putBlob()`
|
|
6352
|
+
* with a `ReadableStream`.
|
|
6353
|
+
*
|
|
6164
6354
|
* @param params.blobs - The blobs to upload.
|
|
6165
6355
|
* @param params.blobs.blobData - The raw data to upload as a Uint8Array.
|
|
6166
6356
|
* @param params.blobs.blobName - The name/path of the blob (e.g. "folder/file.txt").
|
|
@@ -6278,19 +6468,22 @@ var ShelbyClient = class {
|
|
|
6278
6468
|
async fundAccountWithShelbyUSD(params) {
|
|
6279
6469
|
const { address, amount } = params;
|
|
6280
6470
|
try {
|
|
6281
|
-
const faucet = this.config.faucet ?? "https://faucet.shelbynet.shelby.xyz/fund?asset=shelbyusd";
|
|
6471
|
+
const faucet = this.config.faucet?.baseUrl ?? "https://faucet.shelbynet.shelby.xyz/fund?asset=shelbyusd";
|
|
6472
|
+
const authToken = this.config.faucet?.authToken;
|
|
6282
6473
|
const response = await fetch(`${faucet}`, {
|
|
6283
6474
|
method: "POST",
|
|
6284
6475
|
body: JSON.stringify({
|
|
6285
|
-
address:
|
|
6476
|
+
address: AccountAddress5.from(address).toString(),
|
|
6286
6477
|
amount
|
|
6287
6478
|
}),
|
|
6288
6479
|
headers: {
|
|
6289
|
-
"Content-Type": "application/json"
|
|
6480
|
+
"Content-Type": "application/json",
|
|
6481
|
+
...authToken ? { Authorization: `Bearer ${authToken}` } : {}
|
|
6290
6482
|
}
|
|
6291
6483
|
});
|
|
6292
6484
|
if (!response.ok) {
|
|
6293
|
-
|
|
6485
|
+
const errorBody = await response.text();
|
|
6486
|
+
throw new Error(`Failed to fund account: ${errorBody}`);
|
|
6294
6487
|
}
|
|
6295
6488
|
const json = await response.json();
|
|
6296
6489
|
const res = await this.aptos.waitForTransaction({
|
|
@@ -6334,10 +6527,37 @@ var ShelbyClient = class {
|
|
|
6334
6527
|
}
|
|
6335
6528
|
};
|
|
6336
6529
|
|
|
6337
|
-
// ../../packages/sdk/dist/chunk-
|
|
6530
|
+
// ../../packages/sdk/dist/chunk-DI2K6OUG.mjs
|
|
6338
6531
|
var ShelbyNodeClient = class extends ShelbyClient {
|
|
6339
6532
|
};
|
|
6340
6533
|
|
|
6534
|
+
// ../../packages/sdk/dist/chunk-YZXIPUVQ.mjs
|
|
6535
|
+
import {
|
|
6536
|
+
AccountAddress as AccountAddress6,
|
|
6537
|
+
Aptos as Aptos3,
|
|
6538
|
+
Hex as Hex5
|
|
6539
|
+
} from "@aptos-labs/ts-sdk";
|
|
6540
|
+
|
|
6541
|
+
// ../../packages/sdk/dist/chunk-7P6ASYW6.mjs
|
|
6542
|
+
var __defProp2 = Object.defineProperty;
|
|
6543
|
+
var __export = (target, all) => {
|
|
6544
|
+
for (var name2 in all)
|
|
6545
|
+
__defProp2(target, name2, { get: all[name2], enumerable: true });
|
|
6546
|
+
};
|
|
6547
|
+
|
|
6548
|
+
// ../../packages/sdk/dist/chunk-A4IG6GSE.mjs
|
|
6549
|
+
var testUtil_exports = {};
|
|
6550
|
+
__export(testUtil_exports, {
|
|
6551
|
+
makeChunk: () => makeChunk
|
|
6552
|
+
});
|
|
6553
|
+
function makeChunk(n) {
|
|
6554
|
+
const c = Buffer.alloc(n);
|
|
6555
|
+
for (let i = 0; i < n; ++i) {
|
|
6556
|
+
c[i] = i % 256;
|
|
6557
|
+
}
|
|
6558
|
+
return c;
|
|
6559
|
+
}
|
|
6560
|
+
|
|
6341
6561
|
// ../../packages/reed-solomon/dist/index.mjs
|
|
6342
6562
|
var __toBinaryNode = (base64) => new Uint8Array(Buffer.from(base64, "base64"));
|
|
6343
6563
|
var reed_solomon_erasure_bg_default = __toBinaryNode("AGFzbQEAAAAB/oCAgAASYAJ/fwF/YAF/AX9gBH9/f38AYAABf2ABfwBgAn9/AGADf39/AX9gAABgBH9/f38Bf2AGf39/f39/AX9gA39/fwBgBX9/f39/AX9gCH9/f39/f39/AGABfwF+YAZ/f39/f38AYAV/f39/fwBgB39/f39/f38Bf2ADfn9/AX8Dj4GAgACNAQkFBgYCBgkKCQwKAAsIDgYGBQsCBQ8PEAgGCgARCgACBQAFCgUFCAIAAgUBAgAABAQFAgIACgoFBAUKBQAEBQUEBAgABQEGCAADAgYGCgAEBQAFBA8EBAULAQEFAAAAAQEKCAoAAAAKAAUFBgAABAcBBwcBAQEAAQABAw0NDQ0HAwMBDQQEBAQEBAQFBASFgICAAAFwAS0tBYOAgIAAAQASBomAgIAAAX8BQYCAwAALB8eAgIAABQZtZW1vcnkCAAZlbmNvZGUADQtyZWNvbnN0cnVjdAAIEV9fd2JpbmRnZW5fbWFsbG9jAEUPX193YmluZGdlbl9mcmVlAFsJvICAgAABAEEBCywoXIQBMnh5hgGFASl2d3pVQ11OaIgBPlJ7hwF8ZEiLAYoBSxs8iQF9TyAqVn5eNAtlHowBgwEKnoWCgACNAaomARd/IwBB8CRrIgYkAEEAIQcCQCAAKAIIIgggAksNAEEBIQcgCCACSQ0AAkACQAJAAkACQAJAAkACQCACRQ0AAkACQCABKAIEIglFDQAgASACQQN0IgpqIQsgASEMA0AgCkUNAiAKQXhqIQpBCCEHIAwoAgQhDSAMQQhqIQwgDSAJRg0ADAsLCyAGQfAkaiQAQQoPC0ELIQcgAiAERw0IQQAhDEEAIQoDQCAMIAMgCmotAABqIQwgCkEBaiIKIAJJDQALQQ0hByAMIAhGDQhBCSEHIAwgACgCACIKSQ0IIAZCADcD4BwCQCAKQSFJDQAgBkHgHGogChAlCyAGIAZB4BxqQYgCEEYhDCAAKAIEIQogDEIANwPgHAJAIApBIUkNACAMQeAcaiAKECQgAEEEaigCACEKCyAMQYgCaiAMQeAcakGIAhBGGiAMQgA3A+AcAkAgCkEhSQ0AIAxB4BxqIAoQJAsgDEGQBGogDEHgHGpBiAIQRhogACgCACEKIAxCADcD4BwCQCAKQSFJDQAgDEHgHGogChAiIAAoAgAhCgsgDEGYBmogDEHgHGpBiAEQRhogDEIANwPgHAJAIApBIUkNACAMQeAcaiAKECILIAxBoAdqIAxB4BxqQYgBEEYaAkAgCyABRg0AIAJBA3QhDSAMQaAHakEMaiEEIAxBoAdqQQhqIQsgDEGIAmpBCGohDiAMQZAEakEIaiEPIAxBmAZqQQxqIRAgDEGYBmpBCGohESAMQQhqIRJBACEKA0AgCiACTw0DAkACQAJAIAMgCmotAABFDQAgDEEMaigCACAMKAIAIgcgB0EgSyIIGyIJIAAoAgBPDQIgAUEEaigCACETIAEoAgAhFAJAIAkgB0EgIAgbRw0AIAxBf0EAQX8gCWd2IAlBAWpBAkkbIgdBAWoiCCAIIAdJGxAlIAwoAgAhBwsgEigCACEIIAxBDEEAIAdBIEsiBxtqIAlBAWo2AgAgCCASIAcbIAlBA3RqIgcgEzYCBCAHIBQ2AgACQCAQKAIAIAwoApgGIgkgCUEgSyIIGyIHIAlBICAIGyIIRw0AAkACQCAIQQFqIgkgCEkNAEEAIQgCQCAJQQJJDQBBfyAJQX9qZ3YhCAsgCEEBaiIJIAhPDQELQX8hCQsgDEGYBmogCRAiIAwoApgGIQkLIBEoAgAgESAJQSBLIggbIQkgECAMQZgGaiAIGyEIDAELIAFBBGooAgAhCSABKAIAIQgCQAJAIAogACgCAE8NAAJAIAxBiAJqQQxqKAIAIAwoAogCIgcgB0EgSyIUGyITIAdBICAUGyIURw0AAkACQCAUQQFqIgcgFEkNAEEAIRQCQCAHQQJJDQBBfyAHQX9qZ3YhFAsgFEEBaiIHIBRPDQELQX8hBwsgDEGIAmogBxAkIAwoAogCIQcLIA4oAgAhFCAMQYgCakEMQQAgB0EgSyIHG2ogE0EBajYCACAUIA4gBxsgE0EDdGoiByAINgIAIAdBBGohBwwBCwJAIAxBkARqQQxqKAIAIAwoApAEIgcgB0EgSyIUGyITIAdBICAUGyIURw0AAkACQCAUQQFqIgcgFEkNAEEAIRQCQCAHQQJJDQBBfyAHQX9qZ3YhFAsgFEEBaiIHIBRPDQELQX8hBwsgDEGQBGogBxAkIAwoApAEIQcLIA8oAgAhFCAMQZAEakEMQQAgB0EgSyIHG2ogE0EBajYCACAUIA8gBxsgE0EDdGoiByAINgIAIAdBBGohBwsgByAJNgIAAkAgBCgCACAMKAKgByIJIAlBIEsiCBsiByAJQSAgCBsiCEcNAAJAAkAgCEEBaiIJIAhJDQBBACEIAkAgCUECSQ0AQX8gCUF/amd2IQgLIAhBAWoiCSAITw0BC0F/IQkLIAxBoAdqIAkQIiAMKAKgByEJCyALKAIAIAsgCUEgSyIIGyEJIAQgDEGgB2ogCBshCAsgCCAHQQFqNgIAIAkgB0ECdGogCjYCAAsgAUEIaiEBIApBAWohCiANQXhqIg0NAAsLIAxBmAZqQQhqIggoAgAhBCAMQZgGakEMaigCACEBIAwoApgGIQkgDCAAQZwIaiIVIAxBoAdqQQhqIgooAgAgCiAMKAKgByIHQSBLIg0bIhYgDEGgB2pBDGooAgAgByANGyIXEBkiCjYCuAogCg0HIAAoAgAiByAHbCIKQX9MDQICQAJAAkAgCkUNAEEBIQsgCkEBEG0iDUUNCSAKIRIgCkGACE0NAQwCC0EBIQ0LIAxB4BxqIA0gChBGGiAMQbAIakECaiAMQeAcakECai0AADoAACAMIAwvAOAcOwGwCCAMKADjHCEQIAwoAOccIRIgDEHQFGogDEHrHGpB+AcQRhpBACELAkAgCkUNACANIApBARBnCyAQIQ0LIAxBzAxqIAs6AAAgDEHNDGoiECAMLwGwCDsAACAMQcAMakEUaiIRIBI2AgAgDEHADGpBEGoiEiANNgIAIAxBzwxqIAxBsAhqQQJqLQAAOgAAIAwgCjYCyAwgDCAHNgLEDCAMIAc2AsAMIAxB2AxqIAxB0BRqQfgHEEYaAkACQAJAIAEgCSAJQSBLIgobIgdFDQAgBCAIIAobIhggB0ECdGohGSAAQRlqIRNBACEIIABBFGohFCAAQSBqIQ4gAEEQaiEPIAxByAxqIRogAEEcaiEbA0ACQCAAKAIAIgRFDQAgGCgCACELQQAhCgNAIA4oAgAgFCgCACIHIAdBgAhLIgcbIgkgCiAPKAIAIAtsaiINTQ0EIBEoAgAgGigCACIJIAlBgAhLIgkbIhwgCiAIIAwoAsQMbGoiAU0NBSASKAIAIBAgCRsgAWogGygCACATIAcbIA1qLQAAOgAAIApBAWoiCiAESQ0ACwsgCEEBaiEIIBhBBGoiGCAZRw0ACwsgDEHgHGogDEHADGoQASAMLQDsHEECRg0FIAxB0BRqIAxB4BxqQZAIEEYaQZgIQQQQbCIKRQ0GIApCgYCAgBA3AgAgCkEIaiAMQdAUakGQCBBGGiAMIAo2AuAcIBUgFiAXIAxB4BxqECZB/wFxIgdBAkcNBwJAIAxBwAxqQQhqKAIAIgdBgQhJDQAgDEHQDGooAgAgB0EBEGcLIAwoArgKIgdFDQkgByAHKAIAIg1Bf2o2AgAgDUEBRw0JIAxBuApqEEEMCQtBlLXEACANIAkQOgALQaS1xAAgASAcEDoAC0HQs8QAQQBBABA6AAtBgLTEACAKIAIQOgALEHIAC0GDgsAAQSsQNwALQZgIQQQQaQALQYOCwABBKyAHQQFxEDYACyAKQQEQaQALIAwgCjYCrAggAEEEaigCACEKIAxCADcD4BwCQCAKQSFJDQAgDEHgHGogChAlCyAMQbAIaiAMQeAcakGIAhBGGgJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAKAIAIgFFDQAgDEG4CGohCEEAIQoDQCAKIAJPDQMCQAJAIAMgCmotAABFDQAgCkEBaiIKIAFJDQIMAQsgDCgCrAgiB0EMaigCACINIApsIgkgDWoiBCAJSQ0JIAcoAhwgB0EQaigCACILIAtBgAhLIgsbIhAgBEkNCiAHKAIYIAdBFWogCxsgCWohBAJAIAxBsAhqQQxqKAIAIAwoArAIIgcgB0EgSyILGyIJIAdBICALGyILRw0AAkACQCALQQFqIgcgC0kNAEEAIQsCQCAHQQJJDQBBfyAHQX9qZ3YhCwsgC0EBaiIHIAtPDQELQX8hBwsgDEGwCGogBxAlIAwoArAIIQcLIAgoAgAhCyAMQbAIakEMQQAgB0EgSyIHG2ogCUEBajYCACALIAggBxsgCUEDdGoiByANNgIEIAcgBDYCACAKQQFqIgogAUkNAQsLIAAoAgAhCQwBC0EAIQkLIAxBiAJqQQhqIRMgDEEIaiESAkAgCUUNACAMQYgCakEMaigCACAMKAKIAiIKIApBIEsiChshASATKAIAIBMgChshCCAMQQxqKAIAIAwoAgAiCiAKQSBLIgobIQQgEigCACASIAobIQogDEGwCGpBDGooAgAgDCgCsAgiByAHQSBLIgcbIQsgDEGwCGpBCGoiDSgCACANIAcbIRBBACEHA0AgByAETw0DIAAgECALIAcgCigCACAKQQRqKAIAIAggARAJIApBCGohCiAHQQFqIg0hByANIAlJDQALCyAFDQwgAEEEaigCACEKIAxCADcD4BwCQCAKQSFJDQAgDEHgHGogChAlCyAMQbgKaiAMQeAcakGIAhBGGiAMQcAMaiAAEBECQCAAKAIAIgcgAEEIaigCACIBTw0AIAdBA3QhCiAMQbgKakEIaiEIIAxBwAxqQQhqIQQgDEHADGpBDGohFANAIAcgAk8NBgJAIAMgB2otAAANACAUKAIAIAwoAsAMIg0gDUEgSyINGyILIAcgACgCACIJayIQTQ0MIAQoAgAgBCANGyAJQQN0ayAKaiINKAIAIQsgDUEEaigCACEQAkAgDEG4CmpBDGooAgAgDCgCuAoiDSANQSBLIhEbIgkgDUEgIBEbIhFHDQACQAJAIBFBAWoiDSARSQ0AQQAhEQJAIA1BAkkNAEF/IA1Bf2pndiERCyARQQFqIg0gEU8NAQtBfyENCyAMQbgKaiANECUgDCgCuAohDQsgCCgCACERIAxBuApqQQxBACANQSBLIg0baiAJQQFqNgIAIBEgCCANGyAJQQN0aiINIBA2AgQgDSALNgIACyAKQQhqIQogB0EBaiIHIAFJDQALIAAoAgAhBwsgDEIANwPgHAJAIAdBIUkNACAMQeAcaiAHECUgACgCACEHCyAMQdAUaiAMQeAcakGIAhBGGgJAAkACQCAHRQ0AIAxB0BRqQQhqIQggDEGIAmpBDGohFEEAIRFBACEBQQAhCgNAIAogAk8NBgJAAkAgAyAKai0AAEUNACAMQQxqKAIAIAwoAgAiDSANQSBLIg0bIgkgAU0NDSAMQQhqKAIAIBIgDRsgAUEDdGohDSABQQFqIQEMAQsgFCgCACAMKAKIAiINIA1BIEsiDRsiCSARTQ0NIAxBiAJqQQhqKAIAIBMgDRsgEUEDdGohDSARQQFqIRELIApBAWohCiANKAIAIQQgDSgCBCELAkAgDEHQFGpBDGooAgAgDCgC0BQiDSANQSBLIhAbIgkgDUEgIBAbIhBHDQACQAJAIBBBAWoiDSAQSQ0AQQAhEAJAIA1BAkkNAEF/IA1Bf2pndiEQCyAQQQFqIg0gEE8NAQtBfyENCyAMQdAUaiANECUgDCgC0BQhDQsgCCgCACEQIAxB0BRqQQxBACANQSBLIg0baiAJQQFqNgIAIBAgCCANGyAJQQN0aiINIAs2AgQgDSAENgIAIAogB0kNAAsgDCgC0BQhCiAAKAIAIgINAQwCC0EAIQIgDCgC0BQhCkEARQ0BCyAMQZAEakEMaigCACAMKAKQBCIHIAdBIEsiBxshCSAMQZAEakEIaiINKAIAIA0gBxshASAMQdAUakEMaigCACAKIApBIEsiBxshAyAMQdAUakEIaiIKKAIAIAogBxshCiAMQbgKakEMaigCACAMKAK4CiIHIAdBIEsiBxshCCAMQbgKakEIaiINKAIAIA0gBxshBEEAIQcDQCAHIANPDQUgACAEIAggByAKKAIAIApBBGooAgAgASAJEAkgCkEIaiEKIAdBAWoiDSEHIA0gAkkNAAsgDCgC0BQhCgsCQAJAIApBIU8NACAMKALADCIKQSFPDQEMDAsgDEHYFGooAgAgCkEDdEEEEGcgDCgCwAwiCkEhSQ0LCyAMQcgMaigCACAKQQN0QQQQZyAMKAK4CiIKQSFPDQsMDAtBkLTEACAKIAIQOgALQeCzxAAgByAEEDoAC0GwtMQAIAogAhA6AAtB4LPEACAHIAMQOgALQaC0xAAgByACEDoACyAJIAQQOwALIAQgEBA5AAtBwLPEACABIAkQOgALQcCzxAAgESAJEDoAC0HAs8QAIBAgCxA6AAsgDCgCuAoiCkEhSQ0BCyAMQcAKaigCACAKQQN0QQQQZwsCQCAMKAKwCCIKQSFJDQAgDEG4CGooAgAgCkEDdEEEEGcLIAwoAqwIIgogCigCACIKQX9qNgIAAkACQAJAAkACQAJAAkACQAJAAkACQCAKQQFGDQBBISEKIAwoAqAHIgdBIU8NAQwCCyAMQawIahBBQSEhCiAMKAKgByIHQSFJDQELIAxBqAdqKAIAIAdBAnRBBBBnIAwoApgGIgcgCkkNAQwCCyAMKAKYBiIHIApPDQELQSEhCiAMKAKQBCIHQSFPDQEMAgsgDEGgBmooAgAgB0ECdEEEEGdBISEKIAwoApAEIgdBIUkNAQsgDEGYBGooAgAgB0EDdEEEEGcgDCgCiAIiByAKSQ0BDAILIAwoAogCIgcgCk8NAQsgDCgCACIKQSFJDQIMAQsgDEGQAmooAgAgB0EDdEEEEGcgDCgCACIKQSFJDQELIAxBCGooAgAgCkEDdEEEEGcLQQ0hBwsgBkHwJGokACAHC8cWATh/IwBBsCBrIgIkAAJAAkACQAJAAkACQAJAIAEoAgAiAyABKAIERw0AIAJBkAhqIAMQFCABKAIAIgQgAigCkAhHDQEgAigClAggAUEEaigCAGoiBSAEbCIGQX9MDQICQAJAAkAgBkUNAEEBIQcgBkEBEG0iCEUNBiAGIQkgBkGACE0NAQwCC0EBIQgLIAJBoBBqIAggBhBGGiACQawgakECaiACQaAQakECai0AADoAACACIAIvAKAQOwGsICACKACjECEKIAIoAKcQIQkgAkGwGGogAkGrEGpB+AcQRhpBACEHAkAgBkUNACAIIAZBARBnCyAKIQgLIAJBrBBqIAc6AAAgAkGgEGpBDWoiCyACLwGsIDsAACACQaAQakEUaiIMIAk2AgAgAkGgEGpBEGoiDSAINgIAIAJBrxBqIAJBriBqLQAAOgAAIAIgBjYCqBAgAiAFNgKkECACIAQ2AqAQIAJBuBBqIAJBsBhqQfgHEEYaIAEoAgAiDkUNBCABQQ1qIQ8gAkGQCGpBDWohEEEAIRFBASESIAFBBGohE0EIIRQgAkGQCGpBCGohFUGACCEWIAJBkAhqQRRqIRdBACEYDAULQYyIwABBJEH0tcQAEE0ACyACQbwYakEYNgIAIAJBtBBqQQI2AgAgAkEYNgK0GCACIAE2ArAYIAJCAjcCpBAgAkHUtcQANgKgECACIAJBkAhqNgK4GCACIAJBsBhqNgKwECACQaAQakHktcQAED8ACxByAAsgBkEBEGkAC0EAIQYMAQtBASEGCwNAAkACQAJAAkACQAJAAkACQAJAAkAgBg4CAAEBCwJAIAIgAkGgEGpBkAgQRiIGKAKYCCIIQYEISQ0AIAZBoAhqKAIAIAhBARBnCyAGKAIAIhtFDQUgBkENaiEcQQAhHUEBIR5BCCEfIAZBCGohIEGACCEhIAZBFGohIiAGQRBqISNBtpHAACEkQbiLwAAhJUH/ASEmQf4DISdBuI3AACEoQQEhKUEAISpBASEYDAELAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgGA4DAAECAgtBACEGAkAgEygCACIFRQ0AQQAhCCAFIQYDQCABQRRqKAIAIAEgFGooAgAiBCAEIBZLIgQbIgcgCCARIAZsaiIGTQ0FIAwoAgAgAkGgEGogFGooAgAiByAHIBZLIgcbIgogCCARIAIoAqQQbGoiCU0NBiANKAIAIAsgBxsgCWogAUEQaigCACAPIAQbIAZqLQAAOgAAIBMoAgAhBiAIIBJqIgggBUkNAAsLAkAgAigClAgiGUUNACAXKAIAIBUoAgAiCCAIIBZLIgUbIhogGSARbCIKTQ0LQQEhBEEAIQgDQCAMKAIAIAJBoBBqIBRqKAIAIgcgByAWSyIHGyIaIAYgCGogESACKAKkEGwiCWpNDQcgDSgCACALIAcbIAZqIAggCWpqIAJBkAhqQRBqKAIAIBAgBRsgCmotAAA6AAAgCCASaiIHIBlPDQEgAigClAggEWwiCSAEaiEKIAchCCAEIBJqIQQgFygCACAVKAIAIgUgBSAWSyIFGyIaIAkgB2oiB0sNAAwNCwsgESASaiIRIA5JDRFBACEGDBoLICIoAgAiKyAgKAIAIiwgLCAhSyIKGyIJIAIoAgQiBCAqbCItICpqIhhNDQsCQCAjKAIAIBwgChsiGSAYai0AAA0AIAQgKmwhCCAqIAQgKWxqIQZBASEHIAIoAgAhGgNAICogB2ogGk8NASAJIAZNDQcgCCAEaiEIIAcgHmohByAZIAZqIQUgBiAEaiEGIAUtAABFDQALIARFDQAgByAeRg0AIAkgLU0NCSAEICpsIQVBACEGA0AgCSAIIAZqIgdNDQggIygCACAcIAobIgkgBWogBmoiCi0AACEZIAogCSAIaiAGai0AADoAACAiKAIAICAoAgAiCSAJICFLIgkbIgogB00NCSAjKAIAIBwgCRsgCGogBmogGToAAAJAIAYgHmoiByAETw0AIAchBiAiKAIAICAoAgAiCSAJICFLIgobIgkgBSAHaiItSw0BDAsLCyACKAIEIgQgKmwgKmohGCAiKAIAISsgICgCACEsCyArICwgLCAhSyIHGyIKIBhNDQwCQCAjKAIAIgggHCAHGyAYai0AACIGIB5GDQAgBkUNAiAGICVqLQAAIgYgJnMgHSAGayAGGyIGICdPDQ4gBEUNACAKIAQgKmwiCU0NDyAGIChqLQAAIRlBASEIQQAhBgNAICMoAgAgHCAHGyAJaiIHIActAAAgH3QgGXIgJGotAAA6AAAgBiAeaiIGIARPDQEgAigCBCAqbCIFIAhqIQkgCCAeaiEIICIoAgAgICgCACIHIAcgIUsiBxsiCiAFIAZqIgVLDQAMEQsLICogHmoiLSACKAIAIixPDRQgLSEuQQAhBgwSCyAxRQ0SQQAhOUEBIQYMEQsgAEECOgAMICxBgQhJDRQgCCAsQQEQZwwUC0GUtcQAIAYgBxA6AAtBpLXEACAJIAoQOgALQaS1xAAgCSAGaiAIaiAaEDoAC0GUtcQAIAYgCRA6AAtBlLXEACAHIAkQOgALQaS1xAAgByAKEDoAC0GUtcQAIC0gCRA6AAsgCiEHC0GUtcQAIAcgGhA6AAtBlLXEACAYIAkQOgALQZS1xAAgGCAKEDoAC0GUtsQAIAZB/gMQOgALIAkhBQtBlLXEACAFIAoQOgALQQAhGEEBIQYMCAtBASEGDAcLA0ACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgBg4CAAEBCyAiKAIAICAoAgAiBiAGICFLIgQbIgcgAigCBCIZIC5sICpqIgZNDQMCQCAjKAIAIBwgBBsgBmotAAAiGkUNACAZRQ0AIAcgGSAqbCIJTQ0GQQEhCEEAIQYgGSEFA0AgByAGIC4gBWxqIgVNDQMgIygCACAcIAQbIgQgBWoiByAHLQAAIBogH3QgBCAJai0AAHIgJGotAABzOgAAIAYgHmoiBiAZTw0BIAIoAgQiBSAqbCIKIAhqIQkgCCAeaiEIICIoAgAgICgCACIEIAQgIUsiBBsiByAKIAZqIgpLDQAMCAsLIC4gHmoiLiAsSQ0JDA0LIDYoAgAgNCgCACIGIAYgNUsiBBsiByACKAIEIhkgOWwgMWoiBk0NAwJAIDcoAgAgMCAEGyAGai0AACIaRQ0AIBlFDQAgByAZIDFsIglNDQdBASEIQQAhBiAZIQUDQCAHIAYgOSAFbGoiBU0NAyA3KAIAIDAgBBsiBCAFaiIHIActAAAgGiAzdCAEIAlqLQAAciA4ai0AAHM6AAAgBiAyaiIGIBlPDQEgAigCBCIFIDFsIgogCGohCSAIIDJqIQggNigCACA0KAIAIgQgBCA1SyIEGyIHIAogBmoiCksNAAwJCwsgOSAyaiI5IDFJDQkMCwtBpLXEACAFIAcQOgALQaS1xAAgBSAHEDoAC0GUtcQAIAYgBxA6AAtBlLXEACAGIAcQOgALIAkhCgtBlLXEACAKIAcQOgALIAkhCgtBlLXEACAKIAcQOgALQQAhBgwBC0EBIQYMAAsLIDEgMmoiMSAvTw0BQQIhGEEBIQYMBQsgKSAeaiEpIC0hKiAtIBtJDQIgAigCACIvRQ0AIAJBDWohMEEAITFBASEyQQghMyACQQhqITRBgAghNSACQRRqITYgAkEQaiE3QbaRwAAhOEECIRgMAwsgACACQQAgAyADIANBAXQQDiACKAIIIgZBgQhJDQAgAkEQaigCACAGQQEQZyACQbAgaiQADwsgAkGwIGokAA8LQQEhGEEBIQYMAQtBASEGDAALC/oKAg9/AX4jAEEgayIDJABBASEEAkAgAigCGEEiIAJBHGooAgAoAhARAAANAAJAAkAgAUUNACAAIAFqIQUgAkEYaiEGIAJBHGohByAAIQhBACEJQQAhCgJAA0AgCCELIAhBAWohDAJAAkAgCCwAACINQQBIDQAgDUH/AXEhDSAMIQgMAQsCQAJAIAwgBUYNACAMLQAAQT9xIQ4gCEECaiIIIQwMAQtBACEOIAUhCAsgDUEfcSEPAkACQAJAIA1B/wFxIg1B4AFJDQAgCCAFRg0BIAgtAABBP3EhECAIQQFqIgwhEQwCCyAOIA9BBnRyIQ0gDCEIDAILQQAhECAFIRELIBAgDkEGdHIhDgJAAkACQCANQfABSQ0AIBEgBUYNASARQQFqIQggES0AAEE/cSENDAILIA4gD0EMdHIhDSAMIQgMAgtBACENIAwhCAsgDkEGdCAPQRJ0QYCA8ABxciANciINQYCAxABGDQILQQIhDAJAAkACQAJAAkACQAJAAkACQCANQXdqIg9BHksNAEH0ACEOAkAgDw4fCAADAwQDAwMDAwMDAwMDAwMDAwMDAwMDAwIDAwMDAggLQe4AIQ4MBAsgDUHcAEcNAQsgDSEODAULQaC7xAAgDRAhRQ0CDAMLQfIAIQ4LDAILAkAgDUH//wNLDQAgDUGgm8QAQShB8JvEAEGvAkGfnsQAQbwCEBdFDQEMAwsCQCANQf//B0sNACANQdugxABBIUGdocQAQZ4BQbuixABB/QIQF0UNAQwDCyANQe+DOEsNACANQeKLdGpB4o0sSQ0AIA1Bn6h0akGfGEkNACANQd7idGpBDkkNACANQf7//wBxQZ7wCkYNACANQamydWpBKUkNACANQcuRdWpBCksNAgsgDUEBcmdBAnZBB3OtQoCAgIDQAIQhEkEDIQwgDSEOCyADIAE2AgQgAyAANgIAIAMgCTYCCCADIAo2AgwCQCAKIAlJDQACQCAJRQ0AIAkgAUYNACAJIAFPDQEgACAJaiwAAEG/f0wNAQsCQCAKRQ0AIAogAUYNACAKIAFPDQEgACAKaiwAAEG/f0wNAQsCQCAGKAIAIAAgCWogCiAJayAHKAIAKAIMEQYADQADQAJAAkACQAJAAkACQAJAIAxBAUYNAEHcACEJAkAgDEECRg0AIAxBA0cNBiASQiCIp0H/AXFBf2oiDEEESw0GAkAgDA4FAAYEBQMACyASQv////+PYIMhEkEDIQxB/QAhCQwHC0EBIQwMBgtBACEMIA4hCQwFCyASQv////+PYINCgICAgMAAhCESQQMhDAwECyASQv////+PYINCgICAgCCEIRJBAyEMQfsAIQkMAwsgEkL/////j2CDQoCAgIAwhCESQQMhDEH1ACEJDAILIA4gEqciD0ECdEEccXZBD3EiDEEwciAMQdcAaiAMQQpJGyEJAkAgD0UNACASQn98Qv////8PgyASQoCAgIBwg4QhEkEDIQwMAgsgEkL/////j2CDQoCAgIAQhCESQQMhDAwBC0EBIQwCQCANQYABSQ0AQQIhDCANQYAQSQ0AQQNBBCANQYCABEkbIQwLIAwgCmohCQwECyAGKAIAIAkgBygCACgCEBEAAEUNAAsLQQEhBAwGCyADIANBDGo2AhggAyADQQhqNgIUIAMgAzYCECADQRBqEFMACyAKIAtrIAhqIQogBSAIRw0ACwsgCUUNASAJIAFGDQECQCAJIAFPDQAgACAJaiwAAEG/f0oNAgsgACABIAkgARAEAAtBACEJCyACQRhqIgwoAgAgACAJaiABIAlrIAJBHGoiCigCACgCDBEGAA0AIAwoAgBBIiAKKAIAKAIQEQAAIQQLIANBIGokACAEC5wJAQp/IwBBwABrIgMkACADQSRqIAE2AgAgA0E0aiACQRRqKAIAIgQ2AgAgA0EDOgA4IANBLGogAigCECIFIARBA3RqNgIAIANCgICAgIAENwMIIAMgADYCIEEAIQYgA0EANgIYIANBADYCECADIAU2AjAgAyAFNgIoAkACQAJAAkACQCACKAIIIgdFDQAgAigCACEIIAIoAgQiCSACQQxqKAIAIgUgBSAJSxsiCkUNASAAIAgoAgAgCCgCBCABKAIMEQYADQIgCEEMaiEFIANBOGohASADQTRqIQsgA0Ew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QZeVxABBEBBKDAoLIAIgAUGGlcQAQREQSgwJCyACIAFB9JTEAEESEEoMCAsgAiABQeGUxABBExBKDAcLIAIgAUHPlMQAQRIQSgwGCyACIAFBvJTEAEETEEoMBQsgAiABQaqUxABBEhBKDAQLIAIgAUGXlMQAQRMQSgwDCyACIAFBjZTEAEEKEEoMAgsgAiABQfyTxABBERBKDAELIAIgAUHwk8QAQQwQSgsgAhArIQEgAkEQaiQAIAEL+QEBAn8jAEEQayIEJAAgBCABKAIAIgUoAgA2AgwCQAJAAkAgAkECaiICIAJsIgJBgBAgAkGAEEsbIgFBBCAEQQxqQYOCwABBwLLEABAMIgJFDQAgBSAEKAIMNgIADAELIARBg4LAACABQQQQMgJAAkAgBCgCAEUNACAFIAQoAgw2AgAMAQsgBCgCBCICIAQoAgw2AgggBCACNgIMIAFBBCAEQQxqQYOCwABBwLLEABAMIQIgBSAEKAIMNgIAIAINAQtBASEBDAELIAJCADcCBCACIAIgAUECdGpBAnI2AgBBACEBCyAAIAI2AgQgACABNgIAIARBEGokAAvmAQEEfyMAQTBrIgIkACABQQRqIQMCQCABKAIEDQAgASgCACEEIAJBADYCECACQgE3AwggAiACQQhqNgIUIAJBGGpBEGogBEEQaikCADcDACACQRhqQQhqIgUgBEEIaikCADcDACACIAQpAgA3AxggAkEUakG0t8QAIAJBGGoQAxogBSACKAIQNgIAIAIgAikDCDcDGAJAIAMoAgAiBEUNACABQQhqKAIAIgFFDQAgBCABQQEQZwsgAyACKQMYNwIAIANBCGogBSgCADYCAAsgAEHwt8QANgIEIAAgAzYCACACQTBqJAAL0wEBA38gAC0ACCEBAkAgACgCBCICRQ0AIAFB/wFxIQNBASEBAkAgAw0AAkAgACgCACIDLQAAQQRxRQ0AQQEhASADKAIYQd2axABBASADQRxqKAIAKAIMEQYADQEgAEEEaigCACECCwJAIAJBAUcNACAALQAJRQ0AQQEhASAAKAIAIgMoAhhB3JrEAEEBIANBHGooAgAoAgwRBgANAQsgACgCACIBKAIYQd6axABBASABQRxqKAIAKAIMEQYAIQELIABBCGogAToAAAsgAUH/AXFBAEcLuAEBAX8jAEEQayIEJAACQAJAIAFFDQAgBCABNgIEIAJFDQAgA0EESw0BIAJBA2pBAnZBf2oiAUH/AUsNASAAIAFBAnRqQQRqIgFFDQEgBCAANgIIIAQgASgCADYCDCAEQQRqIARBDGogBEEIakHwssQAEB8gASAEKAIMNgIACyAEQRBqJAAPCyAEIAAoAgA2AgwgBEEEaiAEQQxqQYOCwABB2LLEABAfIAAgBCgCDDYCACAEQRBqJAALjwEBA38jAEGAAWsiAiQAIAAoAgAhA0EAIQADQCACIABqQf8AaiADQQ9xIgRBMHIgBEHXAGogBEEKSRs6AAAgAEF/aiEAIANBBHYiAw0ACwJAIABBgAFqIgNBgQFPDQAgAUEBQZKZxABBAiACIABqQYABakEAIABrEAYhACACQYABaiQAIAAPCyADQYABEDsAC44BAQN/IwBBgAFrIgIkACAAKAIAIQNBACEAA0AgAiAAakH/AGogA0EPcSIEQTByIARBN2ogBEEKSRs6AAAgAEF/aiEAIANBBHYiAw0ACwJAIABBgAFqIgNBgQFPDQAgAUEBQZKZxABBAiACIABqQYABakEAIABrEAYhACACQYABaiQAIAAPCyADQYABEDsAC4sBAQV/AkAgACgCCCIBRQ0AIAAoAgAhAiABQQR0IQEDQAJAIAJBBGoiAygCAEUNAAJAIAIoAgAiBEUNACAEIAQoAgAiBUF/ajYCACAFQQFHDQAgAhBACyADEC8LIAJBEGohAiABQXBqIgENAAsLAkAgAEEEaigCACICRQ0AIAAoAgAgAkEEdEEEEGcLC4sBAQV/AkAgACgCCCIBRQ0AIAAoAgAhAiABQQR0IQEDQAJAIAJBBGoiAygCAEUNAAJAIAIoAgAiBEUNACAEIAQoAgAiBUF/ajYCACAFQQFHDQAgAhBBCyADEDALIAJBEGohAiABQXBqIgENAAsLAkAgAEEEaigCACICRQ0AIAAoAgAgAkEEdEEEEGcLC4cBAQJ/AkAgACgCBCICIAAoAggiA2sgAU8NAAJAAkAgAyABaiIBIANJDQAgAkEBdCIDIAEgASADSRsiAUEASA0AAkACQCACRQ0AIAAoAgAgAkEBIAEQYiICRQ0BDAMLIAFBARBsIgINAgsgAUEBEGkACxBvAAsgACACNgIAIABBBGogATYCAAsLcgACQEEAIAJBAnQiAiADQQN0QYCAAWoiAyADIAJJG0GHgARqIgJBEHZAACIDQRB0IANBf0YbIgNFDQAgA0IANwIEIAMgAyACQYCAfHFqQQJyNgIAIAAgAzYCBCAAQQA2AgAPCyAAIAM2AgQgAEEBNgIAC4EBAQF/IwBBwABrIgQkACAEIAE2AgwgBCAANgIIIAQgAzoAFCAEIAI2AhAgBEE8akERNgIAIARBLGpBAjYCACAEQQ82AjQgBEICNwIcIARBwLTEADYCGCAEIARBEGo2AjggBCAEQQhqNgIwIAQgBEEwajYCKCAEQRhqQdC0xAAQRAALewEBfyMAQTBrIgIkACACQRRqQSo2AgAgAkEqNgIMIAIgADYCCCACIABBBGo2AhAgAUEcaigCACEAIAEoAhghASACQSxqQQI2AgAgAkICNwIcIAJBmLjEADYCGCACIAJBCGo2AiggASAAIAJBGGoQAyEBIAJBMGokACABC3oBAX8jAEHAAGsiAyQAIAMgATYCDCADIAA2AgggAyACOgAXIANBPGpBATYCACADQSxqQQI2AgAgA0ECNgI0IANCAjcCHCADQaCyxAA2AhggAyADQRdqNgI4IAMgA0EIajYCMCADIANBMGo2AiggA0EYakGwssQAEEQAC3oBAX8jAEHAAGsiAyQAIAMgATYCDCADIAA2AgggAyACOgAXIANBPGpBDjYCACADQSxqQQI2AgAgA0EPNgI0IANCAjcCHCADQcC0xAA2AhggAyADQRdqNgI4IAMgA0EIajYCMCADIANBMGo2AiggA0EYakHQtMQAEEQAC3MBAX8jAEHAAGsiAiQAIAIgATYCDCACIAA2AgggAkE0akEQNgIAIAJBJGpBAjYCACACQQ82AiwgAkICNwIUIAJBwLTEADYCECACIAJBOGo2AjAgAiACQQhqNgIoIAIgAkEoajYCICACQRBqQdC0xAAQRAALcAIEfwF+IwBBMGsiASQAIAAQcBBZIQIgABBzEFohAyABQQhqIAIQaiABKQMIIQUgAhB0IQQgASACEHU2AhwgASAENgIYIAEgBTcDECABQQA2AiQgASADNgIgIAFBIGpB3LfEACAAEHMgAUEQahAnAAtvAQF/IwBBMGsiAiQAIAIgATYCBCACIAA2AgAgAkEsakEYNgIAIAJBHGpBAjYCACACQRg2AiQgAkICNwIMIAJB4LjEADYCCCACIAJBBGo2AiggAiACNgIgIAIgAkEgajYCGCACQQhqQfC4xAAQRAALbAEBfyMAQTBrIgMkACADIAI2AgQgAyABNgIAIANBLGpBGDYCACADQRxqQQI2AgAgA0EYNgIkIANCAjcCDCADQbi4xAA2AgggAyADNgIoIAMgA0EEajYCICADIANBIGo2AhggA0EIaiAAEEQAC28BAX8jAEEwayICJAAgAiABNgIEIAIgADYCACACQSxqQRg2AgAgAkEcakECNgIAIAJBGDYCJCACQgI3AgwgAkGAucQANgIIIAIgAkEEajYCKCACIAI2AiAgAiACQSBqNgIYIAJBCGpBkLnEABBEAAtjAQF/IwBBIGsiAiQAIAIgACgCADYCBCACQQhqQRBqIAFBEGopAgA3AwAgAkEIakEIaiABQQhqKQIANwMAIAIgASkCADcDCCACQQRqQbS3xAAgAkEIahADIQEgAkEgaiQAIAELaAIBfwN+IwBBMGsiASQAIAApAgghAiAAKQIQIQMgACkCACEEIAFBFGpBADYCACABIAQ3AxggAUGolsQANgIQIAFCATcCBCABIAFBGGo2AgAgASADNwMoIAEgAjcDICABIAFBIGoQRAALaAECfyABKAIAIQIgAUEANgIAAkACQCACRQ0AIAEoAgQhA0EIQQQQbCIBRQ0BIAEgAzYCBCABIAI2AgAgAEH0tMQANgIEIAAgATYCAA8LIABBhLXEADYCBCAAQQE2AgAPC0EIQQQQaQALYgEBfyMAQTBrIgIkACACQSBqIAEoAgAgASgCBCABKAIIIAEoAgwQVCACQRRqIAJBKGopAwA3AgAgAiAANgIIIAJBzLfEADYCBCACQcCVxAA2AgAgAiACKQMgNwIMIAIQOAALVgECfwJAIAAoAgAiAUEQaigCACICQYEISQ0AIAFBGGooAgAgAkEBEGcgACgCACEBCyABIAEoAgQiAkF/ajYCBAJAIAJBAUcNACAAKAIAQZgIQQQQZwsLVgECfwJAIAAoAgAiAUEQaigCACICQYEISQ0AIAFBGGooAgAgAkEBEGcgACgCACEBCyABIAEoAgQiAkF/ajYCBAJAIAJBAUcNACAAKAIAQZgIQQQQZwsLVQEBfwJAAkACQCABQYCAxABGDQBBASEEIAAoAhggASAAQRxqKAIAKAIQEQAADQELIAJFDQEgACgCGCACIAMgAEEcaigCACgCDBEGACEECyAEDwtBAAtIAQF/IwBBEGsiAiQAAkACQCAALQAAQQFHDQAgAiABQd2TxABBCRBKDAELIAIgAUHmk8QAQQoQSgsgAhArIQEgAkEQaiQAIAELSgIBfwF+IwBBIGsiAiQAIAEpAgAhAyACQRRqIAEpAgg3AgAgAiADNwIMIAIgADYCCCACQai4xAA2AgQgAkGolsQANgIAIAIQbgALLgACQCAAQXxLDQACQCAARQ0AIAAgAEF9SUECdBBsIgBFDQEgAA8LQQQPCxBxAAs2AQF/AkAgAkUNACAAIQMDQCADIAEtAAA6AAAgA0EBaiEDIAFBAWohASACQX9qIgINAAsLIAALNwEBfwJAQZjHxAAgAyACEBAiBEUNACAEIAAgAyABIAEgA0sbEEYaQZjHxAAgACABIAIQLAsgBAsxACAAKAIAIQACQCABEF9FDQAgACABEC0PCwJAIAEQYEUNACAAIAEQLg8LIAAgARBkCzwBAX9BACEAAkACQEEAKALIz0RBAUcNAEEAKALMz0QhAAwBC0EAQgE3A8jPRAtBACAANgLMz0QgAEEARws0ACAAIAEoAhggAiADIAFBHGooAgAoAgwRBgA6AAggACABNgIAIAAgA0U6AAkgAEEANgIECy8BAX8gACgCACIAIAIQMSAAIAAoAggiAyACajYCCCADIAAoAgBqIAEgAhBGGkEACywBAX8CQCACRQ0AIAAhAwNAIAMgAToAACADQQFqIQMgAkF/aiICDQALCyAACywBAX8jAEEQayIDJAAgAyABNgIMIAMgADYCCCADQQhqQeC0xABBACACECcACykBAX8jAEEQayICJAAgAiABQbCIwABBDhBKIAIQKyEBIAJBEGokACABCyYBAX8CQCAAKAIEIgFFDQAgAEEIaigCACIARQ0AIAEgAEEBEGcLCyUBAX8jAEEQayICJAAgAiABNgIMIAIgADYCCCACQQhqEIIBGgALIAACQEGYx8QAIAAgARAQIgFFDQAgAUEAIAAQTBoLIAELKgEBfyAAQfS0xABBhLXEACABKAIAIgIbNgIEIAAgAUHDhcAAIAIbNgIACyYBAX8gACgCACIBKAIAIAEoAgQgACgCBCgCACAAKAIIKAIAEAQACx4AIAAgBDYCDCAAIAM2AgggACACNgIEIAAgATYCAAsaACAAQgA3AgQgAEEENgIAIABBDGpCADcCAAscAQF/AkAgACgCBCIBRQ0AIAAoAgAgAUEBEGcLCxoBAX8gACABQQAoArjPRCICQRogAhsRBQAACxQAIAAgASACIAMgBEEBEABB/wFxCxUAAkAgAEUNACAADwtBnLfEABA9AAsVAAJAIABFDQAgAA8LQZy3xAAQPQALEgACQCABRQ0AIAAgAUEEEGcLCxAAIAAoAgAgACgCBCABEGsLEAAgACgCACAAKAIEIAEQawsQACABIAAoAgAgACgCBBAFCw0AIAAtAABBEHFBBHYLDQAgAC0AAEEgcUEFdgsPAEGYx8QAIAAgASACECwLDAAgACABIAIgAxBHCw4AIAAgASACQYCAAhATCw0AIAA1AgBBASABEBwLDQAgADUCAEEBIAEQHAsNAEGYx8QAIAAgARAQCwoAIAAgASACEGELDQBBw4XAAEEZIAEQAgsJACAAIAEQVwALDAAgACABKQIANwIACwoAIAIgACABEAULCAAgACABEGYLCAAgACABEFELBwAgABA4AAsKAEGAuMQAED0ACwcAIABBDGoLBQAQfwALBQAQbwALBwAgACgCCAsHACAAKAIICwcAIAAoAgwLBAAgAQsEAEEACwUAQYAECwQAQQELBwBBnM/EAAsMAELkrsKFl5uliBELDQBChJbbgd3goOPoAAsNAELNp7n04KW6rJV/Cw0AQs2ytoWB2Ij99wALAwAACwQAQQALBABBAAsDAAALDQBCzae59OCluqyVfwsCAAsCAAsCAAsCAAsCAAsCAAsCAAsCAAsCAAsL7c+EgAADAEGAgMAAC8CxBGNhbGxlZCBgUmVzdWx0Ojp1bndyYXAoKWAgb24gYW4gYEVycmAgdmFsdWVhc3NlcnRpb24gZmFpbGVkOiBtaWQgPD0gbGVuc3JjL2xpYmNvcmUvc2xpY2UvbW9kLnJzYXNzZXJ0aW9uIGZhaWxlZDogY2h1bmtfc2l6ZSAhPSAwc3JjL2xpYi5ycwAAAAAAAGF0dGVtcHQgdG8gZGl2aWRlIGJ5IHplcm8AAAAJAAAACgAAAAsAAAAMAAAADQAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAAOiBzcmMvbGliY29yZS9yZXN1bHQucnNjYWxsZWQgYFJlc3VsdDo6dW53cmFwKClgIG9uIGFuIGBFcnJgIHZhbHVlYXNzZXJ0aW9uIGZhaWxlZDogY2h1bmtfc2l6ZSAhPSAwc3JjL2xpYmNvcmUvc2xpY2UvbW9kLnJzYXNzZXJ0aW9uIGZhaWxlZDogbWlkIDw9IGxlbgAAAAAAAAAAAAAAAAAvaG9tZS9uYXphci1wYy8uY2FyZ28vcmVnaXN0cnkvc3JjL2dpdGh1Yi5jb20tMWVjYzYyOTlkYjllYzgyMy9zbWFsbHZlYy0wLjYuMTAvbGliLnJzAAAAAAAAAAAAAAAvaG9tZS9uYXphci1wYy8uY2FyZ28vZ2l0L2NoZWNrb3V0cy9yZWVkLXNvbG9tb24tZXJhc3VyZS0wNTcwOWMwMGRlZjE0NGQwLzg1ZjhkY2Ivc3JjL21hY3Jvcy5ycwAvaG9tZS9uYXphci1wYy8uY2FyZ28vZ2l0L2NoZWNrb3V0cy9yZWVkLXNvbG9tb24tZXJhc3VyZS0wNTcwOWMwMGRlZjE0NGQwLzg1ZjhkY2Ivc3JjL2xpYi5yczogc3JjL2xpYmNvcmUvcmVzdWx0LnJzUG9pc29uRXJyb3IgeyBpbm5lcjogLi4gfQAAAAAvaG9tZS9uYXphci1wYy8uY2FyZ28vcmVnaXN0cnkvc3JjL2dpdGh1Yi5jb20tMWVjYzYyOTlkYjllYzgyMy9zbWFsbHZlYy0wLjYuMTAvbGliLnJzQ29sb21uIGNvdW50IG9uIGxlZnQgaXMgZGlmZmVyZW50IGZyb20gcm93IGNvdW50IG9uIHJpZ2h0LCBsaHMgOiAsIHJocyA6IC9ob21lL25hemFyLXBjLy5jYXJnby9naXQvY2hlY2tvdXRzL3JlZWQtc29sb21vbi1lcmFzdXJlLTA1NzA5YzAwZGVmMTQ0ZDAvODVmOGRjYi9zcmMvbWF0cml4LnJzTWF0cmljZXMgZG8gbm90IGhhdmUgdGhlIHNhbWUgcm93IGNvdW50LCBsaHMgOiBUcnlpbmcgdG8gaW52ZXJ0IGEgbm9uLXNxdWFyZSBtYXRyaXhTaW5ndWxhck1hdHJpeC9ob21lL25hemFyLXBjLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL3NtYWxsdmVjLTAuNi4xMC9saWIucnNh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YnN0ZC9zeXMvd2FzbS9tdXRleC5yc2Nhbm5vdCByZWN1cnNpdmVseSBhY3F1aXJlIG11dGV4Y2FsbGVkIGBSZXN1bHQ6OnVud3JhcCgpYCBvbiBhbiBgRXJyYCB2YWx1ZQAAAC9ydXN0Yy85MTg1NmVkNTJjNThhYTViYTY2YTAxNTM1NGQxY2M2OWU5Nzc5YmRmL3NyYy9saWJjb3JlL3NsaWNlL21vZC5ycy9ob21lL25hemFyLXBjLy5jYXJnby9naXQvY2hlY2tvdXRzL3JlZWQtc29sb21vbi1lcmFzdXJlLTA1NzA5YzAwZGVmMTQ0ZDAvODVmOGRjYi9zcmMvaW52ZXJzaW9uX3RyZWUucnNleHBsaWNpdCBwYW5pY05vdFNxdWFyZUFscmVhZHlTZXRJbnZhbGlkSW5kZXhJbnZhbGlkU2hhcmRGbGFnc0VtcHR5U2hhcmRUb29GZXdTaGFyZHNQcmVzZW50SW5jb3JyZWN0U2hhcmRTaXplVG9vTWFueUJ1ZmZlclNoYXJkc1Rvb0Zld0J1ZmZlclNoYXJkc1Rvb01hbnlQYXJpdHlTaGFyZHNUb29GZXdQYXJpdHlTaGFyZHNUb29NYW55RGF0YVNoYXJkc1Rvb0Zld0RhdGFTaGFyZHNUb29NYW55U2hhcmRzVG9vRmV3U2hhcmRzY2FsbGVkIGBPcHRpb246OnVud3JhcCgpYCBvbiBhIGBOb25lYCB2YWx1ZXNyYy9saWJjb3JlL29wdGlvbi5yc3NyYy9saWJhbGxvYy9yYXdfdmVjLnJzY2FwYWNpdHkgb3ZlcmZsb3dgLi5pbmRleCBvdXQgb2YgYm91bmRzOiB0aGUgbGVuIGlzICBidXQgdGhlIGluZGV4IGlzIGNhbGxlZCBgT3B0aW9uOjp1bndyYXAoKWAgb24gYSBgTm9uZWAgdmFsdWVzcmMvbGliY29yZS9vcHRpb24ucnNzcmMvbGliY29yZS9zbGljZS9tb2QucnNpbmRleCAgb3V0IG9mIHJhbmdlIGZvciBzbGljZSBvZiBsZW5ndGggc2xpY2UgaW5kZXggc3RhcnRzIGF0ICBidXQgZW5kcyBhdCBzcmMvbGliY29yZS9zdHIvbW9kLnJzWy4uLl1ieXRlIGluZGV4ICBpcyBvdXQgb2YgYm91bmRzIG9mIGBiZWdp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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v////+/tgAAAAAAAAAAAP8HAAAAAAD4//8AAAEAAAAAAAAAAAAAAMCfnz0AAAAAAgAAAP///wcAAAAAAAAAAAAAwP8BAAAAAAAA+A8guBIRAEoAAAAIFREAAAIAAAgXEQA3AAAAAAECAwQFBgcICQgKCwwNDg8QERITFAIVFhcYGRobHB0eHyACAgICAgICAgICIQICAgICAgICAgICAgICIiMkJSYCJwIoAgICKSorAiwtLi8wAgIxAgICMgICAgICAgICMwICNAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNQI2AjcCAgICAgICAjgCOQICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICOjs8AgICAj0CAj4/QEFCQ0RFRgICAkcCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICSAICAgICAgICAgICSQICAgICOwIAAQICAgIDAgICAgQCBQYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAEGYx8QAC7gIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPu/gIAABG5hbWUB8L+AgACNAQBKcmVlZF9zb2xvbW9uX2VyYXN1cmU6OlJlZWRTb2xvbW9uOjpyZWNvbnN0cnVjdF9pbnRlcm5hbDo6aGQ0MzhhY2JhNTQ1NzJiMzABP3JlZWRfc29sb21vbl9lcmFzdXJlOjptYXRyaXg6Ok1hdHJpeDo6aW52ZXJ0OjpoMThhNmNmZGNkNTJkYjA2ZgIxPHN0ciBhcyBjb3JlOjpmbXQ6OkRlYnVnPjo6Zm10OjpoZTExOWRiMWJmYWMxOGM2NwMjY29yZTo6Zm10Ojp3cml0ZTo6aDgyMmNkMjY0OGQ4ZWFjZjUELmNvcmU6OnN0cjo6c2xpY2VfZXJyb3JfZmFpbDo6aDZjZjI4OGMxZjcwZDI5YjIFLGNvcmU6OmZtdDo6Rm9ybWF0dGVyOjpwYWQ6Omg5NmM5ZDMyMjA3YjQyNTBhBjVjb3JlOjpmbXQ6OkZvcm1hdHRlcjo6cGFkX2ludGVncmFsOjpoYjkzNmU0N2EzMzRkN2U4MwdBcmVlZF9zb2xvbW9uX2VyYXN1cmU6Om1hdHJpeDo6TWF0cml4OjptdWx0aXBseTo6aGU3Y2Q4ODhmYjYzOGE5OWEIC3JlY29uc3RydWN0CUdyZWVkX3NvbG9tb25fZXJhc3VyZTo6UmVlZFNvbG9tb246OmNvZGVfc2luZ2xlX3NsaWNlOjpoNGQwODU3MDhlODgxMmY3MQpEcmVlZF9zb2xvbW9uX2VyYXN1cmU6Om1hdHJpeDo6TWF0cml4Ojp2YW5kZXJtb25kZTo6aDRlYmZmYjZjMTI5NjE4YzMLMjxjaGFyIGFzIGNvcmU6OmZtdDo6RGVidWc+OjpmbXQ6Omg4OTA4YjRhZmE5YTg4NWUzDC13ZWVfYWxsb2M6OmFsbG9jX2ZpcnN0X2ZpdDo6aDlhNTk4ZGQwMzljYmY2NzANBmVuY29kZQ5DcmVlZF9zb2xvbW9uX2VyYXN1cmU6Om1hdHJpeDo6TWF0cml4OjpzdWJfbWF0cml4OjpoN2RkMDlmODY1NWYwY2IyYg88cmVlZF9zb2xvbW9uX2VyYXN1cmU6OlJlZWRTb2xvbW9uOjplbmNvZGU6OmhlYjU0MGZlYWI2ZDQ2YTBjEFQ8d2VlX2FsbG9jOjpXZWVBbGxvYzwnc3RhdGljPiBhcyBjb3JlOjphbGxvYzo6R2xvYmFsQWxsb2M+OjphbGxvYzo6aDM0ODFhYWI1YjMxZWU4N2MRRXJlZWRfc29sb21vbl9lcmFzdXJlOjpSZWVkU29sb21vbjo6Z2V0X3Bhcml0eV9yb3dzOjpoNjc1ODJiMGYxNWNmMDBiNhJAcmVlZF9zb2xvbW9uX2VyYXN1cmU6OlJlZWRTb2xvbW9uOjplbmNvZGVfc2VwOjpoZDk1N2NiZGM3N2UzMzM2MxNBcmVlZF9zb2xvbW9uX2VyYXN1cmU6OlJlZWRTb2xvbW9uOjp3aXRoX3BwYXJhbTo6aDIyOWJkNzg5MWJjY2E0OWYUQXJlZWRfc29sb21vbl9lcmFzdXJlOjptYXRyaXg6Ok1hdHJpeDo6aWRlbnRpdHk6Omg4OWU0OTQyY2VlMmQyY2U0FT5yZWVkX3NvbG9tb25fZXJhc3VyZTo6Z2Fsb2lzOjptdWxfc2xpY2VfeG9yOjpoMDdlZGRkZmVjNWUyMjkwMBY6cmVlZF9zb2xvbW9uX2VyYXN1cmU6OmdhbG9pczo6bXVsX3NsaWNlOjpoZDQ3ZmUxNWJiOGZkMDM4ZRcyY29yZTo6dW5pY29kZTo6cHJpbnRhYmxlOjpjaGVjazo6aDFhOTVmZjk0ZmNiNzM4ZGIYUXJlZWRfc29sb21vbl9lcmFzdXJlOjppbnZlcnNpb25fdHJlZTo6SW52ZXJzaW9uTm9kZTo6Z2V0X2NoaWxkOjpoZTUzNDg4YmQzZDQwMmUyZBlbcmVlZF9zb2xvbW9uX2VyYXN1cmU6OmludmVyc2lvbl90cmVlOjpJbnZlcnNpb25UcmVlOjpnZXRfaW52ZXJ0ZWRfbWF0cml4OjpoZGMwODIyZTE3NWYxMWY5OBpLcmVlZF9zb2xvbW9uX2VyYXN1cmU6OmludmVyc2lvbl90cmVlOjpJbnZlcnNpb25UcmVlOjpuZXc6OmhkODk5YzdhYjE4MmUyZmFmGzs8Jm11dCBXIGFzIGNvcmU6OmZtdDo6V3JpdGU+Ojp3cml0ZV9jaGFyOjpoMjkzZDQ1NzA5NGFhZjY5YRwvY29yZTo6Zm10OjpudW06OmltcDo6Zm10X3U2NDo6aGMzOTNlMzM3YWI5YmFlOTkdS3JlZWRfc29sb21vbl9lcmFzdXJlOjppbnZlcnNpb25fdHJlZTo6SW52ZXJzaW9uTm9kZTo6bmV3OjpoNjk0ZmQ4Mzg5YTNkOGEwMh5JY29yZTo6Zm10OjpudW06OjxpbXBsIGNvcmU6OmZtdDo6RGVidWcgZm9yIHVzaXplPjo6Zm10OjpoNWQ0MDFjZDE0YTIwYzVhYx9Bd2VlX2FsbG9jOjpXZWVBbGxvYzo6ZGVhbGxvY19pbXBsOjp7e2Nsb3N1cmV9fTo6aGVjODBlODBjMGM1ODliODYgbDxzdGQ6OnBhbmlja2luZzo6Y29udGludWVfcGFuaWNfZm10OjpQYW5pY1BheWxvYWQ8J2E+IGFzIGNvcmU6OnBhbmljOjpCb3hNZVVwPjo6Ym94X21lX3VwOjpoOGQ1N2M2N2IwYzhmMTVmYyE9Y29yZTo6dW5pY29kZTo6Ym9vbF90cmllOjpCb29sVHJpZTo6bG9va3VwOjpoMDI5MmI2MmIxNjQ2MjNmNCIwPHNtYWxsdmVjOjpTbWFsbFZlYzxBPj46Omdyb3c6OmgzODNlYTZlM2IzYzgyN2UwIzxyZWVkX3NvbG9tb25fZXJhc3VyZTo6bWF0cml4OjpNYXRyaXg6Om5ldzo6aDMxNjA2NTFiNzI3Yjg5ZWEkMDxzbWFsbHZlYzo6U21hbGxWZWM8QT4+Ojpncm93OjpoZGExOTQ3ODY5ODI0MzNkMyUwPHNtYWxsdmVjOjpTbWFsbFZlYzxBPj46Omdyb3c6OmhiMWQ4NzE1MzE1N2M5YTk4Jl5yZWVkX3NvbG9tb25fZXJhc3VyZTo6aW52ZXJzaW9uX3RyZWU6OkludmVyc2lvblRyZWU6Omluc2VydF9pbnZlcnRlZF9tYXRyaXg6OmgyMWQ0YjUzZGJjMzNjMWIyJzdzdGQ6OnBhbmlja2luZzo6cnVzdF9wYW5pY193aXRoX2hvb2s6OmhiNzFkNWZlNGRjNmNlYmQzKFE8cmVlZF9zb2xvbW9uX2VyYXN1cmU6OmVycm9yczo6RXJyb3IgYXMgY29yZTo6Zm10OjpEZWJ1Zz46OmZtdDo6aGVlZmU4YTVhYjA1NThiYzkpgAE8d2VlX2FsbG9jOjpzaXplX2NsYXNzZXM6OlNpemVDbGFzc0FsbG9jUG9saWN5PCdhLCAnYj4gYXMgd2VlX2FsbG9jOjpBbGxvY1BvbGljeTwnYT4+OjpuZXdfY2VsbF9mb3JfZnJlZV9saXN0OjpoYjAwMWFhYjFmYmFmZTA3YSpmPHN0ZDo6cGFuaWNraW5nOjpjb250aW51ZV9wYW5pY19mbXQ6OlBhbmljUGF5bG9hZDwnYT4gYXMgY29yZTo6cGFuaWM6OkJveE1lVXA+OjpnZXQ6OmhlMTRjNjZkMzc3MWQ3YjhjKzpjb3JlOjpmbXQ6OmJ1aWxkZXJzOjpEZWJ1Z1R1cGxlOjpmaW5pc2g6OmgzNjg2NDljYzhiM2EwYzFlLFY8d2VlX2FsbG9jOjpXZWVBbGxvYzwnc3RhdGljPiBhcyBjb3JlOjphbGxvYzo6R2xvYmFsQWxsb2M+OjpkZWFsbG9jOjpoYjE0MGMxZWEyNzBmYjJhOS1KY29yZTo6Zm10OjpudW06OjxpbXBsIGNvcmU6OmZtdDo6TG93ZXJIZXggZm9yIGkzMj46OmZtdDo6aDZmNTM3MTU3ZjNiMjM2MjcuSmNvcmU6OmZtdDo6bnVtOjo8aW1wbCBjb3JlOjpmbXQ6OlVwcGVySGV4IGZvciBpMzI+OjpmbXQ6OmgzZDQzYzEzYzUyNzMyNzFjLzBjb3JlOjpwdHI6OnJlYWxfZHJvcF9pbl9wbGFjZTo6aDg1MTgyYWZlNzMxM2M2OWMwMGNvcmU6OnB0cjo6cmVhbF9kcm9wX2luX3BsYWNlOjpoY2Q4ZTRmYjhjMjUxZTJmMTEwPGFsbG9jOjp2ZWM6OlZlYzxUPj46OnJlc2VydmU6OmhhYzhiZWI2NTJmOTRiYjA4MmY8d2VlX2FsbG9jOjpMYXJnZUFsbG9jUG9saWN5IGFzIHdlZV9hbGxvYzo6QWxsb2NQb2xpY3k8J2E+Pjo6bmV3X2NlbGxfZm9yX2ZyZWVfbGlzdDo6aDNmMDA4ODlkMTM4ZWI3NmYzLmNvcmU6OnJlc3VsdDo6dW53cmFwX2ZhaWxlZDo6aGY5MmRkY2RlMGJkYTgwNWM0Sjxjb3JlOjpvcHM6OnJhbmdlOjpSYW5nZTxJZHg+IGFzIGNvcmU6OmZtdDo6RGVidWc+OjpmbXQ6OmhlMTkwOWJmY2Q5OWZkZjI2NS5jb3JlOjpyZXN1bHQ6OnVud3JhcF9mYWlsZWQ6OmhkNmJhMjEzNjFhN2M5YjRlNi5jb3JlOjpyZXN1bHQ6OnVud3JhcF9mYWlsZWQ6OmgwOWM3M2FkY2FmMzAzYTQ3Ny5jb3JlOjpyZXN1bHQ6OnVud3JhcF9mYWlsZWQ6OmhhNTE0ZmNkNzUxZGIzMTdlODVzdGQ6OnBhbmlja2luZzo6Y29udGludWVfcGFuaWNfZm10OjpoMWRhOWJlM2MwN2ZlZDk3OTk0Y29yZTo6c2xpY2U6OnNsaWNlX2luZGV4X2xlbl9mYWlsOjpoZjYyNjUyMDI2MWYwNDhmZTo2Y29yZTo6cGFuaWNraW5nOjpwYW5pY19ib3VuZHNfY2hlY2s6OmgyNzNlNDlhMzgwZDAxZmI3OzZjb3JlOjpzbGljZTo6c2xpY2VfaW5kZXhfb3JkZXJfZmFpbDo6aGRlYmNhY2YzNDk4MmJiNTI8OjwmbXV0IFcgYXMgY29yZTo6Zm10OjpXcml0ZT46OndyaXRlX2ZtdDo6aGI3ZmQ2NTIyZjg0MjE5M2Q9KWNvcmU6OnBhbmlja2luZzo6cGFuaWM6OmgzYzUxMmM3YzJiYjZkYTI1PmQ8c3RkOjpwYW5pY2tpbmc6OmJlZ2luX3BhbmljOjpQYW5pY1BheWxvYWQ8QT4gYXMgY29yZTo6cGFuaWM6OkJveE1lVXA+Ojpib3hfbWVfdXA6Omg1YmRjYmM1MDMwNzE1NjU1PzJzdGQ6OnBhbmlja2luZzo6YmVnaW5fcGFuaWNfZm10OjpoZjhmODM2MjQ5NWQyYWU4MEAzPGFsbG9jOjpzeW5jOjpBcmM8VD4+Ojpkcm9wX3Nsb3c6OmhkZmU1ZmRkMDYzNjMwZTcxQTM8YWxsb2M6OnN5bmM6OkFyYzxUPj46OmRyb3Bfc2xvdzo6aGQ4NTRhMTljMmU3MTRiMDhCQ2NvcmU6OmZtdDo6Rm9ybWF0dGVyOjpwYWRfaW50ZWdyYWw6OndyaXRlX3ByZWZpeDo6aGZkY2ZkMDc0YmUzNWM1ZTBDWTxyZWVkX3NvbG9tb25fZXJhc3VyZTo6aW52ZXJzaW9uX3RyZWU6OkVycm9yIGFzIGNvcmU6OmZtdDo6RGVidWc+OjpmbXQ6Omg4ODVlZTVkMGE4Mzg2NDNlRC1jb3JlOjpwYW5pY2tpbmc6OnBhbmljX2ZtdDo6aDQ3MmQ3NjZlNGRmZjcxYTJFEV9fd2JpbmRnZW5fbWFsbG9jRgZtZW1jcHlHDF9fcmdfcmVhbGxvY0gwPCZUIGFzIGNvcmU6OmZtdDo6RGVidWc+OjpmbXQ6OmgxM2JmNWJkYjM2Njg4ZTU1SSxzdGQ6OnBhbmlja2luZzo6cGFuaWNraW5nOjpoZDI1NjQ1YTczYTYwZjE0Yko0Y29yZTo6Zm10OjpGb3JtYXR0ZXI6OmRlYnVnX3R1cGxlOjpoOTczZTJhZTEzODkyNzZiYks6PCZtdXQgVyBhcyBjb3JlOjpmbXQ6OldyaXRlPjo6d3JpdGVfc3RyOjpoNjZiZDVkNDkzYTllNjhjNUwGbWVtc2V0TS5zdGQ6OnBhbmlja2luZzo6YmVnaW5fcGFuaWM6OmgyNDE4ZmE2ZmJiMTZlM2E4TlE8cmVlZF9zb2xvbW9uX2VyYXN1cmU6Om1hdHJpeDo6RXJyb3IgYXMgY29yZTo6Zm10OjpEZWJ1Zz46OmZtdDo6aDAwMGExZmQ5OTA0ZjYwNjlPMGNvcmU6OnB0cjo6cmVhbF9kcm9wX2luX3BsYWNlOjpoMWFkYmNiZmQ4YTQ5YzYzM1AKcnVzdF9wYW5pY1ERX19yZ19hbGxvY196ZXJvZWRSXjxzdGQ6OnBhbmlja2luZzo6YmVnaW5fcGFuaWM6OlBhbmljUGF5bG9hZDxBPiBhcyBjb3JlOjpwYW5pYzo6Qm94TWVVcD46OmdldDo6aDU4MDBjODBhYjY0MjA0ZTlTgAFjb3JlOjpzdHI6OnRyYWl0czo6PGltcGwgY29yZTo6c2xpY2U6OlNsaWNlSW5kZXg8c3RyPiBmb3IgY29yZTo6b3BzOjpyYW5nZTo6UmFuZ2U8dXNpemU+Pjo6aW5kZXg6Ont7Y2xvc3VyZX19OjpoNWE0YjljMjk5NTVhY2U0YlQ+Y29yZTo6cGFuaWM6OkxvY2F0aW9uOjppbnRlcm5hbF9jb25zdHJ1Y3Rvcjo6aGU2ZTU1MWIwOTBjZTM2NTJVOndhc21fYmluZGdlbjo6YW55cmVmOjpIRUFQX1NMQUI6Ol9faW5pdDo6aGRhYTQxNDMzYjlmOTNiZWRWMGNvcmU6OnB0cjo6cmVhbF9kcm9wX2luX3BsYWNlOjpoNGQ5ZmE0NjY4ZTMwMGM2YVcIcnVzdF9vb21YRnJlZWRfc29sb21vbl9lcmFzdXJlOjpSZWVkU29sb21vbjo6cmVjb25zdHJ1Y3RfZGF0YTo6aDc1YjE5Mjk5M2JhZDFlMGVZNDxjb3JlOjpvcHRpb246Ok9wdGlvbjxUPj46OnVud3JhcDo6aDBiN2QyYWM0ZjA3MzJkMDhaNDxjb3JlOjpvcHRpb246Ok9wdGlvbjxUPj46OnVud3JhcDo6aGY5Y2ViOGY2MmIwOTU1MDFbD19fd2JpbmRnZW5fZnJlZVwyPCZUIGFzIGNvcmU6OmZtdDo6RGlzcGxheT46OmZtdDo6aGFjMTkzZjNhNDI5MjQxZmJdMjwmVCBhcyBjb3JlOjpmbXQ6OkRpc3BsYXk+OjpmbXQ6OmhkZDFlMTI0NmNiMjQ4M2IzXjI8JlQgYXMgY29yZTo6Zm10OjpEaXNwbGF5Pjo6Zm10OjpoYWE4OTNlZjUwOTIyOWUwOF84Y29yZTo6Zm10OjpGb3JtYXR0ZXI6OmRlYnVnX2xvd2VyX2hleDo6aDA1ZTI5NmFiM2Y4YjFiYjdgOGNvcmU6OmZtdDo6Rm9ybWF0dGVyOjpkZWJ1Z191cHBlcl9oZXg6OmgwODUwNWQ1M2JiMDQxMDRmYQxfX3JnX2RlYWxsb2NiDl9fcnVzdF9yZWFsbG9jYzlyZWVkX3NvbG9tb25fZXJhc3VyZTo6UmVlZFNvbG9tb246Om5ldzo6aGRkYzdlMDAzYjIyODRlOWRkTmNvcmU6OmZtdDo6bnVtOjppbXA6OjxpbXBsIGNvcmU6OmZtdDo6RGlzcGxheSBmb3IgdTMyPjo6Zm10OjpoNjJmYzg5OTRmNGY1ZWRiM2U0Y29yZTo6Zm10OjpBcmd1bWVudFYxOjpzaG93X3VzaXplOjpoZWQ5MzI0ZGJlNjlkZmM0MWYKX19yZ19hbGxvY2cOX19ydXN0X2RlYWxsb2NoVTxzdGQ6OnN5c19jb21tb246OnBvaXNvbjo6UG9pc29uRXJyb3I8VD4gYXMgY29yZTo6Zm10OjpEZWJ1Zz46OmZtdDo6aGRlZDZkZjI5Y2FiMjIxNGRpM2FsbG9jOjphbGxvYzo6aGFuZGxlX2FsbG9jX2Vycm9yOjpoMmJmNDQ0ZjA0NzA0OWIwZWouY29yZTo6cGFuaWM6OkxvY2F0aW9uOjpmaWxlOjpoYTk5OTc1ZTA0YWJlYTI4N2szPHN0ciBhcyBjb3JlOjpmbXQ6OkRpc3BsYXk+OjpmbXQ6OmhiMTZhNjk5MTMwMDM0MDM0bAxfX3J1c3RfYWxsb2NtE19fcnVzdF9hbGxvY196ZXJvZWRuEXJ1c3RfYmVnaW5fdW53aW5kbzRhbGxvYzo6cmF3X3ZlYzo6Y2FwYWNpdHlfb3ZlcmZsb3c6OmhhM2ZmMjQ3Y2YxZDA3MmZhcDNjb3JlOjpwYW5pYzo6UGFuaWNJbmZvOjpsb2NhdGlvbjo6aGM4MmI2ZDgwMjQ3NmRmNTRxNXdhc21fYmluZGdlbjo6X19ydDo6bWFsbG9jX2ZhaWx1cmU6OmhjMTkwYjVkOWE2YTU3ODZmcks8YWxsb2M6OnJhd192ZWM6OlJhd1ZlYzxULCBBPj46OmFsbG9jYXRlX2luOjp7e2Nsb3N1cmV9fTo6aDIwMjQzMDAwMGY2ZjQwOThzMmNvcmU6OnBhbmljOjpQYW5pY0luZm86Om1lc3NhZ2U6OmhiZDE3NDJhZjNlYjE5MDI3dC5jb3JlOjpwYW5pYzo6TG9jYXRpb246OmxpbmU6OmgxOGZiY2VhYjJjNmQwMGNjdTBjb3JlOjpwYW5pYzo6TG9jYXRpb246OmNvbHVtbjo6aDk5N2FlM2RmYWVkYTc4MDh2dzx3ZWVfYWxsb2M6OnNpemVfY2xhc3Nlczo6U2l6ZUNsYXNzQWxsb2NQb2xpY3k8J2EsICdiPiBhcyB3ZWVfYWxsb2M6OkFsbG9jUG9saWN5PCdhPj46Om1pbl9jZWxsX3NpemU6Omg5MDFjMTQ1ZWY5ZDYxZmQ2d4oBPHdlZV9hbGxvYzo6c2l6ZV9jbGFzc2VzOjpTaXplQ2xhc3NBbGxvY1BvbGljeTwnYSwgJ2I+IGFzIHdlZV9hbGxvYzo6QWxsb2NQb2xpY3k8J2E+Pjo6c2hvdWxkX21lcmdlX2FkamFjZW50X2ZyZWVfY2VsbHM6Omg0MzgyZGZkYmJkMzFmM2E1eF08d2VlX2FsbG9jOjpMYXJnZUFsbG9jUG9saWN5IGFzIHdlZV9hbGxvYzo6QWxsb2NQb2xpY3k8J2E+Pjo6bWluX2NlbGxfc2l6ZTo6aDlmMWQ3MmEwODYzMGE2YjR5cDx3ZWVfYWxsb2M6OkxhcmdlQWxsb2NQb2xpY3kgYXMgd2VlX2FsbG9jOjpBbGxvY1BvbGljeTwnYT4+OjpzaG91bGRfbWVyZ2VfYWRqYWNlbnRfZnJlZV9jZWxsczo6aDQ2Njc2N2Q4ZjA4NmFjNjN6O3dhc21fYmluZGdlbjo6YW55cmVmOjpIRUFQX1NMQUI6Ol9fZ2V0aXQ6OmhkZGU3YmIwMjNkZWVkYTlmezE8VCBhcyBjb3JlOjphbnk6OkFueT46OnR5cGVfaWQ6Omg2YmQ3N2Y5NzE3ZGJjZjg5fDE8VCBhcyBjb3JlOjphbnk6OkFueT46OnR5cGVfaWQ6Omg4NDFmZDAyNTc5OWZkYjAwfTE8VCBhcyBjb3JlOjphbnk6OkFueT46OnR5cGVfaWQ6Omg3YzQ4MTk0MGYxMDFiYWVhfjE8VCBhcyBjb3JlOjphbnk6OkFueT46OnR5cGVfaWQ6OmhjZDFhMTkzYmU2ZjFkNTQxfyZzdGQ6OnByb2Nlc3M6OmFib3J0OjpoZjYyMWVlNzUyNzY5MjhhYoABNXN0ZDo6c3lzX2NvbW1vbjo6bXV0ZXg6Ok11dGV4OjpuZXc6OmgwNzIyODJjNzE4YTQ0OWZhgQE1c3RkOjpzeXNfY29tbW9uOjpwb2lzb246OkZsYWc6Om5ldzo6aDIzY2JhMzU4ZjkyMzdjNTCCARJfX3J1c3Rfc3RhcnRfcGFuaWODATE8VCBhcyBjb3JlOjphbnk6OkFueT46OnR5cGVfaWQ6Omg3MDUwNjI4NzZkNzc5NWY4hAEwY29yZTo6cHRyOjpyZWFsX2Ryb3BfaW5fcGxhY2U6OmhiZmUxMDUwYzNiMmU2OTI0hQEwY29yZTo6cHRyOjpyZWFsX2Ryb3BfaW5fcGxhY2U6OmgwMTQ2MGFlOTQyOGNiNTkwhgEwY29yZTo6cHRyOjpyZWFsX2Ryb3BfaW5fcGxhY2U6OmhiZmUxMDUwYzNiMmU2OTI0hwEwY29yZTo6cHRyOjpyZWFsX2Ryb3BfaW5fcGxhY2U6OmhjNjVmMTJiYTZiNDUxM2FmiAEwY29yZTo6cHRyOjpyZWFsX2Ryb3BfaW5fcGxhY2U6OmhlY2FkZTFjOWU1Nzk3YmE1iQEwY29yZTo6cHRyOjpyZWFsX2Ryb3BfaW5fcGxhY2U6OmgyZWFkYzhmYzEzNzU4ZTA0igFWPHN0ZDo6c3lzX2NvbW1vbjo6dGhyZWFkX2xvY2FsOjpLZXkgYXMgY29yZTo6b3BzOjpkcm9wOjpEcm9wPjo6ZHJvcDo6aDg2ZDkzMjk5Mjg4NWIzODiLATdzdGQ6OmFsbG9jOjpkZWZhdWx0X2FsbG9jX2Vycm9yX2hvb2s6OmgxOTJmYjQ4YWM5NWUwNjE0jAEwY29yZTo6cHRyOjpyZWFsX2Ryb3BfaW5fcGxhY2U6Omg5ZDIwYTQzNmU4OTMxNjg1AP+AgIAACXByb2R1Y2VycwIIbGFuZ3VhZ2UBBFJ1c3QEMjAxNQxwcm9jZXNzZWQtYnkDBXJ1c3RjHTEuMzQuMCAoOTE4NTZlZDUyIDIwMTktMDQtMTApBndhbHJ1cwYwLjExLjAMd2FzbS1iaW5kZ2VuEjAuMi40OSAoOTA2YWMxNTAwKQ==");
|
|
@@ -6345,11 +6565,10 @@ var reed_solomon_erasure_bg_default = __toBinaryNode("AGFzbQEAAAAB/oCAgAASYAJ/fw
|
|
|
6345
6565
|
// ../../packages/sdk/dist/chunk-PZF2VTGP.mjs
|
|
6346
6566
|
var DEFAULT_CHUNK_SIZE_BYTES2 = 2 * 1024 * 1024;
|
|
6347
6567
|
|
|
6348
|
-
// ../../packages/sdk/dist/chunk-
|
|
6568
|
+
// ../../packages/sdk/dist/chunk-66GI734H.mjs
|
|
6349
6569
|
import {
|
|
6350
6570
|
AccountAddress as AccountAddress7,
|
|
6351
|
-
Aptos as Aptos4
|
|
6352
|
-
AptosConfig as AptosConfig3
|
|
6571
|
+
Aptos as Aptos4
|
|
6353
6572
|
} from "@aptos-labs/ts-sdk";
|
|
6354
6573
|
var ShelbyMicropaymentChannelClient = class _ShelbyMicropaymentChannelClient {
|
|
6355
6574
|
aptos;
|
|
@@ -6375,16 +6594,7 @@ var ShelbyMicropaymentChannelClient = class _ShelbyMicropaymentChannelClient {
|
|
|
6375
6594
|
* ```
|
|
6376
6595
|
*/
|
|
6377
6596
|
constructor(config) {
|
|
6378
|
-
|
|
6379
|
-
const aptosConfig = new AptosConfig3({
|
|
6380
|
-
...baseAptosConfig,
|
|
6381
|
-
clientConfig: {
|
|
6382
|
-
...baseAptosConfig.clientConfig,
|
|
6383
|
-
// Only use top-level apiKey if no API_KEY is already provided in Aptos settings
|
|
6384
|
-
API_KEY: baseAptosConfig.clientConfig?.API_KEY ?? config.apiKey
|
|
6385
|
-
}
|
|
6386
|
-
});
|
|
6387
|
-
this.aptos = new Aptos4(aptosConfig);
|
|
6597
|
+
this.aptos = new Aptos4(getAptosConfig(config));
|
|
6388
6598
|
this.deployer = config.deployer ?? AccountAddress7.fromString(MICROPAYMENTS_DEPLOYER);
|
|
6389
6599
|
this.indexer = getShelbyIndexerClient(config);
|
|
6390
6600
|
}
|
|
@@ -6833,23 +7043,23 @@ var ShelbyMicropaymentChannelClient = class _ShelbyMicropaymentChannelClient {
|
|
|
6833
7043
|
};
|
|
6834
7044
|
|
|
6835
7045
|
// ../../packages/sdk/dist/chunk-VRLIOKWG.mjs
|
|
6836
|
-
import { Network as
|
|
6837
|
-
var shelbyNetworks = [
|
|
7046
|
+
import { Network as Network3 } from "@aptos-labs/ts-sdk";
|
|
7047
|
+
var shelbyNetworks = [Network3.LOCAL, Network3.SHELBYNET];
|
|
6838
7048
|
|
|
6839
7049
|
// ../../packages/sdk/dist/chunk-BDSW5PHM.mjs
|
|
6840
|
-
import { Network as
|
|
7050
|
+
import { Network as Network4 } from "@aptos-labs/ts-sdk";
|
|
6841
7051
|
function getShelbyExplorerBaseUrl(network) {
|
|
6842
7052
|
const normalizedNetwork = network.toLowerCase();
|
|
6843
7053
|
switch (normalizedNetwork) {
|
|
6844
|
-
case
|
|
7054
|
+
case Network4.MAINNET.toLowerCase():
|
|
6845
7055
|
return "https://explorer.shelby.xyz/mainnet";
|
|
6846
|
-
case
|
|
7056
|
+
case Network4.TESTNET.toLowerCase():
|
|
6847
7057
|
return "https://explorer.shelby.xyz/testnet";
|
|
6848
|
-
case
|
|
7058
|
+
case Network4.DEVNET.toLowerCase():
|
|
6849
7059
|
return "https://explorer.shelby.xyz/devnet";
|
|
6850
|
-
case
|
|
7060
|
+
case Network4.LOCAL.toLowerCase():
|
|
6851
7061
|
return "https://explorer.shelby.xyz/local";
|
|
6852
|
-
case
|
|
7062
|
+
case Network4.SHELBYNET.toLowerCase():
|
|
6853
7063
|
return "https://explorer.shelby.xyz/shelbynet";
|
|
6854
7064
|
default:
|
|
6855
7065
|
return `https://explorer.shelby.xyz/${normalizedNetwork}`;
|
|
@@ -6860,40 +7070,20 @@ function getShelbyAccountExplorerUrl(network, accountAddress) {
|
|
|
6860
7070
|
return `${baseUrl}/account/${accountAddress}`;
|
|
6861
7071
|
}
|
|
6862
7072
|
|
|
6863
|
-
// ../../packages/sdk/dist/chunk-7P6ASYW6.mjs
|
|
6864
|
-
var __defProp2 = Object.defineProperty;
|
|
6865
|
-
var __export = (target, all) => {
|
|
6866
|
-
for (var name2 in all)
|
|
6867
|
-
__defProp2(target, name2, { get: all[name2], enumerable: true });
|
|
6868
|
-
};
|
|
6869
|
-
|
|
6870
|
-
// ../../packages/sdk/dist/chunk-A4IG6GSE.mjs
|
|
6871
|
-
var testUtil_exports = {};
|
|
6872
|
-
__export(testUtil_exports, {
|
|
6873
|
-
makeChunk: () => makeChunk
|
|
6874
|
-
});
|
|
6875
|
-
function makeChunk(n) {
|
|
6876
|
-
const c = Buffer.alloc(n);
|
|
6877
|
-
for (let i = 0; i < n; ++i) {
|
|
6878
|
-
c[i] = i % 256;
|
|
6879
|
-
}
|
|
6880
|
-
return c;
|
|
6881
|
-
}
|
|
6882
|
-
|
|
6883
7073
|
// ../../packages/sdk/dist/chunk-C6RQ3AEU.mjs
|
|
6884
|
-
import { Network as
|
|
7074
|
+
import { Network as Network5 } from "@aptos-labs/ts-sdk";
|
|
6885
7075
|
function getAptosExplorerBaseUrl(network) {
|
|
6886
7076
|
const normalizedNetwork = network.toLowerCase();
|
|
6887
7077
|
switch (normalizedNetwork) {
|
|
6888
|
-
case
|
|
7078
|
+
case Network5.MAINNET.toLowerCase():
|
|
6889
7079
|
return "https://explorer.aptoslabs.com";
|
|
6890
|
-
case
|
|
7080
|
+
case Network5.TESTNET.toLowerCase():
|
|
6891
7081
|
return "https://explorer.aptoslabs.com";
|
|
6892
|
-
case
|
|
7082
|
+
case Network5.DEVNET.toLowerCase():
|
|
6893
7083
|
return "https://explorer.aptoslabs.com";
|
|
6894
|
-
case
|
|
7084
|
+
case Network5.LOCAL.toLowerCase():
|
|
6895
7085
|
return "https://explorer.aptoslabs.com";
|
|
6896
|
-
case
|
|
7086
|
+
case Network5.SHELBYNET.toLowerCase():
|
|
6897
7087
|
return "https://explorer.aptoslabs.com";
|
|
6898
7088
|
default:
|
|
6899
7089
|
return "https://explorer.aptoslabs.com";
|
|
@@ -6902,15 +7092,15 @@ function getAptosExplorerBaseUrl(network) {
|
|
|
6902
7092
|
function getAptosExplorerNetworkParam(network) {
|
|
6903
7093
|
const normalizedNetwork = network.toLowerCase();
|
|
6904
7094
|
switch (normalizedNetwork) {
|
|
6905
|
-
case
|
|
7095
|
+
case Network5.MAINNET.toLowerCase():
|
|
6906
7096
|
return "mainnet";
|
|
6907
|
-
case
|
|
7097
|
+
case Network5.TESTNET.toLowerCase():
|
|
6908
7098
|
return "testnet";
|
|
6909
|
-
case
|
|
7099
|
+
case Network5.DEVNET.toLowerCase():
|
|
6910
7100
|
return "devnet";
|
|
6911
|
-
case
|
|
7101
|
+
case Network5.LOCAL.toLowerCase():
|
|
6912
7102
|
return "local";
|
|
6913
|
-
case
|
|
7103
|
+
case Network5.SHELBYNET.toLowerCase():
|
|
6914
7104
|
return "shelbynet";
|
|
6915
7105
|
default:
|
|
6916
7106
|
return normalizedNetwork;
|
|
@@ -6943,7 +7133,7 @@ import os2 from "os";
|
|
|
6943
7133
|
import path2 from "path";
|
|
6944
7134
|
import {
|
|
6945
7135
|
Aptos as Aptos5,
|
|
6946
|
-
AptosConfig as
|
|
7136
|
+
AptosConfig as AptosConfig2,
|
|
6947
7137
|
Ed25519Account,
|
|
6948
7138
|
Ed25519PrivateKey,
|
|
6949
7139
|
NetworkToNetworkName
|
|
@@ -6989,6 +7179,14 @@ import path from "path";
|
|
|
6989
7179
|
import fs from "fs-extra";
|
|
6990
7180
|
import YAML from "yaml";
|
|
6991
7181
|
import { z as z7 } from "zod";
|
|
7182
|
+
|
|
7183
|
+
// src/utils/permissions.ts
|
|
7184
|
+
var DIR_PERMISSIONS = 448;
|
|
7185
|
+
var FILE_PERMISSIONS = 384;
|
|
7186
|
+
var PERMISSION_MASK = 511;
|
|
7187
|
+
var GROUP_WORLD_BITS = 63;
|
|
7188
|
+
|
|
7189
|
+
// src/utils/global-config.ts
|
|
6992
7190
|
var GlobalConfigSchema = z7.object({
|
|
6993
7191
|
config_location_behavior: z7.enum(["global", "walk"])
|
|
6994
7192
|
});
|
|
@@ -7022,7 +7220,15 @@ function loadGlobalConfig() {
|
|
|
7022
7220
|
function saveGlobalConfig(config) {
|
|
7023
7221
|
fs.mkdirpSync(path.dirname(GLOBAL_CONFIG_PATH));
|
|
7024
7222
|
GlobalConfigSchema.parse(config);
|
|
7025
|
-
fs.writeFileSync(GLOBAL_CONFIG_PATH, YAML.stringify(config),
|
|
7223
|
+
fs.writeFileSync(GLOBAL_CONFIG_PATH, YAML.stringify(config), {
|
|
7224
|
+
encoding: "utf8",
|
|
7225
|
+
mode: FILE_PERMISSIONS
|
|
7226
|
+
});
|
|
7227
|
+
fs.chmodSync(GLOBAL_CONFIG_PATH, FILE_PERMISSIONS);
|
|
7228
|
+
const dir = path.dirname(GLOBAL_CONFIG_PATH);
|
|
7229
|
+
if (path.basename(dir) === ".shelby") {
|
|
7230
|
+
fs.chmodSync(dir, DIR_PERMISSIONS);
|
|
7231
|
+
}
|
|
7026
7232
|
}
|
|
7027
7233
|
|
|
7028
7234
|
// src/utils/config.ts
|
|
@@ -7066,6 +7272,19 @@ function loadConfigOrExit(configFile) {
|
|
|
7066
7272
|
);
|
|
7067
7273
|
process.exit(1);
|
|
7068
7274
|
}
|
|
7275
|
+
if (process.platform !== "win32") {
|
|
7276
|
+
const mode = fs2.statSync(configPath).mode & PERMISSION_MASK;
|
|
7277
|
+
if (mode & GROUP_WORLD_BITS) {
|
|
7278
|
+
console.error(
|
|
7279
|
+
`\u274C Permissions 0${mode.toString(8)} for '${configPath}' are too open.`
|
|
7280
|
+
);
|
|
7281
|
+
console.error(
|
|
7282
|
+
" Your config file contains private keys and must not be accessible by others."
|
|
7283
|
+
);
|
|
7284
|
+
console.error(` Run: chmod 600 ${configPath}`);
|
|
7285
|
+
process.exit(1);
|
|
7286
|
+
}
|
|
7287
|
+
}
|
|
7069
7288
|
return { configPath, config: loadConfig(configPath) };
|
|
7070
7289
|
} catch (err) {
|
|
7071
7290
|
console.error("\u274C Failed to load configuration file");
|
|
@@ -7144,7 +7363,15 @@ function saveConfig(config, configPath) {
|
|
|
7144
7363
|
const resolvedPath = resolveConfigPath(configPath);
|
|
7145
7364
|
fs2.mkdirpSync(path2.dirname(resolvedPath));
|
|
7146
7365
|
ConfigSchema.parse(config);
|
|
7147
|
-
fs2.writeFileSync(resolvedPath, YAML2.stringify(config),
|
|
7366
|
+
fs2.writeFileSync(resolvedPath, YAML2.stringify(config), {
|
|
7367
|
+
encoding: "utf8",
|
|
7368
|
+
mode: FILE_PERMISSIONS
|
|
7369
|
+
});
|
|
7370
|
+
fs2.chmodSync(resolvedPath, FILE_PERMISSIONS);
|
|
7371
|
+
const dir = path2.dirname(resolvedPath);
|
|
7372
|
+
if (path2.basename(dir) === ".shelby") {
|
|
7373
|
+
fs2.chmodSync(dir, DIR_PERMISSIONS);
|
|
7374
|
+
}
|
|
7148
7375
|
}
|
|
7149
7376
|
function getCurrentContext(config, contextName) {
|
|
7150
7377
|
const name2 = contextName || config.default_context;
|
|
@@ -7196,7 +7423,7 @@ function getAptosSettingsFromContext(context) {
|
|
|
7196
7423
|
}
|
|
7197
7424
|
function getAptosFromContext(context) {
|
|
7198
7425
|
const config = getAptosSettingsFromContext(context);
|
|
7199
|
-
return new Aptos5(new
|
|
7426
|
+
return new Aptos5(new AptosConfig2(config));
|
|
7200
7427
|
}
|
|
7201
7428
|
function getShelbyConfigFromContext(context) {
|
|
7202
7429
|
const aptosSettings = getAptosSettingsFromContext(context);
|
|
@@ -7913,7 +8140,7 @@ import { useState as useState5 } from "react";
|
|
|
7913
8140
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
7914
8141
|
|
|
7915
8142
|
// src/components/InitWizard.tsx
|
|
7916
|
-
import { Account as Account2, Ed25519PrivateKey as Ed25519PrivateKey3, Network as
|
|
8143
|
+
import { Account as Account2, Ed25519PrivateKey as Ed25519PrivateKey3, Network as Network7 } from "@aptos-labs/ts-sdk";
|
|
7917
8144
|
import { Box as Box6, Text as Text6 } from "ink";
|
|
7918
8145
|
import SelectInput3 from "ink-select-input";
|
|
7919
8146
|
import Spinner from "ink-spinner";
|
|
@@ -7927,7 +8154,7 @@ import {
|
|
|
7927
8154
|
} from "@aptos-labs/ts-sdk";
|
|
7928
8155
|
|
|
7929
8156
|
// src/utils/constants.ts
|
|
7930
|
-
import { APTOS_COIN, Network as
|
|
8157
|
+
import { APTOS_COIN, Network as Network6 } from "@aptos-labs/ts-sdk";
|
|
7931
8158
|
|
|
7932
8159
|
// src/utils/context-helpers.ts
|
|
7933
8160
|
import {
|
|
@@ -7956,15 +8183,15 @@ function createContextForNetwork(network) {
|
|
|
7956
8183
|
// src/utils/constants.ts
|
|
7957
8184
|
var DEFAULT_CONFIG = {
|
|
7958
8185
|
contexts: {
|
|
7959
|
-
[
|
|
7960
|
-
...createContextForNetwork(
|
|
8186
|
+
[Network6.LOCAL]: {
|
|
8187
|
+
...createContextForNetwork(Network6.LOCAL),
|
|
7961
8188
|
// Override shelby_network for local
|
|
7962
8189
|
shelby_network: { rpc_endpoint: "http://localhost:9090/" }
|
|
7963
8190
|
},
|
|
7964
|
-
[
|
|
8191
|
+
[Network6.SHELBYNET]: createContextForNetwork(Network6.SHELBYNET)
|
|
7965
8192
|
},
|
|
7966
8193
|
accounts: {},
|
|
7967
|
-
default_context:
|
|
8194
|
+
default_context: Network6.SHELBYNET,
|
|
7968
8195
|
default_account: ""
|
|
7969
8196
|
};
|
|
7970
8197
|
var STANDARD_CONTEXT_NAMES = Object.keys(DEFAULT_CONFIG.contexts).join(
|
|
@@ -8642,9 +8869,9 @@ var InitWizard = ({
|
|
|
8642
8869
|
if (setupStandardContexts) {
|
|
8643
8870
|
const modifiedStandardContexts = { ...DEFAULT_CONFIG.contexts };
|
|
8644
8871
|
if (standardContextsApiKey) {
|
|
8645
|
-
if (modifiedStandardContexts[
|
|
8646
|
-
modifiedStandardContexts[
|
|
8647
|
-
...modifiedStandardContexts[
|
|
8872
|
+
if (modifiedStandardContexts[Network7.SHELBYNET]) {
|
|
8873
|
+
modifiedStandardContexts[Network7.SHELBYNET] = {
|
|
8874
|
+
...modifiedStandardContexts[Network7.SHELBYNET],
|
|
8648
8875
|
api_key: standardContextsApiKey
|
|
8649
8876
|
};
|
|
8650
8877
|
}
|
|
@@ -8831,7 +9058,7 @@ var InitWizard = ({
|
|
|
8831
9058
|
] }),
|
|
8832
9059
|
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
8833
9060
|
"Enter API Key for ",
|
|
8834
|
-
|
|
9061
|
+
Network7.SHELBYNET,
|
|
8835
9062
|
" (optional: press Enter to skip)"
|
|
8836
9063
|
] }),
|
|
8837
9064
|
/* @__PURE__ */ jsx8(
|
|
@@ -8994,7 +9221,8 @@ var ERROR_CODES = {
|
|
|
8994
9221
|
EBLOB_WRITE_INSUFFICIENT_FUNDS: "EBLOB_WRITE_INSUFFICIENT_FUNDS",
|
|
8995
9222
|
EBLOB_WRITE_CHUNKSET_ALREADY_EXISTS: "EBLOB_WRITE_CHUNKSET_ALREADY_EXISTS",
|
|
8996
9223
|
ECONNREFUSED: "ECONNREFUSED",
|
|
8997
|
-
ENOTFOUND: "ENOTFOUND"
|
|
9224
|
+
ENOTFOUND: "ENOTFOUND",
|
|
9225
|
+
EPIPE: "EPIPE"
|
|
8998
9226
|
};
|
|
8999
9227
|
var DEFAULT_ERROR_RESPONSE = {
|
|
9000
9228
|
displayMessage: "An unknown error occurred",
|
|
@@ -9038,6 +9266,18 @@ var handleError = (error) => {
|
|
|
9038
9266
|
code: ERROR_CODES.ENOTFOUND
|
|
9039
9267
|
};
|
|
9040
9268
|
}
|
|
9269
|
+
if (error.code === ERROR_CODES.EPIPE) {
|
|
9270
|
+
return {
|
|
9271
|
+
displayMessage: "Upload failed because the connection to the Shelby RPC endpoint was closed while sending data (EPIPE).",
|
|
9272
|
+
code: ERROR_CODES.EPIPE
|
|
9273
|
+
};
|
|
9274
|
+
}
|
|
9275
|
+
}
|
|
9276
|
+
if (error.message.includes(ERROR_CODES.EPIPE)) {
|
|
9277
|
+
return {
|
|
9278
|
+
displayMessage: "Upload failed because the connection to the Shelby RPC endpoint was closed while sending data (EPIPE).",
|
|
9279
|
+
code: ERROR_CODES.EPIPE
|
|
9280
|
+
};
|
|
9041
9281
|
}
|
|
9042
9282
|
if (error.cause instanceof AggregateError) {
|
|
9043
9283
|
const firstKnownError = error.cause.errors.find((error2) => {
|
|
@@ -9890,7 +10130,7 @@ function contextCommand(program) {
|
|
|
9890
10130
|
}
|
|
9891
10131
|
|
|
9892
10132
|
// src/commands/delete.tsx
|
|
9893
|
-
import { Aptos as Aptos6, AptosConfig as
|
|
10133
|
+
import { Aptos as Aptos6, AptosConfig as AptosConfig3 } from "@aptos-labs/ts-sdk";
|
|
9894
10134
|
import { Box as Box7, render as render3, Text as Text7 } from "ink";
|
|
9895
10135
|
import SelectInput4 from "ink-select-input";
|
|
9896
10136
|
import ora from "ora";
|
|
@@ -10075,7 +10315,7 @@ function deleteCommand(program) {
|
|
|
10075
10315
|
config,
|
|
10076
10316
|
program.opts().account
|
|
10077
10317
|
).account;
|
|
10078
|
-
const aptos = new Aptos6(new
|
|
10318
|
+
const aptos = new Aptos6(new AptosConfig3(shelbyConfig.aptos));
|
|
10079
10319
|
const shelbyClient = new ShelbyNodeClient(shelbyConfig);
|
|
10080
10320
|
const start = performance.now();
|
|
10081
10321
|
let deleteList;
|
|
@@ -11060,12 +11300,12 @@ function downloadCommand(program) {
|
|
|
11060
11300
|
}
|
|
11061
11301
|
|
|
11062
11302
|
// src/commands/faucet.tsx
|
|
11063
|
-
import { Network as
|
|
11303
|
+
import { Network as Network8 } from "@aptos-labs/ts-sdk";
|
|
11064
11304
|
import { Option as Option2 } from "@commander-js/extra-typings";
|
|
11065
11305
|
import { execaSync } from "execa";
|
|
11066
11306
|
import { z as z18 } from "zod";
|
|
11067
11307
|
var FaucetOptionsSchema = z18.object({
|
|
11068
|
-
network: z18.enum([
|
|
11308
|
+
network: z18.enum([Network8.SHELBYNET]).optional(),
|
|
11069
11309
|
open: z18.boolean().optional().default(true)
|
|
11070
11310
|
});
|
|
11071
11311
|
function faucetCommand(program) {
|
|
@@ -11073,7 +11313,7 @@ function faucetCommand(program) {
|
|
|
11073
11313
|
new Option2(
|
|
11074
11314
|
"--network <network>",
|
|
11075
11315
|
"Network to request tokens for (shelbynet)"
|
|
11076
|
-
).choices(Object.values(
|
|
11316
|
+
).choices(Object.values(Network8))
|
|
11077
11317
|
).addOption(
|
|
11078
11318
|
new Option2(
|
|
11079
11319
|
"--no-open",
|
|
@@ -11085,7 +11325,7 @@ function faucetCommand(program) {
|
|
|
11085
11325
|
const { config } = loadConfigOrExit(program.opts().configFile);
|
|
11086
11326
|
const accountName = program.opts().account || config.default_account;
|
|
11087
11327
|
const { account } = getCurrentAccount(config, accountName);
|
|
11088
|
-
const network = validatedOptions.network ||
|
|
11328
|
+
const network = validatedOptions.network || Network8.SHELBYNET;
|
|
11089
11329
|
if (network === "mainnet") {
|
|
11090
11330
|
throw new Error(
|
|
11091
11331
|
"\u274C No faucet available for mainnet. Mainnet tokens must be obtained through other means."
|
|
@@ -11147,7 +11387,7 @@ function openBrowser(url) {
|
|
|
11147
11387
|
|
|
11148
11388
|
// src/commands/init.tsx
|
|
11149
11389
|
import path7 from "path";
|
|
11150
|
-
import { Network as
|
|
11390
|
+
import { Network as Network9 } from "@aptos-labs/ts-sdk";
|
|
11151
11391
|
import fs8 from "fs-extra";
|
|
11152
11392
|
import { render as render4 } from "ink";
|
|
11153
11393
|
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
@@ -11219,7 +11459,7 @@ function initCommand(program) {
|
|
|
11219
11459
|
console.log(` Private key: ${generated.privateKey.toAIP80String()}`);
|
|
11220
11460
|
console.log("");
|
|
11221
11461
|
console.log(
|
|
11222
|
-
`\u2139\uFE0F To fund your new account on-chain (${
|
|
11462
|
+
`\u2139\uFE0F To fund your new account on-chain (${Network9.SHELBYNET} only), run:`
|
|
11223
11463
|
);
|
|
11224
11464
|
console.log(" \u{1F449} shelby faucet");
|
|
11225
11465
|
console.log("");
|
|
@@ -11250,7 +11490,7 @@ function initCommand(program) {
|
|
|
11250
11490
|
)) {
|
|
11251
11491
|
console.log("");
|
|
11252
11492
|
console.log(
|
|
11253
|
-
`\u2139\uFE0F To fund your new account on-chain (${
|
|
11493
|
+
`\u2139\uFE0F To fund your new account on-chain (${Network9.SHELBYNET} only), run:`
|
|
11254
11494
|
);
|
|
11255
11495
|
console.log(" \u{1F449} shelby faucet");
|
|
11256
11496
|
}
|
|
@@ -11281,9 +11521,11 @@ function ensureConfigDir(resolvedPath) {
|
|
|
11281
11521
|
}
|
|
11282
11522
|
|
|
11283
11523
|
// src/commands/upload.tsx
|
|
11524
|
+
import { createReadStream as createReadStream2 } from "fs";
|
|
11284
11525
|
import * as fs9 from "fs/promises";
|
|
11285
11526
|
import * as path8 from "path";
|
|
11286
|
-
import {
|
|
11527
|
+
import { Readable as Readable3 } from "stream";
|
|
11528
|
+
import { Aptos as Aptos7, AptosConfig as AptosConfig4 } from "@aptos-labs/ts-sdk";
|
|
11287
11529
|
import * as chrono from "chrono-node";
|
|
11288
11530
|
import { glob } from "glob";
|
|
11289
11531
|
import ignore from "ignore";
|
|
@@ -11293,6 +11535,11 @@ import ora3 from "ora";
|
|
|
11293
11535
|
import { z as z19 } from "zod";
|
|
11294
11536
|
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
11295
11537
|
var normBlobName2 = (i, f, b) => normBlobName(path8, i, f, b);
|
|
11538
|
+
function createFileStream(filePath) {
|
|
11539
|
+
return Readable3.toWeb(
|
|
11540
|
+
createReadStream2(filePath)
|
|
11541
|
+
);
|
|
11542
|
+
}
|
|
11296
11543
|
var flexibleDateSchema = z19.string().transform((val, ctx) => {
|
|
11297
11544
|
const now = /* @__PURE__ */ new Date();
|
|
11298
11545
|
let parsedDate = null;
|
|
@@ -11632,7 +11879,7 @@ function uploadCommand(program) {
|
|
|
11632
11879
|
config,
|
|
11633
11880
|
program.opts().account
|
|
11634
11881
|
).account;
|
|
11635
|
-
const aptos = new Aptos7(new
|
|
11882
|
+
const aptos = new Aptos7(new AptosConfig4(shelbyConfig.aptos));
|
|
11636
11883
|
const shelbyClient = new ShelbyNodeClient(shelbyConfig);
|
|
11637
11884
|
const handleSigint = () => {
|
|
11638
11885
|
spinner.fail("Quitting due to ctrl-C / SIGINT...");
|
|
@@ -11671,19 +11918,21 @@ function uploadCommand(program) {
|
|
|
11671
11918
|
for (const entry of filelist) {
|
|
11672
11919
|
const fileName = path8.basename(entry.filename);
|
|
11673
11920
|
let currentFileUploadedBytes = 0;
|
|
11921
|
+
let finalizeTimer;
|
|
11922
|
+
const assertUnchangedSize = async (stage) => {
|
|
11923
|
+
const latestStats = await fs9.stat(entry.filename);
|
|
11924
|
+
if (latestStats.size !== entry.sizeBytes) {
|
|
11925
|
+
throw new Error(
|
|
11926
|
+
`Size of file ${entry.filename} changed before ${stage}. Original size was ${entry.sizeBytes} but it is now ${latestStats.size}`
|
|
11927
|
+
);
|
|
11928
|
+
}
|
|
11929
|
+
};
|
|
11674
11930
|
const formatOverallProgress = () => isSingleFile ? `(${formatOverallProgressPercent(currentFileUploadedBytes)}%)` : `(${filesProcessed}/${filelist.length} files, ${formatOverallProgressPercent(
|
|
11675
11931
|
currentFileUploadedBytes
|
|
11676
11932
|
)}%)`;
|
|
11677
11933
|
const overallProgress = formatOverallProgress();
|
|
11678
|
-
spinner.text = `\u{
|
|
11934
|
+
spinner.text = `\u{1F517} Checking if blob exists... ${overallProgress}`;
|
|
11679
11935
|
try {
|
|
11680
|
-
const blobData = await fs9.readFile(entry.filename);
|
|
11681
|
-
if (blobData.length !== entry.sizeBytes) {
|
|
11682
|
-
throw new Error(
|
|
11683
|
-
`Size of file ${entry.filename} changed after initial scan. Original size was ${entry.sizeBytes} but it is now ${blobData.length}`
|
|
11684
|
-
);
|
|
11685
|
-
}
|
|
11686
|
-
spinner.text = `\u{1F517} Checking if blob exists... ${overallProgress}`;
|
|
11687
11936
|
const existingBlobMetadata = await shelbyClient.coordination.getBlobMetadata({
|
|
11688
11937
|
account: activeAccount.accountAddress,
|
|
11689
11938
|
name: entry.blobname
|
|
@@ -11695,8 +11944,12 @@ function uploadCommand(program) {
|
|
|
11695
11944
|
process.exit(1);
|
|
11696
11945
|
}
|
|
11697
11946
|
spinner.text = `\u{1F517} Generating commitments for ${fileName}... ${overallProgress}`;
|
|
11947
|
+
await assertUnchangedSize("commitment generation");
|
|
11698
11948
|
const provider = await getErasureCodingProvider();
|
|
11699
|
-
const blobCommitments = await generateCommitments(
|
|
11949
|
+
const blobCommitments = await generateCommitments(
|
|
11950
|
+
provider,
|
|
11951
|
+
createFileStream(entry.filename)
|
|
11952
|
+
);
|
|
11700
11953
|
if (options.outputCommitments) {
|
|
11701
11954
|
outputCommitments[entry.filename] = blobCommitments;
|
|
11702
11955
|
}
|
|
@@ -11705,7 +11958,7 @@ function uploadCommand(program) {
|
|
|
11705
11958
|
account: activeAccount,
|
|
11706
11959
|
blobName: entry.blobname,
|
|
11707
11960
|
blobMerkleRoot: blobCommitments.blob_merkle_root,
|
|
11708
|
-
size:
|
|
11961
|
+
size: entry.sizeBytes,
|
|
11709
11962
|
expirationMicros: options.expiration.getTime() * 1e3
|
|
11710
11963
|
});
|
|
11711
11964
|
const registerTransactionHash = pendingRegisterBlobTransaction.hash;
|
|
@@ -11716,17 +11969,29 @@ function uploadCommand(program) {
|
|
|
11716
11969
|
transactionHash: pendingRegisterBlobTransaction.hash
|
|
11717
11970
|
});
|
|
11718
11971
|
spinner.text = `\u{1F4E4} Uploading ${fileName} to Shelby RPC... ${overallProgress}`;
|
|
11972
|
+
await assertUnchangedSize("upload");
|
|
11719
11973
|
await shelbyClient.rpc.putBlob({
|
|
11720
11974
|
account: activeAccount.accountAddress,
|
|
11721
11975
|
blobName: entry.blobname,
|
|
11722
|
-
blobData,
|
|
11723
|
-
|
|
11976
|
+
blobData: createFileStream(entry.filename),
|
|
11977
|
+
totalBytes: entry.sizeBytes,
|
|
11978
|
+
onProgress: ({ phase, uploadedBytes, totalBytes }) => {
|
|
11979
|
+
if (phase === "finalizing") {
|
|
11980
|
+
const finalizeStart = performance.now();
|
|
11981
|
+
finalizeTimer = setInterval(() => {
|
|
11982
|
+
const elapsed = ((performance.now() - finalizeStart) / 1e3).toFixed(0);
|
|
11983
|
+
spinner.text = `\u{1F4E4} Finalizing ${fileName} (${elapsed}s) \u2014 server is reassembling chunks and encoding erasure data (do not quit)`;
|
|
11984
|
+
}, 1e3);
|
|
11985
|
+
spinner.text = `\u{1F4E4} Finalizing ${fileName} (0s) \u2014 server is reassembling chunks and encoding erasure data (do not quit)`;
|
|
11986
|
+
return;
|
|
11987
|
+
}
|
|
11724
11988
|
currentFileUploadedBytes = uploadedBytes;
|
|
11725
11989
|
const pct = totalBytes > 0 ? (100 * uploadedBytes / totalBytes).toFixed(2) : "0.00";
|
|
11726
11990
|
spinner.text = isSingleFile ? `\u{1F4E4} Uploading ${fileName} to Shelby RPC... ${pct}%` : `\u{1F4E4} Uploading ${fileName} to Shelby RPC... ${pct}% ${formatOverallProgress()}`;
|
|
11727
11991
|
}
|
|
11728
11992
|
});
|
|
11729
|
-
|
|
11993
|
+
clearInterval(finalizeTimer);
|
|
11994
|
+
amountUploaded += entry.sizeBytes;
|
|
11730
11995
|
filesProcessed++;
|
|
11731
11996
|
} catch (error) {
|
|
11732
11997
|
const { displayMessage } = handleError(error);
|
|
@@ -12545,14 +12810,39 @@ function createProgram() {
|
|
|
12545
12810
|
localnetCommand(program);
|
|
12546
12811
|
uploadCommand(program);
|
|
12547
12812
|
commitmentCommand(program);
|
|
12813
|
+
program.action(() => {
|
|
12814
|
+
program.outputHelp();
|
|
12815
|
+
});
|
|
12548
12816
|
return program;
|
|
12549
12817
|
}
|
|
12550
12818
|
|
|
12819
|
+
// src/utils/cli-args.ts
|
|
12820
|
+
function findUnknownCommandArg(args, knownCommands) {
|
|
12821
|
+
const firstPositionalArg = args.find((arg) => !arg.startsWith("-"));
|
|
12822
|
+
if (firstPositionalArg !== void 0 && firstPositionalArg !== "help" && !knownCommands.has(firstPositionalArg)) {
|
|
12823
|
+
return firstPositionalArg;
|
|
12824
|
+
}
|
|
12825
|
+
return void 0;
|
|
12826
|
+
}
|
|
12827
|
+
|
|
12551
12828
|
// src/entry.ts
|
|
12552
12829
|
function main() {
|
|
12553
12830
|
checkForUpdatesAsync();
|
|
12554
12831
|
const rawArgs = process.argv.slice(2);
|
|
12555
12832
|
const normalizedArgs = rawArgs[0] === "--" ? rawArgs.slice(1) : rawArgs;
|
|
12556
|
-
createProgram()
|
|
12833
|
+
const program = createProgram();
|
|
12834
|
+
const knownCommands = new Set(
|
|
12835
|
+
program.commands.map((command) => command.name())
|
|
12836
|
+
);
|
|
12837
|
+
const unknownCommandArg = findUnknownCommandArg(
|
|
12838
|
+
normalizedArgs,
|
|
12839
|
+
knownCommands
|
|
12840
|
+
);
|
|
12841
|
+
if (unknownCommandArg !== void 0) {
|
|
12842
|
+
console.error(`error: unknown command '${unknownCommandArg}'`);
|
|
12843
|
+
program.outputHelp();
|
|
12844
|
+
process.exit(1);
|
|
12845
|
+
}
|
|
12846
|
+
program.parse([process.argv[0], process.argv[1], ...normalizedArgs]);
|
|
12557
12847
|
}
|
|
12558
12848
|
main();
|