@shelby-protocol/cli 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/entry.js +1880 -1499
  2. package/package.json +20 -18
package/bin/entry.js CHANGED
@@ -4,409 +4,1064 @@
4
4
  import { Command } from "commander";
5
5
 
6
6
  // package.json
7
- var version = "0.0.7";
7
+ var version = "0.0.8";
8
8
 
9
- // src/commands/init.tsx
10
- import { render } from "ink";
9
+ // src/commands/account.tsx
10
+ import { Hex as Hex3 } from "@aptos-labs/ts-sdk";
11
11
 
12
- // src/components/AccountWizard.tsx
13
- import { Box, Text } from "ink";
14
- import TextInput from "ink-text-input";
15
- import { useEffect, useState } from "react";
12
+ // ../../packages/sdk/dist/chunk-OTBLZL2S.mjs
13
+ import { AccountAddress } from "@aptos-labs/ts-sdk";
14
+ var createBlobKey = (params) => {
15
+ return `@${AccountAddress.from(params.account).toStringLongWithoutPrefix()}/${params.blobName}`;
16
+ };
16
17
 
17
- // src/utils/keys.ts
18
- import {
19
- Account,
20
- AccountAddress,
21
- Ed25519PrivateKey,
22
- Secp256k1PrivateKey,
23
- SigningSchemeInput
24
- } from "@aptos-labs/ts-sdk";
25
- function generateEd25519Account() {
26
- const account = Account.generate({
27
- scheme: SigningSchemeInput.Ed25519,
28
- legacy: true
29
- });
30
- return account;
31
- }
32
- function isValidEd25519PrivateKey(value) {
18
+ // ../../packages/sdk/dist/chunk-5Z3RVWU3.mjs
19
+ import { Hex } from "@aptos-labs/ts-sdk";
20
+ async function* readInChunks(input, chunkSize) {
21
+ let idx = 0;
22
+ if (Buffer.isBuffer(input)) {
23
+ for (let offset = 0; offset < input.length; offset += chunkSize) {
24
+ yield [idx++, Buffer.from(input.subarray(offset, offset + chunkSize))];
25
+ }
26
+ return;
27
+ }
28
+ const reader = input.getReader();
29
+ let buffer = new Uint8Array(chunkSize);
30
+ let bufferWriteOffset = 0;
33
31
  try {
34
- const key = new Ed25519PrivateKey(value);
35
- return true;
36
- } catch {
37
- return false;
32
+ while (true) {
33
+ const { value, done } = await reader.read();
34
+ if (done) break;
35
+ if (value === void 0) continue;
36
+ let srcOffset = 0;
37
+ while (srcOffset < value.length) {
38
+ const remainingCapacity = chunkSize - bufferWriteOffset;
39
+ const bytesToCopy = Math.min(
40
+ remainingCapacity,
41
+ value.length - srcOffset
42
+ );
43
+ buffer.set(
44
+ value.subarray(srcOffset, srcOffset + bytesToCopy),
45
+ bufferWriteOffset
46
+ );
47
+ bufferWriteOffset += bytesToCopy;
48
+ srcOffset += bytesToCopy;
49
+ if (bufferWriteOffset >= chunkSize) {
50
+ yield [idx++, Buffer.from(buffer)];
51
+ buffer = new Uint8Array(chunkSize);
52
+ bufferWriteOffset = 0;
53
+ }
54
+ }
55
+ }
56
+ } finally {
57
+ reader.releaseLock();
58
+ }
59
+ if (bufferWriteOffset > 0) {
60
+ yield [idx++, Buffer.from(buffer.subarray(0, bufferWriteOffset))];
38
61
  }
39
62
  }
40
- function isValidAddress(address) {
41
- return AccountAddress.isValid({ input: address }).valid;
63
+ function zeroPadBuffer(buffer, desiredLength) {
64
+ if (buffer.length >= desiredLength) {
65
+ return buffer;
66
+ }
67
+ const paddedBuffer = Buffer.alloc(desiredLength);
68
+ buffer.copy(paddedBuffer);
69
+ return paddedBuffer;
42
70
  }
43
- var SECP256K1_NAME = "secp256k1";
44
- var ED25519_NAME = "ed25519";
45
- function isValidScheme(scheme) {
46
- return SECP256K1_NAME === scheme || ED25519_NAME === scheme;
71
+ async function concatHashes(parts) {
72
+ const combined = Buffer.concat(
73
+ parts.map((part) => Hex.fromHexInput(part).toUint8Array())
74
+ );
75
+ return Hex.fromHexInput(
76
+ new Uint8Array(await crypto.subtle.digest("SHA-256", combined))
77
+ );
47
78
  }
48
79
 
49
- // src/components/AccountWizard.tsx
50
- import { jsx, jsxs } from "react/jsx-runtime";
51
- var AccountWizard = ({ onComplete }) => {
52
- const [step, setStep] = useState("name");
53
- const [name2, setName] = useState("");
54
- const [address, setAddress] = useState("");
55
- const [privateKey, setPrivateKey] = useState("");
56
- useEffect(() => {
57
- if (step === "done") {
58
- onComplete({
59
- name: name2,
60
- address: address || void 0,
61
- privateKey
62
- });
80
+ // ../../packages/reed-solomon/dist/index.mjs
81
+ var __toBinaryNode = (base64) => new Uint8Array(Buffer.from(base64, "base64"));
82
+ var reed_solomon_erasure_bg_default = __toBinaryNode("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QCAKIAlJDQACQCAJRQ0AIAkgAUYNACAJIAFPDQEgACAJaiwAAEG/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==");
83
+ var ReedSolomonErasure = class _ReedSolomonErasure {
84
+ constructor(exports) {
85
+ this.exports = exports;
86
+ }
87
+ static RESULT_OK = 0;
88
+ static RESULT_ERROR_TOO_FEW_SHARDS = 1;
89
+ static RESULT_ERROR_TOO_MANY_SHARDS = 2;
90
+ static RESULT_ERROR_TOO_FEW_DATA_SHARDS = 3;
91
+ static RESULT_ERROR_TOO_MANY_DATA_SHARDS = 4;
92
+ static RESULT_ERROR_TOO_FEW_PARITY_SHARDS = 5;
93
+ static RESULT_ERROR_TOO_MANY_PARITY_SHARDS = 6;
94
+ static RESULT_ERROR_TOO_FEW_BUFFER_SHARDS = 7;
95
+ static RESULT_ERROR_TOO_MANY_BUFFER_SHARDS = 8;
96
+ static RESULT_ERROR_INCORRECT_SHARD_SIZE = 9;
97
+ static RESULT_ERROR_TOO_FEW_SHARDS_PRESENT = 10;
98
+ static RESULT_ERROR_EMPTY_SHARD = 11;
99
+ static RESULT_ERROR_INVALID_SHARD_FLAGS = 12;
100
+ static RESULT_ERROR_INVALID_INDEX = 13;
101
+ static fromBytes(bytes) {
102
+ const module = new WebAssembly.Module(bytes);
103
+ const instance = new WebAssembly.Instance(module);
104
+ return new _ReedSolomonErasure(
105
+ instance.exports
106
+ );
107
+ }
108
+ memoryCache = null;
109
+ /**
110
+ * Takes a contiguous array of bytes that contain space for `data_shards + parity_shards` shards with `data_shards` shards containing data and fills
111
+ * additional `parity_shards` with parity information that can be later used to reconstruct data in case of corruption
112
+ *
113
+ * @param shards
114
+ * @param dataShards
115
+ * @param parityShards
116
+ *
117
+ * @returns One of `RESULT_*` constants; if `RESULT_OK` then parity shards were updated in `shards` in-place
118
+ */
119
+ encode(shards, dataShards, parityShards) {
120
+ const exports = this.exports;
121
+ const shardsLength = shards.length;
122
+ const shardsPointer = exports.__wbindgen_malloc(shardsLength);
123
+ this.getUint8Memory().set(shards, shardsPointer);
124
+ const shardSize = shardsLength / (dataShards + parityShards);
125
+ const result = exports.encode(
126
+ shardsPointer,
127
+ shardsLength,
128
+ dataShards,
129
+ parityShards
130
+ );
131
+ if (result === _ReedSolomonErasure.RESULT_OK) {
132
+ shards.set(
133
+ this.getUint8Memory().subarray(
134
+ shardsPointer + shardSize * dataShards,
135
+ shardsPointer + shardsLength
136
+ ),
137
+ shardSize * dataShards
138
+ );
63
139
  }
64
- }, [onComplete, step, name2, address, privateKey]);
65
- if (step === "name") {
66
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
67
- /* @__PURE__ */ jsx(Text, { children: "Account name?" }),
68
- /* @__PURE__ */ jsx(
69
- TextInput,
70
- {
71
- value: name2,
72
- onChange: setName,
73
- onSubmit: () => setStep("address")
74
- }
75
- )
76
- ] });
140
+ exports.__wbindgen_free(shardsPointer, shardsLength);
141
+ return result;
77
142
  }
78
- if (step === "address") {
79
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
80
- /* @__PURE__ */ jsx(Text, { children: "Address (optional)?" }),
81
- /* @__PURE__ */ jsx(
82
- TextInput,
83
- {
84
- value: address,
85
- onChange: setAddress,
86
- onSubmit: () => setStep("key")
87
- }
88
- )
89
- ] });
143
+ /**
144
+ * Takes a contiguous array of bytes that contain `data_shards + parity_shards` shards and tries to reconstruct data shards if they are broken and whenever
145
+ * possible using information from `shards_available` (contains `data_shards + parity_shards` boolean values, each of which is either `true` if shard is not
146
+ * corrupted or `false` if it is)
147
+ *
148
+ * @param shards
149
+ * @param dataShards
150
+ * @param parityShards
151
+ * @param shardsAvailable
152
+ *
153
+ * @returns One of `RESULT_*` constants; if `RESULT_OK` then data shards were reconstructed in `shards` in-place
154
+ */
155
+ reconstruct(shards, dataShards, parityShards, shardsAvailable) {
156
+ const exports = this.exports;
157
+ const shardsLength = shards.length;
158
+ const shardsPointer = exports.__wbindgen_malloc(shardsLength);
159
+ this.getUint8Memory().set(shards, shardsPointer);
160
+ const shardsAvailableLength = shardsAvailable.length;
161
+ const shardsAvailablePointer = exports.__wbindgen_malloc(
162
+ shardsAvailableLength
163
+ );
164
+ this.getUint8Memory().set(
165
+ shardsAvailable.map((value) => value ? 1 : 0),
166
+ shardsAvailablePointer
167
+ );
168
+ const shardSize = shardsLength / (dataShards + parityShards);
169
+ const result = exports.reconstruct(
170
+ shardsPointer,
171
+ shardsLength,
172
+ dataShards,
173
+ parityShards,
174
+ shardsAvailablePointer,
175
+ shardsAvailableLength
176
+ );
177
+ if (result === _ReedSolomonErasure.RESULT_OK) {
178
+ shards.set(
179
+ this.getUint8Memory().subarray(
180
+ shardsPointer,
181
+ shardsPointer + shardSize * dataShards
182
+ )
183
+ );
184
+ }
185
+ exports.__wbindgen_free(shardsPointer, shardsLength);
186
+ exports.__wbindgen_free(shardsAvailablePointer, shardsAvailableLength);
187
+ return result;
90
188
  }
91
- if (step === "key") {
92
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
93
- /* @__PURE__ */ jsx(Text, { children: "Paste private key or leave blank to generate" }),
94
- /* @__PURE__ */ jsx(
95
- TextInput,
96
- {
97
- value: privateKey,
98
- onChange: setPrivateKey,
99
- onSubmit: () => {
100
- if (!privateKey) {
101
- const acct = generateEd25519Account();
102
- setPrivateKey(acct.privateKey.toAIP80String());
103
- setAddress((prev) => prev || acct.accountAddress.toString());
104
- }
105
- setStep("done");
106
- }
107
- }
108
- )
109
- ] });
189
+ getUint8Memory() {
190
+ let cachegetUint8Memory = this.memoryCache;
191
+ if (cachegetUint8Memory === null || cachegetUint8Memory.buffer !== this.exports.memory.buffer) {
192
+ cachegetUint8Memory = new Uint8Array(this.exports.memory.buffer);
193
+ this.memoryCache = cachegetUint8Memory;
194
+ }
195
+ return cachegetUint8Memory;
110
196
  }
111
- return null;
112
197
  };
198
+ function createWasmReedSolomonBinding() {
199
+ return ReedSolomonErasure.fromBytes(reed_solomon_erasure_bg_default);
200
+ }
113
201
 
114
- // src/components/InitWizard.tsx
115
- import { execSync } from "child_process";
116
- import { Box as Box2, Text as Text2 } from "ink";
117
- import SelectInput from "ink-select-input";
118
- import Spinner from "ink-spinner";
119
- import TextInput2 from "ink-text-input";
120
- import { useEffect as useEffect2, useState as useState2 } from "react";
121
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
122
- var InitWizard = ({ onComplete }) => {
123
- const [step, setStep] = useState2("checkAptos");
124
- const [aptosFound, setAptosFound] = useState2(false);
125
- const [setupStandardContexts, setSetupStandardContexts] = useState2(false);
126
- const [setupCustomContext, setSetupCustomContext] = useState2(false);
127
- const [customContextName, setCustomContextName] = useState2("staging");
128
- const [shelbyRpcEndpoint, setShelbyRpcEndpoint] = useState2(
129
- "https://shelby.rpc.staging.example.com"
130
- );
131
- const [aptosNetwork, setAptosNetwork] = useState2("mainnet");
132
- const [setupAccount, setSetupAccount] = useState2(false);
133
- const [accountName, setAccountName] = useState2("alice");
134
- const [signatureScheme, setSignatureScheme] = useState2("ed25519");
135
- const [privateKey, setPrivateKey] = useState2("");
136
- const [address, setAddress] = useState2("");
137
- const [generatedKey, setGeneratedKey] = useState2("");
138
- const [generatedAddress, setGeneratedAddress] = useState2("");
139
- useEffect2(() => {
140
- if (step === "checkAptos") {
141
- try {
142
- const aptosVersion = execSync("aptos --version").toString().trim();
143
- if (aptosVersion.includes("aptos")) {
144
- setAptosFound(true);
145
- }
146
- } catch (error) {
147
- }
148
- setStep("standardContexts");
149
- }
150
- }, [step]);
151
- useEffect2(() => {
152
- if (step === "complete") {
153
- const config = {
154
- contexts: {},
155
- accounts: {},
156
- default_context: setupStandardContexts ? "devnet" : customContextName,
157
- default_account: setupAccount ? accountName : "default_account"
158
- };
159
- if (setupStandardContexts) {
160
- config.contexts.local = {
161
- aptos_network: "local",
162
- shelby_rpc_endpoint: "http://localhost:9090"
163
- };
164
- config.contexts.devnet = {
165
- aptos_network: "devnet",
166
- shelby_rpc_endpoint: "https://shelby.rpc.devnet.example.com"
167
- };
168
- config.contexts.testnet = {
169
- aptos_network: "testnet",
170
- shelby_rpc_endpoint: "https://shelby.rpc.testnet.example.com"
171
- };
172
- config.contexts.mainnet = {
173
- aptos_network: "mainnet",
174
- shelby_rpc_endpoint: "https://shelby.rpc.mainnet.example.com"
175
- };
176
- }
177
- if (setupCustomContext) {
178
- config.contexts[customContextName] = {
179
- aptos_network: aptosNetwork,
180
- shelby_rpc_endpoint: shelbyRpcEndpoint
181
- };
182
- }
183
- if (setupAccount) {
184
- const finalPrivateKey = privateKey || generatedKey;
185
- const finalAddress = address || generatedAddress;
186
- config.accounts[accountName] = {
187
- private_key: finalPrivateKey,
188
- address: finalAddress
189
- };
190
- }
191
- onComplete(config);
192
- }
193
- }, [step]);
194
- if (step === "checkAptos") {
195
- return /* @__PURE__ */ jsx2(Box2, { children: /* @__PURE__ */ jsxs2(Text2, { children: [
196
- /* @__PURE__ */ jsx2(Spinner, { type: "dots" }),
197
- " Checking for Aptos CLI >v7.2.0..."
198
- ] }) });
199
- }
200
- if (step === "standardContexts") {
201
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
202
- /* @__PURE__ */ jsxs2(Text2, { children: [
203
- "\u2714 Checking for Aptos CLI >v7.2.0...",
204
- " ",
205
- aptosFound ? "found" : "not found"
206
- ] }),
207
- /* @__PURE__ */ jsx2(Text2, { children: "Do you want to set up standard contexts (devnet, testnet, mainnet)?" }),
208
- /* @__PURE__ */ jsx2(
209
- SelectInput,
210
- {
211
- items: [
212
- { label: "Yes", value: true },
213
- { label: "No", value: false }
214
- ],
215
- onSelect: (item) => {
216
- setSetupStandardContexts(item.value);
217
- setStep("customContext");
218
- }
219
- }
220
- )
221
- ] });
202
+ // ../../packages/sdk/dist/chunk-P7BVGLTV.mjs
203
+ function erasureEncode(data, k, m) {
204
+ const rawShardSize = Math.ceil(data.length / k);
205
+ const shardSize = Math.ceil(rawShardSize / 8) * 8;
206
+ const dataSize = shardSize * k;
207
+ const paritySize = shardSize * m;
208
+ const reedSolomon = createWasmReedSolomonBinding();
209
+ const dataBuf = Buffer.alloc(dataSize);
210
+ data.copy(dataBuf, 0);
211
+ const shards = new Uint8Array(dataSize + paritySize);
212
+ shards.set(new Uint8Array(dataBuf), 0);
213
+ reedSolomon.encode(shards, k, m);
214
+ const res = [];
215
+ for (let i = 0; i < k; i++) {
216
+ res.push(
217
+ Buffer.from(shards.slice(i * shardSize, i * shardSize + shardSize))
218
+ );
222
219
  }
223
- if (step === "customContext") {
224
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
225
- /* @__PURE__ */ jsxs2(Text2, { children: [
226
- "\u2714 Checking for Aptos CLI >v7.2.0...",
227
- " ",
228
- aptosFound ? "found" : "not found"
229
- ] }),
230
- /* @__PURE__ */ jsxs2(Text2, { children: [
231
- "\u2714 Do you want to set up standard contexts (devnet, testnet, mainnet)?",
232
- " ",
233
- setupStandardContexts ? "Yes" : "No"
234
- ] }),
235
- /* @__PURE__ */ jsx2(Text2, { children: "Do you want to set up a custom context?" }),
236
- /* @__PURE__ */ jsx2(
237
- SelectInput,
238
- {
239
- items: [
240
- { label: "Yes", value: true },
241
- { label: "No", value: false }
242
- ],
243
- onSelect: (item) => {
244
- setSetupCustomContext(item.value);
245
- if (item.value) {
246
- setStep("customContextDetails");
247
- } else {
248
- setStep("setupAccount");
249
- }
250
- }
251
- }
220
+ for (let j = 0; j < m; j++) {
221
+ res.push(
222
+ Buffer.from(
223
+ shards.slice((k + j) * shardSize, (k + j) * shardSize + shardSize)
252
224
  )
253
- ] });
225
+ );
254
226
  }
255
- if (step === "customContextDetails") {
256
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
257
- /* @__PURE__ */ jsx2(Text2, { children: "\u2714 Do you want to set up a custom context? Yes" }),
258
- /* @__PURE__ */ jsx2(Text2, { children: "Context name? (default: staging)" }),
259
- /* @__PURE__ */ jsx2(
260
- TextInput2,
261
- {
262
- value: customContextName,
263
- onChange: setCustomContextName,
264
- onSubmit: () => setStep("shelbyRpcEndpoint")
265
- }
266
- )
267
- ] });
227
+ return new Promise((resolve2) => resolve2(res));
228
+ }
229
+
230
+ // ../../packages/sdk/dist/chunk-NUQZDY3N.mjs
231
+ var DEFAULT_SHELBY_BASE_URL = "https://api.shelby.dev";
232
+ var SHELBY_DEPLOYER = "0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5";
233
+ var ERASURE_K = 10;
234
+ var ERASURE_M = 6;
235
+ var CHUNKSET_SIZE_BYTES = 10 * 1024 * 1024;
236
+ function getChunksetSizeBytes() {
237
+ return CHUNKSET_SIZE_BYTES;
238
+ }
239
+
240
+ // ../../packages/sdk/dist/chunk-6CBXBS3X.mjs
241
+ import { AccountAddress as AccountAddress2 } from "@aptos-labs/ts-sdk";
242
+ import { z } from "zod";
243
+ var BlobNameSchema = z.string().min(1, "Blob name path parameter cannot be empty.").max(1024, "Blob name cannot exceed 1024 characters.").refine((name) => !name.endsWith("/"), {
244
+ message: "Blob name cannot end with a slash"
245
+ });
246
+ function roundSize(size) {
247
+ let ret = 0;
248
+ let remain = size;
249
+ while (remain > 0) {
250
+ ret += getChunksetSizeBytes();
251
+ remain -= getChunksetSizeBytes();
268
252
  }
269
- if (step === "shelbyRpcEndpoint") {
270
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
271
- /* @__PURE__ */ jsxs2(Text2, { children: [
272
- "\u2714 Context name? ",
273
- customContextName
274
- ] }),
275
- /* @__PURE__ */ jsx2(Text2, { children: "Shelby RPC endpoint? (default: https://shelby.rpc.staging.example.com)" }),
276
- /* @__PURE__ */ jsx2(
277
- TextInput2,
278
- {
279
- value: shelbyRpcEndpoint,
280
- onChange: setShelbyRpcEndpoint,
281
- onSubmit: () => setStep("aptosNetwork")
253
+ return ret;
254
+ }
255
+
256
+ // ../../packages/sdk/dist/chunk-27CPX5O2.mjs
257
+ import { z as z2 } from "zod";
258
+ var ChunksetCommitmentSchema = z2.object({
259
+ // Chunkset root (vector commitment of child chunks)
260
+ chunkset_root: z2.string().nullable(),
261
+ // the size is known statically from the current configuration
262
+ chunk_commitments: z2.array(z2.string())
263
+ }).refine(
264
+ (data) => {
265
+ return data.chunk_commitments.length === ERASURE_K + ERASURE_M;
266
+ },
267
+ {
268
+ message: `Chunkset must have exactly ${ERASURE_K + ERASURE_M} chunks (ERASURE_K + ERASURE_M = ${ERASURE_K} + ${ERASURE_M})`,
269
+ path: ["chunk_commitments"]
270
+ }
271
+ );
272
+ function expectedTotalChunksets(rawSize) {
273
+ return roundSize(rawSize) / getChunksetSizeBytes();
274
+ }
275
+ var BlobCommitmentsSchema = z2.object({
276
+ schema_version: z2.string(),
277
+ raw_data_size: z2.number(),
278
+ // FIXME I am not sure about this being here, or if it should be somewhere else
279
+ blob_merkle_root: z2.string(),
280
+ chunkset_commitments: z2.array(ChunksetCommitmentSchema)
281
+ }).refine(
282
+ (data) => {
283
+ return expectedTotalChunksets(data.raw_data_size) === data.chunkset_commitments.length;
284
+ },
285
+ {
286
+ message: "Total chunkset count mismatches with raw data size",
287
+ // FIXME put more details in here
288
+ path: ["chunkset_commitments"]
289
+ }
290
+ );
291
+ async function generateCommitments(fullData, onChunk, options) {
292
+ const chunksetCommitments = [];
293
+ const chunksetCommitmentHashes = [];
294
+ let rawDataSize = 0;
295
+ const chunksetGen = readInChunks(
296
+ fullData,
297
+ options?.chunksetSize ?? getChunksetSizeBytes()
298
+ );
299
+ for await (const [chunksetIdx, chunksetData] of chunksetGen) {
300
+ const chunkCommitments = [];
301
+ rawDataSize += chunksetData.length;
302
+ const paddedChunksetData = zeroPadBuffer(
303
+ chunksetData,
304
+ options?.chunksetSize ?? getChunksetSizeBytes()
305
+ );
306
+ const chunks = await erasureEncode(
307
+ paddedChunksetData,
308
+ options?.erasureK ?? ERASURE_K,
309
+ options?.erasureM ?? ERASURE_M
310
+ );
311
+ let chunkIdx = 0;
312
+ for (const chunkData of chunks) {
313
+ if (onChunk !== void 0) {
314
+ await onChunk(chunksetIdx, chunkIdx, chunkData);
315
+ }
316
+ const chunkHash = await concatHashes([chunkData]);
317
+ chunkCommitments.push(chunkHash);
318
+ chunkIdx += 1;
319
+ }
320
+ const h = await concatHashes(
321
+ chunkCommitments.map((chunk) => chunk.toUint8Array())
322
+ );
323
+ chunksetCommitments.push({
324
+ chunkset_root: h.toString(),
325
+ chunk_commitments: chunkCommitments.map((chunk) => chunk.toString())
326
+ });
327
+ chunksetCommitmentHashes.push(h);
328
+ }
329
+ return {
330
+ schema_version: "1.3",
331
+ raw_data_size: rawDataSize,
332
+ blob_merkle_root: (await concatHashes(
333
+ chunksetCommitmentHashes.map((chunk) => chunk.toUint8Array())
334
+ )).toString(),
335
+ chunkset_commitments: chunksetCommitments
336
+ };
337
+ }
338
+
339
+ // ../../packages/sdk/dist/chunk-BRCI47CW.mjs
340
+ import {
341
+ AccountAddress as AccountAddress3,
342
+ Aptos,
343
+ Hex as Hex2,
344
+ MoveVector
345
+ } from "@aptos-labs/ts-sdk";
346
+ var ShelbyBlobClient = class _ShelbyBlobClient {
347
+ aptos;
348
+ deployer;
349
+ /**
350
+ * The ShelbyBlobClient is used to interact with the Shelby contract on the Aptos blockchain. This
351
+ * includes functions like writing blob commitments, confirming chunks, and retrieving blob metadata.
352
+ *
353
+ * @param config.aptos.config - The Aptos config.
354
+ * @param config.shelbyDeployer - The deployer account address of the Shelby contract. If not provided, the default deployer address will be used.
355
+ *
356
+ * @example
357
+ * ```typescript
358
+ * const aptos = new Aptos(new AptosConfig({ network: Network.TESTNET }));
359
+ * const blobClient = new ShelbyBlobClient({ aptos });
360
+ * ```
361
+ */
362
+ constructor(config) {
363
+ this.aptos = new Aptos(config.aptos.config);
364
+ this.deployer = config.shelby?.deployer ?? AccountAddress3.fromString(SHELBY_DEPLOYER);
365
+ }
366
+ /**
367
+ * Retrieves the blob metadata from the blockchain. If it does not exist,
368
+ * returns `undefined`.
369
+ *
370
+ * @param params.account - The account namespace the blob is stored in (e.g. "0x1")
371
+ * @param params.name - The name of the blob (e.g. "foo/bar")
372
+ * @returns The blob metadata.
373
+ *
374
+ * @example
375
+ * ```typescript
376
+ * const metadata = await client.getBlobMetadata({
377
+ * account: AccountAddress.fromString("0x1"),
378
+ * name: "foo/bar.txt",
379
+ * });
380
+ * ```
381
+ */
382
+ async getBlobMetadata(params) {
383
+ try {
384
+ const rawMetadata = await this.aptos.view({
385
+ payload: {
386
+ function: `${this.deployer.toString()}::global_metadata::get_blob_metadata`,
387
+ functionArguments: [
388
+ createBlobKey({
389
+ account: params.account,
390
+ blobName: params.name
391
+ })
392
+ ]
282
393
  }
283
- )
284
- ] });
394
+ });
395
+ if (!rawMetadata?.[0]?.vec?.[0]) {
396
+ return void 0;
397
+ }
398
+ const metadata = rawMetadata[0].vec[0];
399
+ return {
400
+ blobMerkleRoot: Hex2.fromHexInput(
401
+ metadata.blob_commitment
402
+ ).toUint8Array(),
403
+ owner: AccountAddress3.fromString(metadata.owner),
404
+ name: params.name,
405
+ size: metadata.blob_size,
406
+ encoding: {
407
+ variant: "clay",
408
+ // TODO
409
+ erasureK: 10,
410
+ erasureM: 6,
411
+ chunksetSize: 10 * 1024 * 1024
412
+ },
413
+ expirationMicros: metadata.expiration_micros
414
+ };
415
+ } catch (error) {
416
+ if (error instanceof Error && // Depending on the network, the error message may show up differently.
417
+ (error.message?.includes("sub_status: Some(404)") || error.message?.includes("EBLOB_NOT_FOUND"))) {
418
+ return void 0;
419
+ }
420
+ throw error;
421
+ }
285
422
  }
286
- if (step === "aptosNetwork") {
287
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
288
- /* @__PURE__ */ jsxs2(Text2, { children: [
289
- "\u2714 Shelby RPC endpoint? ",
290
- shelbyRpcEndpoint
291
- ] }),
292
- /* @__PURE__ */ jsx2(Text2, { children: "Aptos network? (default: mainnet)" }),
293
- /* @__PURE__ */ jsx2(
294
- TextInput2,
423
+ /**
424
+ * Retrieves all the blobs and their metadata for an account from the
425
+ * blockchain.
426
+ *
427
+ * @param params.account - The account namespace the blobs are stored in (e.g. "0x1")
428
+ * @returns The blob metadata for all the blobs for the account.
429
+ *
430
+ * @example
431
+ * ```typescript
432
+ * // BlobMetadata[]
433
+ * const blobs = await client.getAccountBlobs({
434
+ * account: AccountAddress.fromString("0x1"),
435
+ * });
436
+ * ```
437
+ */
438
+ getAccountBlobs(_params) {
439
+ throw new Error("Not implemented");
440
+ }
441
+ /**
442
+ * Retrieves the blob chunks for a given blob from the blockchain. The blob chunk will contain
443
+ * the commitment, the storage provider location, and the status of the chunk (stored or pending).
444
+ *
445
+ * @param params.account - The account namespace the blob is stored in (e.g. "0x1")
446
+ * @param params.name - The name of the blob (e.g. "foo/bar")
447
+ * @returns The chunks that make up the blob.
448
+ *
449
+ * @example
450
+ * ```typescript
451
+ * // BlobChunk[]
452
+ * const chunks = await client.getBlobChunks({
453
+ * account: AccountAddress.fromString("0x1"),
454
+ * name: "foo/bar.txt",
455
+ * });
456
+ *
457
+ * const isStored = chunks.every((c) => c.location.variant === "stored");
458
+ * ```
459
+ */
460
+ getBlobChunks(_params) {
461
+ throw new Error("Not implemented");
462
+ }
463
+ /**
464
+ * Writes the blob commitments to the blockchain.
465
+ *
466
+ * If `data` is provided instead of `blobCommitments`, the data will be encoded into commitments before being written
467
+ * to the blockchain.
468
+ *
469
+ * @param params.signer - The account that is signing the transaction.
470
+ * @param params.blobName - The name of the blob (e.g. "foo/bar")
471
+ * @param params.expirationMicros - The expiration time of the blob in microseconds.
472
+ * @param params.options - Additional options for transaction building and encoding.
473
+ * @param params.blobCommitments - The blob commitments to write to the blockchain (required if `data` is not provided).
474
+ * @param params.data - The data to encode into commitments before writing to the blockchain (required if `blobCommitments` is not provided).
475
+ *
476
+ * @returns The blob commitments and the pending transaction.
477
+ *
478
+ * @example
479
+ * ```typescript
480
+ * const blobCommitments = await generateCommitments(data);
481
+ *
482
+ * const { transaction } = await client.registerBlob({
483
+ * account: signer,
484
+ * blobName: "foo/bar.txt",
485
+ * blobMerkleRoot: blobCommitments.blob_merkle_root,
486
+ * size: data.length,
487
+ * expirationMicros: Date.now() * 1000 + 3600_000_000, // 1 hour from now in microseconds
488
+ * });
489
+ * ```
490
+ */
491
+ async registerBlob(params) {
492
+ const transaction = await this.aptos.transaction.build.simple({
493
+ ...params.options?.build,
494
+ data: _ShelbyBlobClient.createWriteBlobCommitmentsPayload({
495
+ deployer: this.deployer,
496
+ account: params.account.accountAddress,
497
+ blobName: params.blobName,
498
+ blobSize: params.size,
499
+ blobMerkleRoot: params.blobMerkleRoot,
500
+ num_chunksets: expectedTotalChunksets(params.size),
501
+ expirationMicros: params.expirationMicros
502
+ }),
503
+ sender: params.account.accountAddress
504
+ });
505
+ return {
506
+ transaction: await this.aptos.signAndSubmitTransaction({
507
+ signer: params.account,
508
+ transaction
509
+ })
510
+ };
511
+ }
512
+ /**
513
+ * Confirms an array of signed chunk commitments for a blob. Once all chunks for a blob are confirmed, the blob is
514
+ * considered "stored" and can be retrieved by RPC nodes.
515
+ *
516
+ * @param params.signer - The account that is signing the transaction.
517
+ * @param params.account - The account namespace the blob is stored in (e.g. "0x1")
518
+ * @param params.blobName - The name of the blob (e.g. "foo/bar")
519
+ * @param params.signedChunksetChunkCommitments - The signed chunk commitments, signed by their storage provider.
520
+ * @param params.options - Additional options for transaction building and encoding.
521
+ *
522
+ * @returns The pending transaction response.
523
+ *
524
+ * @example
525
+ * ```typescript
526
+ * const { transaction } = await client.confirmBlobChunks({
527
+ * signer,
528
+ * account: AccountAddress.fromString("0x1"),
529
+ * blobName: "foo/bar.txt",
530
+ * signedChunksetChunkCommitments,
531
+ * });
532
+ * ```
533
+ */
534
+ async confirmBlobChunks(params) {
535
+ const transaction = await this.aptos.transaction.build.simple({
536
+ ...params.options?.build,
537
+ data: _ShelbyBlobClient.createConfirmBlobChunksPayload({
538
+ deployer: this.deployer,
539
+ account: params.account,
540
+ blobName: params.blobName,
541
+ signedChunksetChunkCommitments: params.signedChunksetChunkCommitments
542
+ }),
543
+ sender: params.signer.accountAddress
544
+ });
545
+ return {
546
+ transaction: await this.aptos.signAndSubmitTransaction({
547
+ signer: params.signer,
548
+ transaction
549
+ })
550
+ };
551
+ }
552
+ /**
553
+ * Creates a transaction payload to write blob commitments to the blockchain.
554
+ *
555
+ * @param params.deployer - The deployer account address of the Shelby contract. If not provided, the default deployer address will be used.
556
+ * @param params.account - The account namespace the blob is stored in (e.g. "0x1")
557
+ * @param params.blobName - The name of the blob (e.g. "foo/bar")
558
+ * @param params.blobMerkleRoot - The blob merkle root.
559
+ * @param params.expirationMicros - The expiration time of the blob in microseconds.
560
+ * @param params.size - The size of the blob in bytes.
561
+ *
562
+ * @see https://github.com/JumpCrypto/shelby/blob/e009607aad330ccddb08d80bf9addfaadae7972b/move/prototype/move/sources/prototype_interface.move#L211-L220
563
+ */
564
+ static createWriteBlobCommitmentsPayload(params) {
565
+ return {
566
+ function: `${(params.deployer ?? SHELBY_DEPLOYER).toString()}::global_metadata::register_blob`,
567
+ functionArguments: [
568
+ params.blobName,
569
+ params.expirationMicros,
570
+ MoveVector.U8(params.blobMerkleRoot),
571
+ params.num_chunksets,
572
+ params.blobSize,
573
+ 0,
574
+ // payment tier
575
+ 0
576
+ // encoding
577
+ ]
578
+ };
579
+ }
580
+ /**
581
+ * Creates a transaction payload to confirm the chunks of a blob.
582
+ *
583
+ * @param params.deployer - The deployer account address of the Shelby contract. If not provided, the default deployer address will be used.
584
+ * @param params.account - The account namespace the blob is stored in (e.g. "0x1")
585
+ * @param params.blobName - The name of the blob (e.g. "foo/bar")
586
+ * @param params.signedChunksetChunkCommitments - The signed chunk commitments, signed by their storage provider.
587
+ *
588
+ * @see https://github.com/JumpCrypto/shelby/blob/e009607aad330ccddb08d80bf9addfaadae7972b/move/prototype/move/sources/prototype_interface.move#L343-L349
589
+ */
590
+ static createConfirmBlobChunksPayload(params) {
591
+ return {
592
+ function: `${(params.deployer ?? SHELBY_DEPLOYER).toString()}::prototype_interface::write_complete`,
593
+ functionArguments: [
594
+ createBlobKey({
595
+ account: params.account,
596
+ blobName: params.blobName
597
+ }),
598
+ params.signedChunksetChunkCommitments.map(
599
+ (chunkset) => chunkset.map((chunk) => AccountAddress3.from(chunk.provider))
600
+ ),
601
+ params.signedChunksetChunkCommitments.map(
602
+ (chunkset) => chunkset.map((chunk) => MoveVector.U8(chunk.signedCommitment))
603
+ ),
604
+ true
605
+ ]
606
+ };
607
+ }
608
+ };
609
+
610
+ // ../../packages/sdk/dist/chunk-I6NG5GNL.mjs
611
+ function sleep(ms) {
612
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
613
+ }
614
+
615
+ // ../../packages/sdk/dist/chunk-7KAW6I42.mjs
616
+ import { AccountAddress as AccountAddress4 } from "@aptos-labs/ts-sdk";
617
+ function encodeURIComponentKeepSlashes(str) {
618
+ return encodeURIComponent(str).replace(/%2F/g, "/");
619
+ }
620
+ var ShelbyRPCClient = class {
621
+ baseUrl;
622
+ /**
623
+ * The ShelbyRPCClient is used to interact with the Shelby RPC node. This
624
+ * includes functions like uploading blobs after they have been committed to the
625
+ * blockchain and downloading blobs.
626
+ *
627
+ * @param config.aptos.config - The Aptos config.
628
+ * @param config.shelby.baseUrl - The base URL of the Shelby RPC node.
629
+ *
630
+ * @example
631
+ * ```typescript
632
+ * const aptos = new Aptos(new AptosConfig({ network: Network.TESTNET }));
633
+ * const client = new ShelbyRPCClient({ aptos, shelby: { baseUrl: "https://api.shelby.dev" } });
634
+ * ```
635
+ */
636
+ constructor(config) {
637
+ this.baseUrl = config.shelby?.baseUrl ?? DEFAULT_SHELBY_BASE_URL;
638
+ }
639
+ async #uploadPart(uploadId, partIdx, partData) {
640
+ const nRetries = 5;
641
+ for (let i = 0; i < nRetries; ++i) {
642
+ const partResponse = await fetch(
643
+ `${this.baseUrl}/v1/multipart-uploads/${uploadId}/parts/${partIdx}`,
295
644
  {
296
- value: aptosNetwork,
297
- onChange: setAptosNetwork,
298
- onSubmit: () => setStep("setupAccount")
645
+ method: "PUT",
646
+ headers: {
647
+ "Content-Type": "application/octet-stream"
648
+ },
649
+ body: partData
299
650
  }
300
- )
301
- ] });
651
+ );
652
+ if (partResponse.ok) return;
653
+ if (i < nRetries - 1) {
654
+ const delay = 2 ** i * 100;
655
+ await sleep(delay);
656
+ }
657
+ }
658
+ throw new Error(`Failed to upload part ${partIdx}.`);
302
659
  }
303
- if (step === "setupAccount") {
304
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
305
- /* @__PURE__ */ jsx2(Text2, { children: "Create or update an account now?" }),
306
- /* @__PURE__ */ jsx2(
307
- SelectInput,
308
- {
309
- items: [
310
- { label: "Yes", value: true },
311
- { label: "No", value: false }
312
- ],
313
- onSelect: (item) => {
314
- setSetupAccount(item.value);
315
- if (item.value) {
316
- setStep("accountName");
317
- } else {
318
- setStep("complete");
660
+ async #putBlobMultipart(account, blobName, blobData, partSize = 5 * 1024 * 1024) {
661
+ const startResponse = await fetch(`${this.baseUrl}/v1/multipart-uploads`, {
662
+ method: "POST",
663
+ headers: {
664
+ "Content-Type": "application/json"
665
+ },
666
+ body: JSON.stringify({
667
+ rawAccount: account.toString(),
668
+ rawBlobName: blobName,
669
+ rawPartSize: partSize
670
+ })
671
+ });
672
+ if (!startResponse.ok) {
673
+ let errorBodyText = "Could not read error body";
674
+ try {
675
+ errorBodyText = await startResponse.text();
676
+ } catch (_e) {
677
+ }
678
+ throw new Error(
679
+ `Failed to start multipart upload! status: ${startResponse.status}, body: ${errorBodyText}`
680
+ );
681
+ }
682
+ const { uploadId } = await startResponse.json();
683
+ const totalParts = Math.ceil(blobData.length / partSize);
684
+ for (let partIdx = 0; partIdx < totalParts; partIdx++) {
685
+ const start = partIdx * partSize;
686
+ const end = Math.min(start + partSize, blobData.length);
687
+ const partData = blobData.slice(start, end);
688
+ await this.#uploadPart(uploadId, partIdx, partData);
689
+ }
690
+ const completeResponse = await fetch(
691
+ `${this.baseUrl}/v1/multipart-uploads/${uploadId}/complete`,
692
+ {
693
+ method: "POST",
694
+ headers: {
695
+ "Content-Type": "application/json"
696
+ }
697
+ }
698
+ );
699
+ if (!completeResponse.ok) {
700
+ let errorBodyText = "Could not read error body";
701
+ try {
702
+ errorBodyText = await completeResponse.text();
703
+ } catch (_e) {
704
+ }
705
+ throw new Error(
706
+ `Failed to complete multipart upload! status: ${completeResponse.status}, body: ${errorBodyText}`
707
+ );
708
+ }
709
+ }
710
+ /**
711
+ * Uploads blob data to the Shelby RPC node to be stored and confirmed by storage providers. This should be performed after the blob
712
+ * commitments have been written to the blockchain.
713
+ *
714
+ * @param params.account - The account namespace the blob is stored in (e.g. "0x1")
715
+ * @param params.blobName - The name of the blob (e.g. "foo/bar")
716
+ * @param params.blobData - The data to upload.
717
+ *
718
+ * @example
719
+ * ```typescript
720
+ * const blobData = new TextEncoder().encode("Hello, world!");
721
+ *
722
+ * await client.putBlob({ account, blobName: "foo/bar.txt", blobData });
723
+ * ```
724
+ */
725
+ async putBlob(params) {
726
+ BlobNameSchema.parse(params.blobName);
727
+ await this.#putBlobMultipart(
728
+ params.account,
729
+ params.blobName,
730
+ params.blobData
731
+ );
732
+ }
733
+ // FIXME make this possible to stream in put ^^^
734
+ /**
735
+ * Downloads a blob from the Shelby RPC node.
736
+ *
737
+ * @param params.account - The account namespace the blob is stored in (e.g. "0x1")
738
+ * @param params.blobName - The name of the blob (e.g. "foo/bar")
739
+ * @param params.range - The range of the blob to download.
740
+ *
741
+ * @returns A `ShelbyBlob` object containing the blob data.
742
+ *
743
+ * @example
744
+ * ```typescript
745
+ * const blob = await client.getBlob({
746
+ * account,
747
+ * blobName: "foo/bar.txt",
748
+ * });
749
+ * ```
750
+ */
751
+ async getBlob(params) {
752
+ BlobNameSchema.parse(params.blobName);
753
+ const url = `${this.baseUrl}/v1/blobs/${params.account.toString()}/${encodeURIComponentKeepSlashes(params.blobName)}`;
754
+ const requestInit = {};
755
+ if (params.range !== void 0) {
756
+ const headers = new Headers();
757
+ const { start, end } = params.range;
758
+ if (end === void 0) {
759
+ headers.set("Range", `bytes=${start}-`);
760
+ } else {
761
+ if (end < start) {
762
+ throw new Error("Range end cannot be less than start.");
763
+ }
764
+ headers.set("Range", `bytes=${start}-${end}`);
765
+ }
766
+ requestInit.headers = headers;
767
+ }
768
+ const response = await fetch(url, requestInit);
769
+ if (!response.ok) {
770
+ throw new Error(
771
+ `Failed to download blob: ${response.status} ${response.statusText}`
772
+ );
773
+ }
774
+ if (!response.body) {
775
+ throw new Error("Response body is null");
776
+ }
777
+ const contentLengthHeader = response.headers.get("content-length");
778
+ if (contentLengthHeader === null) {
779
+ throw new Error(
780
+ "Response did not have content-length header, which is required"
781
+ );
782
+ }
783
+ const expectedContentLength = Number.parseInt(contentLengthHeader, 10);
784
+ if (Number.isNaN(expectedContentLength)) {
785
+ throw new Error(
786
+ `Invalid content-length header received: ${contentLengthHeader}`
787
+ );
788
+ }
789
+ const validatingStream = new ReadableStream({
790
+ start(controller) {
791
+ const maybeReader = response.body?.getReader();
792
+ if (!maybeReader) {
793
+ controller.error(new Error("Response body reader is unavailable"));
794
+ return;
795
+ }
796
+ const reader = maybeReader;
797
+ let bytesReceived = 0;
798
+ function pump() {
799
+ return reader.read().then(({ done, value }) => {
800
+ if (done) {
801
+ if (bytesReceived !== expectedContentLength) {
802
+ controller.error(
803
+ new Error(
804
+ `Downloaded data size (${bytesReceived} bytes) does not match content-length header (${expectedContentLength} bytes). This might indicate a partial or corrupted download.`
805
+ )
806
+ );
807
+ return;
808
+ }
809
+ controller.close();
810
+ return;
319
811
  }
320
- }
812
+ bytesReceived += value.byteLength;
813
+ controller.enqueue(value);
814
+ return pump();
815
+ }).catch((error) => {
816
+ controller.error(error);
817
+ });
321
818
  }
322
- )
323
- ] });
819
+ return pump();
820
+ }
821
+ });
822
+ return {
823
+ account: AccountAddress4.from(params.account),
824
+ name: params.blobName,
825
+ readable: validatingStream,
826
+ contentLength: expectedContentLength
827
+ };
828
+ }
829
+ };
830
+
831
+ // ../../packages/sdk/dist/chunk-WHZVCCJD.mjs
832
+ import {
833
+ Aptos as Aptos2
834
+ } from "@aptos-labs/ts-sdk";
835
+ var ShelbyClient = class {
836
+ /**
837
+ * The coordination client is used to interact with the Aptos blockchain which handles the commitments
838
+ * and metadata for blobs.
839
+ */
840
+ coordination;
841
+ /**
842
+ * The RPC client is used to interact with the Shelby RPC node which can be responsible for storing,
843
+ * confirming, and retrieving blobs from the storage layer.
844
+ */
845
+ rpc;
846
+ /**
847
+ * The configuration for the Shelby client.
848
+ */
849
+ config;
850
+ /**
851
+ * The Aptos client.
852
+ */
853
+ aptos;
854
+ /**
855
+ * The base class for Shelby clients
856
+ *
857
+ * @param config.aptos.config - The Aptos config.
858
+ * @param config.shelby.baseUrl - The base URL of the Shelby RPC node. If not provided, the default base URL will be used.
859
+ */
860
+ constructor(config) {
861
+ this.config = config;
862
+ this.aptos = new Aptos2(this.config.aptos.config);
863
+ this.coordination = new ShelbyBlobClient(config);
864
+ this.rpc = new ShelbyRPCClient(config);
865
+ }
866
+ /**
867
+ * The base URL for the Shelby RPC node.
868
+ */
869
+ get baseUrl() {
870
+ return this.config.shelby?.baseUrl ?? DEFAULT_SHELBY_BASE_URL;
871
+ }
872
+ /**
873
+ * Uploads a blob to the Shelby network.
874
+ *
875
+ * @param params.blobData - The data to upload.
876
+ * @param params.signer - The signer of the transaction.
877
+ * @param params.blobName - The name of the blob.
878
+ * @param params.expirationMicros - The expiration time of the blob in microseconds.
879
+ * @param params.options - The options for the upload.
880
+ *
881
+ * @returns The transaction and generated blob commitments.
882
+ */
883
+ async upload(params) {
884
+ await generateCommitments(
885
+ params.blobData,
886
+ void 0,
887
+ params.options?.encoding
888
+ );
889
+ }
890
+ /**
891
+ * Downloads a blob from the Shelby RPC node.
892
+ *
893
+ * @param params.account - The account namespace the blob is stored in (e.g. "0x1")
894
+ * @param params.blobName - The name of the blob (e.g. "foo/bar")
895
+ * @param params.range - The range of the blob to download.
896
+ *
897
+ * @returns A `ShelbyBlob` object containing the blob data.
898
+ *
899
+ * @example
900
+ * ```typescript
901
+ * const blob = await client.download({
902
+ * account,
903
+ * blobName: "foo/bar.txt",
904
+ * });
905
+ * ```
906
+ */
907
+ async download(params) {
908
+ return await this.rpc.getBlob(params);
909
+ }
910
+ };
911
+
912
+ // ../../packages/sdk/dist/chunk-YVPHW2RN.mjs
913
+ var ShelbyNodeClient = class extends ShelbyClient {
914
+ };
915
+
916
+ // ../../packages/sdk/dist/chunk-7P6ASYW6.mjs
917
+ var __defProp = Object.defineProperty;
918
+ var __export = (target, all) => {
919
+ for (var name in all)
920
+ __defProp(target, name, { get: all[name], enumerable: true });
921
+ };
922
+
923
+ // ../../packages/sdk/dist/chunk-A4IG6GSE.mjs
924
+ var testUtil_exports = {};
925
+ __export(testUtil_exports, {
926
+ makeChunk: () => makeChunk
927
+ });
928
+ function makeChunk(n) {
929
+ const c = Buffer.alloc(n);
930
+ for (let i = 0; i < n; ++i) {
931
+ c[i] = i % 256;
932
+ }
933
+ return c;
934
+ }
935
+
936
+ // src/commands/account.tsx
937
+ import Table from "cli-table3";
938
+ import { render } from "ink";
939
+ import { z as z6 } from "zod";
940
+
941
+ // src/components/AccountWizard.tsx
942
+ import { Box, Text } from "ink";
943
+ import TextInput from "ink-text-input";
944
+ import { useEffect, useState } from "react";
945
+
946
+ // src/utils/keys.ts
947
+ import {
948
+ Account,
949
+ AccountAddress as AccountAddress5,
950
+ Ed25519PrivateKey,
951
+ Secp256k1PrivateKey,
952
+ SigningSchemeInput
953
+ } from "@aptos-labs/ts-sdk";
954
+ function generateEd25519Account() {
955
+ const account = Account.generate({
956
+ scheme: SigningSchemeInput.Ed25519,
957
+ legacy: true
958
+ });
959
+ return account;
960
+ }
961
+ function isValidEd25519PrivateKey(value) {
962
+ try {
963
+ new Ed25519PrivateKey(value);
964
+ return true;
965
+ } catch {
966
+ return false;
324
967
  }
325
- if (step === "accountName") {
326
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
327
- /* @__PURE__ */ jsx2(Text2, { children: "\u2714 Create or update an account now? Yes" }),
328
- /* @__PURE__ */ jsx2(Text2, { children: "Account name? (default: alice)" }),
329
- /* @__PURE__ */ jsx2(
330
- TextInput2,
968
+ }
969
+ function isValidAddress(address) {
970
+ return AccountAddress5.isValid({ input: address }).valid;
971
+ }
972
+ var SECP256K1_NAME = "secp256k1";
973
+ var ED25519_NAME = "ed25519";
974
+ function isValidScheme(scheme) {
975
+ return SECP256K1_NAME === scheme || ED25519_NAME === scheme;
976
+ }
977
+
978
+ // src/components/AccountWizard.tsx
979
+ import { jsx, jsxs } from "react/jsx-runtime";
980
+ var AccountWizard = ({ onComplete }) => {
981
+ const [step, setStep] = useState("name");
982
+ const [name, setName] = useState("");
983
+ const [address, setAddress] = useState("");
984
+ const [privateKey, setPrivateKey] = useState("");
985
+ useEffect(() => {
986
+ if (step === "done") {
987
+ onComplete({
988
+ name,
989
+ address: address || void 0,
990
+ privateKey
991
+ });
992
+ }
993
+ }, [onComplete, step, name, address, privateKey]);
994
+ if (step === "name") {
995
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
996
+ /* @__PURE__ */ jsx(Text, { children: "Account name?" }),
997
+ /* @__PURE__ */ jsx(
998
+ TextInput,
331
999
  {
332
- value: accountName,
333
- onChange: setAccountName,
334
- onSubmit: () => setStep("signatureScheme")
1000
+ value: name,
1001
+ onChange: setName,
1002
+ onSubmit: () => setStep("address")
335
1003
  }
336
1004
  )
337
1005
  ] });
338
1006
  }
339
- if (step === "signatureScheme") {
340
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
341
- /* @__PURE__ */ jsxs2(Text2, { children: [
342
- "\u2714 Account name? ",
343
- accountName
344
- ] }),
345
- /* @__PURE__ */ jsx2(Text2, { children: "Signature scheme? (ed25519)" }),
346
- /* @__PURE__ */ jsx2(
347
- SelectInput,
1007
+ if (step === "address") {
1008
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
1009
+ /* @__PURE__ */ jsx(Text, { children: "Address (optional)?" }),
1010
+ /* @__PURE__ */ jsx(
1011
+ TextInput,
348
1012
  {
349
- items: [
350
- { label: ED25519_NAME, value: ED25519_NAME }
351
- // { label: SECP256K1_NAME, value: SECP256K1_NAME },
352
- ],
353
- onSelect: (item) => {
354
- setSignatureScheme(item.value);
355
- setStep("privateKey");
356
- }
1013
+ value: address,
1014
+ onChange: setAddress,
1015
+ onSubmit: () => setStep("key")
357
1016
  }
358
1017
  )
359
1018
  ] });
360
1019
  }
361
- if (step === "privateKey") {
362
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
363
- /* @__PURE__ */ jsxs2(Text2, { children: [
364
- "\u2714 Signature scheme? ",
365
- signatureScheme
366
- ] }),
367
- /* @__PURE__ */ jsx2(Text2, { children: "Private key? (leave blank to generate new key)" }),
368
- /* @__PURE__ */ jsx2(
369
- TextInput2,
1020
+ if (step === "key") {
1021
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
1022
+ /* @__PURE__ */ jsx(Text, { children: "Paste private key or leave blank to generate" }),
1023
+ /* @__PURE__ */ jsx(
1024
+ TextInput,
370
1025
  {
371
1026
  value: privateKey,
372
1027
  onChange: setPrivateKey,
373
1028
  onSubmit: () => {
374
1029
  if (!privateKey) {
375
- const newKey = generateEd25519Account();
376
- setGeneratedKey(newKey.privateKey.toAIP80String());
377
- setGeneratedAddress(newKey.accountAddress.toString());
1030
+ const acct = generateEd25519Account();
1031
+ setPrivateKey(acct.privateKey.toAIP80String());
1032
+ setAddress((prev) => prev || acct.accountAddress.toString());
378
1033
  }
379
- setStep("complete");
1034
+ setStep("done");
380
1035
  }
381
1036
  }
382
1037
  )
383
1038
  ] });
384
1039
  }
385
- return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: /* @__PURE__ */ jsx2(Text2, { children: "\u2705 Configuration complete!" }) });
1040
+ return null;
386
1041
  };
387
1042
 
388
1043
  // src/components/ContextWizard.tsx
389
- import { Box as Box3, Text as Text3 } from "ink";
390
- import TextInput3 from "ink-text-input";
391
- import { useEffect as useEffect3, useState as useState3 } from "react";
392
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1044
+ import { Box as Box2, Text as Text2 } from "ink";
1045
+ import TextInput2 from "ink-text-input";
1046
+ import { useEffect as useEffect2, useState as useState2 } from "react";
1047
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
393
1048
  var ContextWizard = ({ onComplete }) => {
394
- const [step, setStep] = useState3("name");
395
- const [name2, setName] = useState3("");
396
- const [shelbyRpcEndpoint, setShelbyRpcEndpoint] = useState3("");
397
- const [aptosNetwork, setAptosNetwork] = useState3("");
398
- useEffect3(() => {
1049
+ const [step, setStep] = useState2("name");
1050
+ const [name, setName] = useState2("");
1051
+ const [shelbyRpcEndpoint, setShelbyRpcEndpoint] = useState2("");
1052
+ const [aptosNetwork, setAptosNetwork] = useState2("");
1053
+ useEffect2(() => {
399
1054
  if (step === "done") {
400
- onComplete({ name: name2, shelbyRpcEndpoint, aptosNetwork });
1055
+ onComplete({ name, shelbyRpcEndpoint, aptosNetwork });
401
1056
  }
402
- }, [step, name2, shelbyRpcEndpoint, aptosNetwork, onComplete]);
1057
+ }, [step, name, shelbyRpcEndpoint, aptosNetwork, onComplete]);
403
1058
  if (step === "name") {
404
- return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
405
- /* @__PURE__ */ jsx3(Text3, { children: "Context name?" }),
406
- /* @__PURE__ */ jsx3(
407
- TextInput3,
1059
+ return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
1060
+ /* @__PURE__ */ jsx2(Text2, { children: "Context name?" }),
1061
+ /* @__PURE__ */ jsx2(
1062
+ TextInput2,
408
1063
  {
409
- value: name2,
1064
+ value: name,
410
1065
  onChange: setName,
411
1066
  onSubmit: () => setStep("shelbyRpc")
412
1067
  }
@@ -414,377 +1069,101 @@ var ContextWizard = ({ onComplete }) => {
414
1069
  ] });
415
1070
  }
416
1071
  if (step === "shelbyRpc") {
417
- return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
418
- /* @__PURE__ */ jsx3(Text3, { children: "Shelby RPC endpoint?" }),
419
- /* @__PURE__ */ jsx3(
420
- TextInput3,
421
- {
422
- value: shelbyRpcEndpoint,
423
- placeholder: "https://shelby.rpc.devnet.example.com",
424
- onChange: setShelbyRpcEndpoint,
425
- onSubmit: () => setStep("aptosApi")
426
- }
427
- )
428
- ] });
429
- }
430
- if (step === "aptosApi") {
431
- return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
432
- /* @__PURE__ */ jsx3(Text3, { children: "Aptos API endpoint?" }),
433
- /* @__PURE__ */ jsx3(
434
- TextInput3,
435
- {
436
- value: aptosNetwork,
437
- placeholder: "devnet",
438
- onChange: setAptosNetwork,
439
- onSubmit: () => setStep("done")
440
- }
441
- )
442
- ] });
443
- }
444
- return null;
445
- };
446
-
447
- // src/components/UpdateContextWizard.tsx
448
- import { Box as Box4, Text as Text4 } from "ink";
449
- import TextInput4 from "ink-text-input";
450
- import { useEffect as useEffect4, useState as useState4 } from "react";
451
-
452
- // src/schemas/AptosNetworkSchema.ts
453
- import { z } from "zod";
454
- var AptosNetworkSchema = z.enum([
455
- "mainnet",
456
- "testnet",
457
- "devnet",
458
- "local"
459
- ]);
460
-
461
- // src/schemas/EndpointSchema.ts
462
- import { z as z2 } from "zod";
463
- var EndpointSchema = z2.string().url("Must be a valid URL");
464
-
465
- // src/components/UpdateContextWizard.tsx
466
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
467
- var UpdateContextWizard = ({
468
- contextName,
469
- currentShelbyRpc,
470
- currentAptosNetwork,
471
- onComplete
472
- }) => {
473
- const [step, setStep] = useState4("shelbyRpc");
474
- const [shelbyRpcEndpoint, setShelbyRpcEndpoint] = useState4(currentShelbyRpc);
475
- const [aptosNetwork, setAptosNetwork] = useState4(currentAptosNetwork);
476
- const [error, setError] = useState4("");
477
- useEffect4(() => {
478
- if (step === "done") {
479
- const updates = {};
480
- if (shelbyRpcEndpoint !== currentShelbyRpc) {
481
- updates.shelbyRpcEndpoint = shelbyRpcEndpoint;
482
- }
483
- if (aptosNetwork !== currentAptosNetwork) {
484
- updates.aptosNetwork = aptosNetwork;
485
- }
486
- onComplete(updates);
487
- }
488
- }, [
489
- step,
490
- shelbyRpcEndpoint,
491
- aptosNetwork,
492
- currentShelbyRpc,
493
- currentAptosNetwork,
494
- onComplete
495
- ]);
496
- if (step === "shelbyRpc") {
497
- return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
498
- /* @__PURE__ */ jsxs4(Text4, { children: [
499
- "Updating context: ",
500
- contextName
501
- ] }),
502
- /* @__PURE__ */ jsxs4(Text4, { children: [
503
- "Shelby RPC endpoint? (current: ",
504
- currentShelbyRpc,
505
- ")"
506
- ] }),
507
- error && /* @__PURE__ */ jsxs4(Text4, { color: "red", children: [
508
- "Error: ",
509
- error
510
- ] }),
511
- /* @__PURE__ */ jsx4(
512
- TextInput4,
1072
+ return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
1073
+ /* @__PURE__ */ jsx2(Text2, { children: "Shelby RPC endpoint?" }),
1074
+ /* @__PURE__ */ jsx2(
1075
+ TextInput2,
513
1076
  {
514
1077
  value: shelbyRpcEndpoint,
515
- placeholder: currentShelbyRpc,
516
- onChange: (value) => {
517
- setShelbyRpcEndpoint(value);
518
- setError("");
519
- },
520
- onSubmit: () => {
521
- if (shelbyRpcEndpoint && shelbyRpcEndpoint !== currentShelbyRpc) {
522
- const result = EndpointSchema.safeParse(shelbyRpcEndpoint);
523
- if (!result.success) {
524
- setError(result.error.errors[0].message);
525
- return;
526
- }
527
- }
528
- setError("");
529
- setStep("aptosApi");
530
- }
531
- }
532
- ),
533
- /* @__PURE__ */ jsx4(Text4, { color: "gray", children: "Press Enter to continue" })
534
- ] });
535
- }
536
- if (step === "aptosApi") {
537
- return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
538
- /* @__PURE__ */ jsxs4(Text4, { children: [
539
- "Aptos network? (current: ",
540
- currentAptosNetwork,
541
- ")"
542
- ] }),
543
- error && /* @__PURE__ */ jsxs4(Text4, { color: "red", children: [
544
- "Error: ",
545
- error
546
- ] }),
547
- /* @__PURE__ */ jsx4(
548
- TextInput4,
1078
+ placeholder: "https://shelby.rpc.devnet.example.com",
1079
+ onChange: setShelbyRpcEndpoint,
1080
+ onSubmit: () => setStep("aptosApi")
1081
+ }
1082
+ )
1083
+ ] });
1084
+ }
1085
+ if (step === "aptosApi") {
1086
+ return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
1087
+ /* @__PURE__ */ jsx2(Text2, { children: "Aptos API endpoint?" }),
1088
+ /* @__PURE__ */ jsx2(
1089
+ TextInput2,
549
1090
  {
550
1091
  value: aptosNetwork,
551
- placeholder: currentAptosNetwork,
552
- onChange: (value) => {
553
- setAptosNetwork(value);
554
- setError("");
555
- },
556
- onSubmit: () => {
557
- if (aptosNetwork && aptosNetwork !== currentAptosNetwork) {
558
- const result = AptosNetworkSchema.safeParse(aptosNetwork);
559
- if (!result.success) {
560
- setError("Must be one of: mainnet, testnet, devnet, local");
561
- return;
562
- }
563
- }
564
- setError("");
565
- setStep("done");
566
- }
1092
+ placeholder: "devnet",
1093
+ onChange: setAptosNetwork,
1094
+ onSubmit: () => setStep("done")
567
1095
  }
568
- ),
569
- /* @__PURE__ */ jsx4(Text4, { color: "gray", children: "Valid options: mainnet, testnet, devnet, local" }),
570
- /* @__PURE__ */ jsx4(Text4, { color: "gray", children: "Press Enter to save changes" })
1096
+ )
571
1097
  ] });
572
1098
  }
573
1099
  return null;
574
1100
  };
575
1101
 
576
- // src/utils/config.ts
577
- import os from "os";
578
- import path from "path";
579
- import {
580
- AptosConfig,
581
- Ed25519Account,
582
- Ed25519PrivateKey as Ed25519PrivateKey2,
583
- NetworkToNetworkName
584
- } from "@aptos-labs/ts-sdk";
585
- import fs from "fs-extra";
586
- import YAML from "yaml";
587
- import { z as z3 } from "zod";
588
-
589
- // tests/utils/mockConfig.ts
590
- var mockAccountAlice = generateEd25519Account();
591
- var mockAccountBob = generateEd25519Account();
592
- var mockConfig = {
593
- contexts: {
594
- devnet: {
595
- aptos_network: "devnet",
596
- shelby_rpc_endpoint: "https://shelby.rpc.devnet.example.com"
597
- },
598
- testnet: {
599
- aptos_network: "testnet",
600
- shelby_rpc_endpoint: "https://shelby.rpc.testnet.example.com"
601
- },
602
- mainnet: {
603
- aptos_network: "mainnet",
604
- shelby_rpc_endpoint: "https://shelby.rpc.mainnet.example.com"
605
- }
606
- },
607
- accounts: {
608
- alice: {
609
- address: mockAccountAlice.accountAddress.toString(),
610
- private_key: mockAccountAlice.privateKey.toAIP80String()
611
- },
612
- bob: {
613
- private_key: mockAccountBob.privateKey.toAIP80String(),
614
- address: mockAccountBob.accountAddress.toString()
615
- }
616
- },
617
- default_context: "devnet",
618
- default_account: "alice"
619
- };
620
-
621
- // src/utils/constants.ts
622
- var DEFAULT_CONFIG_PATH = "~/.shelby/config.yaml";
1102
+ // src/components/InitWizard.tsx
1103
+ import { Box as Box3, Text as Text3 } from "ink";
1104
+ import SelectInput from "ink-select-input";
1105
+ import Spinner from "ink-spinner";
1106
+ import TextInput3 from "ink-text-input";
1107
+ import { useEffect as useEffect3, useState as useState3 } from "react";
623
1108
 
624
- // src/utils/config.ts
625
- var ContextSchema = z3.object({
626
- aptos_network: AptosNetworkSchema,
627
- shelby_rpc_endpoint: EndpointSchema
628
- });
629
- var ConfigSchema = z3.object({
630
- contexts: z3.record(ContextSchema),
631
- accounts: z3.record(
632
- z3.object({
633
- address: z3.string().optional(),
634
- private_key: z3.string({ message: "private_key must be provided" })
635
- })
636
- ),
637
- default_context: z3.string(),
638
- default_account: z3.string()
639
- });
640
- function resolveConfigPath(configPath) {
641
- if (configPath.startsWith("~")) {
642
- return path.join(os.homedir(), configPath.slice(1));
643
- }
644
- return configPath;
645
- }
646
- function loadConfig(configPath = DEFAULT_CONFIG_PATH) {
647
- const resolvedPath = resolveConfigPath(configPath);
648
- const dir = path.dirname(resolvedPath);
649
- if (!fs.existsSync(resolvedPath)) {
650
- fs.mkdirpSync(dir);
651
- const yamlText = YAML.stringify(mockConfig);
652
- fs.writeFileSync(resolvedPath, yamlText, "utf8");
653
- return mockConfig;
654
- }
655
- const raw = fs.readFileSync(resolvedPath, "utf8");
656
- let parsed;
657
- try {
658
- parsed = YAML.parse(raw);
659
- } catch {
660
- throw new Error("Invalid config file");
661
- }
1109
+ // src/utils/version.ts
1110
+ import { execSync } from "child_process";
1111
+ import semver from "semver";
1112
+ var MIN_APTOS_CLI_VERSION = "7.6.0";
1113
+ function getAptosCliVersion() {
662
1114
  try {
663
- return ConfigSchema.parse(parsed);
664
- } catch (err) {
665
- throw new Error(`Invalid config file: ${err.message}`);
666
- }
667
- }
668
- function saveConfig(config, configPath = "~/.shelby/config.yaml") {
669
- const resolvedPath = resolveConfigPath(configPath);
670
- fs.mkdirpSync(path.dirname(resolvedPath));
671
- ConfigSchema.parse(config);
672
- fs.writeFileSync(resolvedPath, YAML.stringify(config), "utf8");
673
- }
674
- function getCurrentAccount(config, accountName) {
675
- const name2 = accountName || config.default_account;
676
- if (!name2) {
677
- throw new Error(`Account with name '${name2}' not found in config`);
678
- }
679
- const account = config.accounts[name2];
680
- if (!account) {
681
- throw new Error(`Account '${name2}' not found in config`);
682
- }
683
- let privateKey;
684
- if (account.private_key) {
685
- privateKey = account.private_key;
686
- } else {
687
- throw new Error(`No private key found for account '${name2}'`);
688
- }
689
- return {
690
- address: account.address,
691
- privateKey,
692
- account: new Ed25519Account({
693
- privateKey: new Ed25519PrivateKey2(privateKey)
694
- })
695
- };
696
- }
697
- function getCurrentShelbyConfig(config, opts = {
698
- context: config.default_context
699
- }) {
700
- const { context } = opts;
701
- const selectedContext = config.contexts[context ?? config.default_context];
702
- if (!selectedContext) {
703
- throw new Error(
704
- `Context '${context ?? config.default_context}' not found in config`
1115
+ const aptosVersionOutput = execSync("aptos --version").toString().trim();
1116
+ const versionMatch = aptosVersionOutput.match(
1117
+ /aptos (\d+\.\d+\.\d+(?:-[\w.-]+)?)/
705
1118
  );
1119
+ return versionMatch ? versionMatch[1] : null;
1120
+ } catch (_error) {
1121
+ return null;
706
1122
  }
707
- const aptosNetwork = NetworkToNetworkName[selectedContext.aptos_network];
708
- if (!aptosNetwork) {
709
- throw new Error(`Invalid Aptos network: ${selectedContext.aptos_network}`);
710
- }
711
- return {
712
- aptos: { config: new AptosConfig({ network: aptosNetwork }) },
713
- shelby: { baseUrl: selectedContext.shelby_rpc_endpoint }
714
- };
715
- }
716
-
717
- // src/utils/paths.ts
718
- import path2 from "path";
719
- function normBlobName(pathModule, inputDirectoryName, filename, blobPrefix) {
720
- const blobNameWithoutInputDir = pathModule.relative(
721
- inputDirectoryName,
722
- filename
723
- );
724
- const blobNameWithPrefix = pathModule.join(
725
- blobPrefix,
726
- blobNameWithoutInputDir
727
- );
728
- const blobNameNormalized = pathModule.normalize(blobNameWithPrefix);
729
- const parts = blobNameNormalized.split(pathModule.sep);
730
- return path2.posix.join(...parts);
731
1123
  }
732
- function denormBlobName(pathModule, blobPrefix, blobName, outputPrefix) {
733
- if (!pathModule.isAbsolute(outputPrefix)) {
734
- throw new Error(`Output prefix '${outputPrefix}' must be an absolute path`);
735
- }
736
- if (!blobName.startsWith(blobPrefix)) {
737
- throw new Error(
738
- `Blob name '${blobName}' does not start with prefix '${blobPrefix}'`
739
- );
740
- }
741
- const relativePath = blobName.slice(blobPrefix.length);
742
- const pathParts = relativePath.split("/").filter((part) => part.length > 0);
743
- if (pathParts.length === 0) {
744
- return outputPrefix;
745
- }
746
- return pathModule.join(outputPrefix, ...pathParts);
1124
+ function getAptosCliVersionInfo(minVersion = MIN_APTOS_CLI_VERSION) {
1125
+ const version2 = getAptosCliVersion();
1126
+ const meetsRequirement = version2 ? semver.gte(version2, minVersion) : false;
1127
+ return { version: version2, meetsRequirement };
747
1128
  }
748
1129
 
749
- // src/commands/init.tsx
750
- import { jsx as jsx5 } from "react/jsx-runtime";
751
- function initCommand(program) {
752
- program.command("init").description(
753
- "Bootstrap your Shelby config via an interactive wizard or flags"
754
- ).option(
755
- "--setup-default-contexts",
756
- "Create devnet, testnet, mainnet contexts",
757
- false
758
- ).option("--context <name>", "Custom context name").option(
759
- "--shelby-rpc-endpoint <url>",
760
- "Shelby RPC endpoint for this context"
761
- ).option(
762
- "--aptos-api-endpoint <url>",
763
- "Aptos REST API endpoint for this context"
764
- ).option(
765
- "--account <name>",
766
- "Account name to create/update",
767
- "default_account"
768
- ).option(
769
- "--signature-scheme <scheme>",
770
- // "Signature scheme (ed25519 or secp256k1)",
771
- "Signature scheme (ed25519)",
772
- ED25519_NAME
773
- ).option("--private-key <key>", "Raw private key").action(async (options) => {
774
- const configPath = program.opts().configFile || "~/.shelby/config.yaml";
775
- if (options.setupDefaultContexts || options.context && options.shelbyRpcEndpoint && options.aptosNetwork) {
776
- let config;
777
- try {
778
- config = loadConfig(configPath);
779
- } catch (error) {
780
- config = {
781
- contexts: {},
782
- accounts: {},
783
- default_context: options.setupDefaultContexts ? "devnet" : options.context,
784
- default_account: options.account
785
- };
786
- }
787
- if (options.setupDefaultContexts) {
1130
+ // src/components/InitWizard.tsx
1131
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1132
+ var InitWizard = ({ onComplete }) => {
1133
+ const [step, setStep] = useState3("checkAptos");
1134
+ const [aptosCliMeetsRequirement, setAptosCliMeetsRequirement] = useState3(false);
1135
+ const [aptosCliVersion, setAptosCliVersion] = useState3(null);
1136
+ const [setupStandardContexts, setSetupStandardContexts] = useState3(false);
1137
+ const [setupCustomContext, setSetupCustomContext] = useState3(false);
1138
+ const [customContextName, setCustomContextName] = useState3("staging");
1139
+ const [shelbyRpcEndpoint, setShelbyRpcEndpoint] = useState3(
1140
+ "https://shelby.rpc.staging.example.com"
1141
+ );
1142
+ const [aptosNetwork, setAptosNetwork] = useState3("mainnet");
1143
+ const [setupAccount, setSetupAccount] = useState3(false);
1144
+ const [accountName, setAccountName] = useState3("alice");
1145
+ const [signatureScheme, setSignatureScheme] = useState3("ed25519");
1146
+ const [privateKey, setPrivateKey] = useState3("");
1147
+ const [address, _setAddress] = useState3("");
1148
+ const [generatedKey, setGeneratedKey] = useState3("");
1149
+ const [generatedAddress, setGeneratedAddress] = useState3("");
1150
+ useEffect3(() => {
1151
+ if (step === "checkAptos") {
1152
+ const { version: version2, meetsRequirement } = getAptosCliVersionInfo();
1153
+ setAptosCliVersion(version2);
1154
+ setAptosCliMeetsRequirement(meetsRequirement);
1155
+ setStep("standardContexts");
1156
+ }
1157
+ }, [step]);
1158
+ useEffect3(() => {
1159
+ if (step === "complete") {
1160
+ const config = {
1161
+ contexts: {},
1162
+ accounts: {},
1163
+ default_context: setupStandardContexts ? "devnet" : customContextName,
1164
+ default_account: setupAccount ? accountName : "default_account"
1165
+ };
1166
+ if (setupStandardContexts) {
788
1167
  config.contexts.local = {
789
1168
  aptos_network: "local",
790
1169
  shelby_rpc_endpoint: "http://localhost:9090"
@@ -802,704 +1181,535 @@ function initCommand(program) {
802
1181
  shelby_rpc_endpoint: "https://shelby.rpc.mainnet.example.com"
803
1182
  };
804
1183
  }
805
- if (options.context && options.shelbyRpcEndpoint && options.aptosNetwork) {
806
- config.contexts[options.context] = {
807
- aptos_network: options.aptosNetwork,
808
- shelby_rpc_endpoint: options.shelbyRpcEndpoint
1184
+ if (setupCustomContext) {
1185
+ config.contexts[customContextName] = {
1186
+ aptos_network: aptosNetwork,
1187
+ shelby_rpc_endpoint: shelbyRpcEndpoint
809
1188
  };
810
1189
  }
811
- if (options.privateKey) {
812
- config.accounts[options.account] = {
813
- private_key: options.privateKey
1190
+ if (setupAccount) {
1191
+ const finalPrivateKey = privateKey || generatedKey;
1192
+ const finalAddress = address || generatedAddress;
1193
+ config.accounts[accountName] = {
1194
+ private_key: finalPrivateKey,
1195
+ address: finalAddress
814
1196
  };
815
1197
  }
816
- saveConfig(config, configPath);
817
- console.log(
818
- `\u2705 Configuration saved to ${resolveConfigPath(configPath)}`
819
- );
820
- } else {
821
- const { unmount } = render(
822
- /* @__PURE__ */ jsx5(
823
- InitWizard,
824
- {
825
- onComplete: (config) => {
826
- saveConfig(config, configPath);
827
- console.log(
828
- `\u2705 Configuration saved to ${resolveConfigPath(configPath)}`
829
- );
830
- if (config.default_account && config.accounts[config.default_account]?.private_key?.startsWith("ed25519-priv-")) {
831
- console.log(
832
- "\n\u2139\uFE0F To fund your new account on-chain (devnet/testnet only):"
833
- );
834
- console.log(" 1. Import the private key into Aptos CLI:");
835
- console.log(
836
- ` aptos init --profile ${config.default_account} --private-key ${config.accounts[config.default_account].private_key} --network ${config.default_context}`
837
- );
838
- console.log(" 2. Run the faucet:");
839
- console.log(
840
- ` aptos account fund-with-faucet --profile ${config.default_account}`
841
- );
842
- }
843
- unmount();
844
- process.exit(0);
1198
+ onComplete(config);
1199
+ }
1200
+ }, [step]);
1201
+ if (step === "checkAptos") {
1202
+ return /* @__PURE__ */ jsx3(Box3, { children: /* @__PURE__ */ jsxs3(Text3, { children: [
1203
+ /* @__PURE__ */ jsx3(Spinner, { type: "dots" }),
1204
+ " Checking for Aptos CLI >=v",
1205
+ MIN_APTOS_CLI_VERSION,
1206
+ "..."
1207
+ ] }) });
1208
+ }
1209
+ if (step === "standardContexts") {
1210
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
1211
+ /* @__PURE__ */ jsxs3(Text3, { children: [
1212
+ "\u2714 Checking for Aptos CLI >=v",
1213
+ MIN_APTOS_CLI_VERSION,
1214
+ "...",
1215
+ " ",
1216
+ aptosCliMeetsRequirement ? "found" : "not found"
1217
+ ] }),
1218
+ !aptosCliMeetsRequirement && aptosCliVersion && /* @__PURE__ */ jsxs3(Text3, { color: "yellow", children: [
1219
+ "Warning: Found Aptos CLI v",
1220
+ aptosCliVersion,
1221
+ ", but v",
1222
+ MIN_APTOS_CLI_VERSION,
1223
+ " or higher is required. Please update."
1224
+ ] }),
1225
+ !aptosCliMeetsRequirement && !aptosCliVersion && /* @__PURE__ */ jsx3(Text3, { color: "yellow", children: "Warning: Aptos CLI not found. Please install." }),
1226
+ /* @__PURE__ */ jsx3(Text3, { children: "Do you want to set up standard contexts (devnet, testnet, mainnet)?" }),
1227
+ /* @__PURE__ */ jsx3(
1228
+ SelectInput,
1229
+ {
1230
+ items: [
1231
+ { label: "Yes", value: true },
1232
+ { label: "No", value: false }
1233
+ ],
1234
+ onSelect: (item) => {
1235
+ setSetupStandardContexts(item.value);
1236
+ setStep("customContext");
1237
+ }
1238
+ }
1239
+ )
1240
+ ] });
1241
+ }
1242
+ if (step === "customContext") {
1243
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
1244
+ /* @__PURE__ */ jsxs3(Text3, { children: [
1245
+ "\u2714 Checking for Aptos CLI >=v",
1246
+ MIN_APTOS_CLI_VERSION,
1247
+ "...",
1248
+ " ",
1249
+ aptosCliMeetsRequirement ? "found" : "not found"
1250
+ ] }),
1251
+ /* @__PURE__ */ jsxs3(Text3, { children: [
1252
+ "\u2714 Do you want to set up standard contexts (devnet, testnet, mainnet)?",
1253
+ " ",
1254
+ setupStandardContexts ? "Yes" : "No"
1255
+ ] }),
1256
+ /* @__PURE__ */ jsx3(Text3, { children: "Do you want to set up a custom context?" }),
1257
+ /* @__PURE__ */ jsx3(
1258
+ SelectInput,
1259
+ {
1260
+ items: [
1261
+ { label: "Yes", value: true },
1262
+ { label: "No", value: false }
1263
+ ],
1264
+ onSelect: (item) => {
1265
+ setSetupCustomContext(item.value);
1266
+ if (item.value) {
1267
+ setStep("customContextDetails");
1268
+ } else {
1269
+ setStep("setupAccount");
845
1270
  }
846
1271
  }
847
- )
848
- );
849
- }
850
- });
851
- }
852
-
853
- // src/commands/account.tsx
854
- import { Hex as Hex2 } from "@aptos-labs/ts-sdk";
855
- import { Aptos as Aptos3 } from "@aptos-labs/ts-sdk";
856
-
857
- // ../../packages/sdk/dist/chunk-7ZRA6VJT.mjs
858
- import { Aptos } from "@aptos-labs/ts-sdk";
859
- var ShelbyClient = class {
860
- config;
861
- #aptos;
862
- constructor(config) {
863
- this.config = config;
864
- this.#aptos = new Aptos(this.config.aptos.config);
1272
+ }
1273
+ )
1274
+ ] });
865
1275
  }
866
- get baseUrl() {
867
- return this.config.shelby.baseUrl;
1276
+ if (step === "customContextDetails") {
1277
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
1278
+ /* @__PURE__ */ jsx3(Text3, { children: "\u2714 Do you want to set up a custom context? Yes" }),
1279
+ /* @__PURE__ */ jsx3(Text3, { children: "Context name? (default: staging)" }),
1280
+ /* @__PURE__ */ jsx3(
1281
+ TextInput3,
1282
+ {
1283
+ value: customContextName,
1284
+ onChange: setCustomContextName,
1285
+ onSubmit: () => setStep("shelbyRpcEndpoint")
1286
+ }
1287
+ )
1288
+ ] });
868
1289
  }
869
- get aptos() {
870
- return this.#aptos;
1290
+ if (step === "shelbyRpcEndpoint") {
1291
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
1292
+ /* @__PURE__ */ jsxs3(Text3, { children: [
1293
+ "\u2714 Context name? ",
1294
+ customContextName
1295
+ ] }),
1296
+ /* @__PURE__ */ jsx3(Text3, { children: "Shelby RPC endpoint? (default: https://shelby.rpc.staging.example.com)" }),
1297
+ /* @__PURE__ */ jsx3(
1298
+ TextInput3,
1299
+ {
1300
+ value: shelbyRpcEndpoint,
1301
+ onChange: setShelbyRpcEndpoint,
1302
+ onSubmit: () => setStep("aptosNetwork")
1303
+ }
1304
+ )
1305
+ ] });
871
1306
  }
872
- };
873
-
874
- // ../../packages/sdk/dist/chunk-FVQ65BD6.mjs
875
- var SHELBY_DEPLOYER = "0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5";
876
- var ERASURE_K = 2;
877
- var ERASURE_M = 1;
878
- var CHUNKSET_SIZE_BYTES = 10 * 1024 * 1024;
879
- function getChunksetSizeBytes() {
880
- return CHUNKSET_SIZE_BYTES;
881
- }
882
-
883
- // ../../packages/sdk/dist/chunk-LATCKOZE.mjs
884
- import { AccountAddress as AccountAddress2 } from "@aptos-labs/ts-sdk";
885
- import { z as z4 } from "zod";
886
- var BlobNameSchema = z4.string().min(1, "Blob name path parameter cannot be empty.").max(1024, "Blob name cannot exceed 1024 characters.").refine((name2) => !name2.endsWith("/"), {
887
- message: "Blob name cannot end with a slash"
888
- });
889
- function roundSize(size) {
890
- let ret = 0;
891
- let remain = size;
892
- while (remain > 0) {
893
- ret += getChunksetSizeBytes();
894
- remain -= getChunksetSizeBytes();
1307
+ if (step === "aptosNetwork") {
1308
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
1309
+ /* @__PURE__ */ jsxs3(Text3, { children: [
1310
+ "\u2714 Shelby RPC endpoint? ",
1311
+ shelbyRpcEndpoint
1312
+ ] }),
1313
+ /* @__PURE__ */ jsx3(Text3, { children: "Aptos network? (default: mainnet)" }),
1314
+ /* @__PURE__ */ jsx3(
1315
+ TextInput3,
1316
+ {
1317
+ value: aptosNetwork,
1318
+ onChange: setAptosNetwork,
1319
+ onSubmit: () => setStep("setupAccount")
1320
+ }
1321
+ )
1322
+ ] });
895
1323
  }
896
- return ret;
897
- }
898
-
899
- // ../../packages/sdk/dist/chunk-2YUSOPAD.mjs
900
- import { Readable, Transform } from "stream";
901
- function encodeURIComponentKeepSlashes(str) {
902
- return encodeURIComponent(str).replace(/%2F/g, "/");
903
- }
904
- var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
905
- var ShelbyNodeClient = class extends ShelbyClient {
906
- async #uploadPart(uploadId, partIdx, partData) {
907
- const nRetries = 5;
908
- for (let i = 0; i < nRetries; ++i) {
909
- const partResponse = await fetch(
910
- `${this.baseUrl}/api/v1/multipartUpload/uploadPart/${uploadId}/${partIdx}`,
1324
+ if (step === "setupAccount") {
1325
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
1326
+ /* @__PURE__ */ jsx3(Text3, { children: "Create or update an account now?" }),
1327
+ /* @__PURE__ */ jsx3(
1328
+ SelectInput,
911
1329
  {
912
- method: "PUT",
913
- headers: {
914
- "Content-Type": "application/octet-stream"
915
- },
916
- body: partData
1330
+ items: [
1331
+ { label: "Yes", value: true },
1332
+ { label: "No", value: false }
1333
+ ],
1334
+ onSelect: (item) => {
1335
+ setSetupAccount(item.value);
1336
+ if (item.value) {
1337
+ setStep("accountName");
1338
+ } else {
1339
+ setStep("complete");
1340
+ }
1341
+ }
917
1342
  }
918
- );
919
- if (partResponse.ok) return;
920
- if (i < nRetries - 1) {
921
- const delay = 2 ** i * 100;
922
- await sleep(delay);
923
- }
924
- }
925
- throw new Error(`Failed to upload part ${partIdx}.`);
1343
+ )
1344
+ ] });
926
1345
  }
927
- async #putBlobMultipart(account, blobName, blobData, partSize = 5 * 1024 * 1024) {
928
- const startResponse = await fetch(
929
- `${this.baseUrl}/api/v1/multipartUpload/start`,
930
- {
931
- method: "POST",
932
- headers: {
933
- "Content-Type": "application/json"
934
- },
935
- body: JSON.stringify({
936
- rawAccount: account.toString(),
937
- rawBlobName: blobName,
938
- rawPartSize: partSize
939
- })
940
- }
941
- );
942
- if (!startResponse.ok) {
943
- let errorBodyText = "Could not read error body";
944
- try {
945
- errorBodyText = await startResponse.text();
946
- } catch (e) {
947
- }
948
- throw new Error(
949
- `Failed to start multipart upload! status: ${startResponse.status}, body: ${errorBodyText}`
950
- );
951
- }
952
- const { uploadId } = await startResponse.json();
953
- const totalParts = Math.ceil(blobData.length / partSize);
954
- for (let partIdx = 0; partIdx < totalParts; partIdx++) {
955
- const start = partIdx * partSize;
956
- const end = Math.min(start + partSize, blobData.length);
957
- const partData = blobData.subarray(start, end);
958
- await this.#uploadPart(uploadId, partIdx, partData);
959
- }
960
- const completeResponse = await fetch(
961
- `${this.baseUrl}/api/v1/multipartUpload/complete/${uploadId}`,
962
- {
963
- method: "POST",
964
- headers: {
965
- "Content-Type": "application/json"
1346
+ if (step === "accountName") {
1347
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
1348
+ /* @__PURE__ */ jsx3(Text3, { children: "\u2714 Create or update an account now? Yes" }),
1349
+ /* @__PURE__ */ jsx3(Text3, { children: "Account name? (default: alice)" }),
1350
+ /* @__PURE__ */ jsx3(
1351
+ TextInput3,
1352
+ {
1353
+ value: accountName,
1354
+ onChange: setAccountName,
1355
+ onSubmit: () => setStep("signatureScheme")
1356
+ }
1357
+ )
1358
+ ] });
1359
+ }
1360
+ if (step === "signatureScheme") {
1361
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
1362
+ /* @__PURE__ */ jsxs3(Text3, { children: [
1363
+ "\u2714 Account name? ",
1364
+ accountName
1365
+ ] }),
1366
+ /* @__PURE__ */ jsx3(Text3, { children: "Signature scheme? (ed25519)" }),
1367
+ /* @__PURE__ */ jsx3(
1368
+ SelectInput,
1369
+ {
1370
+ items: [
1371
+ { label: ED25519_NAME, value: ED25519_NAME }
1372
+ // { label: SECP256K1_NAME, value: SECP256K1_NAME },
1373
+ ],
1374
+ onSelect: (item) => {
1375
+ setSignatureScheme(item.value);
1376
+ setStep("privateKey");
1377
+ }
966
1378
  }
967
- }
968
- );
969
- if (!completeResponse.ok) {
970
- let errorBodyText = "Could not read error body";
971
- try {
972
- errorBodyText = await completeResponse.text();
973
- } catch (e) {
974
- }
975
- throw new Error(
976
- `Failed to complete multipart upload! status: ${completeResponse.status}, body: ${errorBodyText}`
977
- );
978
- }
979
- }
980
- async putBlob(account, blobName, blobData) {
981
- BlobNameSchema.parse(blobName);
982
- await this.#putBlobMultipart(account, blobName, blobData);
1379
+ )
1380
+ ] });
983
1381
  }
984
- // FIXME make this possible to stream in put ^^^
985
- async getBlob(account, blobName, range) {
986
- BlobNameSchema.parse(blobName);
987
- const url = `${this.baseUrl}/storage/${account.toString()}/${encodeURIComponentKeepSlashes(blobName)}`;
988
- const requestInit = {};
989
- if (range !== void 0) {
990
- const headers = new Headers();
991
- const { start, end } = range;
992
- if (end === void 0) {
993
- headers.set("Range", `bytes=${start}-`);
994
- } else {
995
- if (end < start) {
996
- throw new Error("Range end cannot be less than start.");
1382
+ if (step === "privateKey") {
1383
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
1384
+ /* @__PURE__ */ jsxs3(Text3, { children: [
1385
+ "\u2714 Signature scheme? ",
1386
+ signatureScheme
1387
+ ] }),
1388
+ /* @__PURE__ */ jsx3(Text3, { children: "Private key? (leave blank to generate new key)" }),
1389
+ /* @__PURE__ */ jsx3(
1390
+ TextInput3,
1391
+ {
1392
+ value: privateKey,
1393
+ onChange: setPrivateKey,
1394
+ onSubmit: () => {
1395
+ if (!privateKey) {
1396
+ const newKey = generateEd25519Account();
1397
+ setGeneratedKey(newKey.privateKey.toAIP80String());
1398
+ setGeneratedAddress(newKey.accountAddress.toString());
1399
+ }
1400
+ setStep("complete");
1401
+ }
997
1402
  }
998
- headers.set("Range", `bytes=${start}-${end}`);
1403
+ )
1404
+ ] });
1405
+ }
1406
+ return /* @__PURE__ */ jsx3(Box3, { flexDirection: "column", children: /* @__PURE__ */ jsx3(Text3, { children: "\u2705 Configuration complete!" }) });
1407
+ };
1408
+
1409
+ // src/components/UpdateContextWizard.tsx
1410
+ import { Box as Box4, Text as Text4 } from "ink";
1411
+ import TextInput4 from "ink-text-input";
1412
+ import { useEffect as useEffect4, useState as useState4 } from "react";
1413
+
1414
+ // src/schemas/AptosNetworkSchema.ts
1415
+ import { z as z3 } from "zod";
1416
+ var AptosNetworkSchema = z3.enum([
1417
+ "mainnet",
1418
+ "testnet",
1419
+ "devnet",
1420
+ "local"
1421
+ ]);
1422
+
1423
+ // src/schemas/EndpointSchema.ts
1424
+ import { z as z4 } from "zod";
1425
+ var EndpointSchema = z4.string().url("Must be a valid URL");
1426
+
1427
+ // src/components/UpdateContextWizard.tsx
1428
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1429
+ var UpdateContextWizard = ({
1430
+ contextName,
1431
+ currentShelbyRpc,
1432
+ currentAptosNetwork,
1433
+ onComplete
1434
+ }) => {
1435
+ const [step, setStep] = useState4("shelbyRpc");
1436
+ const [shelbyRpcEndpoint, setShelbyRpcEndpoint] = useState4(currentShelbyRpc);
1437
+ const [aptosNetwork, setAptosNetwork] = useState4(currentAptosNetwork);
1438
+ const [error, setError] = useState4("");
1439
+ useEffect4(() => {
1440
+ if (step === "done") {
1441
+ const updates = {};
1442
+ if (shelbyRpcEndpoint !== currentShelbyRpc) {
1443
+ updates.shelbyRpcEndpoint = shelbyRpcEndpoint;
999
1444
  }
1000
- requestInit.headers = headers;
1001
- }
1002
- const response = await fetch(url, requestInit);
1003
- if (!response.ok) {
1004
- throw new Error(
1005
- `Failed to download blob: ${response.status} ${response.statusText}`
1006
- );
1007
- }
1008
- if (!response.body) {
1009
- throw new Error("Response body is null");
1010
- }
1011
- const contentLengthHeader = response.headers.get("content-length");
1012
- if (contentLengthHeader === null) {
1013
- throw new Error(
1014
- "Response did not have content-length header, which is required"
1015
- );
1016
- }
1017
- const expectedContentLength = Number.parseInt(contentLengthHeader, 10);
1018
- if (Number.isNaN(expectedContentLength)) {
1019
- throw new Error(
1020
- `Invalid content-length header received: ${contentLengthHeader}`
1021
- );
1445
+ if (aptosNetwork !== currentAptosNetwork) {
1446
+ updates.aptosNetwork = aptosNetwork;
1447
+ }
1448
+ onComplete(updates);
1022
1449
  }
1023
- let bytesReceived = 0;
1024
- const reader = response.body.getReader();
1025
- const sourceStream = new Readable({
1026
- async read() {
1027
- try {
1028
- const { done, value } = await reader.read();
1029
- if (done) {
1030
- this.push(null);
1031
- } else {
1032
- this.push(Buffer.from(value));
1450
+ }, [
1451
+ step,
1452
+ shelbyRpcEndpoint,
1453
+ aptosNetwork,
1454
+ currentShelbyRpc,
1455
+ currentAptosNetwork,
1456
+ onComplete
1457
+ ]);
1458
+ if (step === "shelbyRpc") {
1459
+ return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
1460
+ /* @__PURE__ */ jsxs4(Text4, { children: [
1461
+ "Updating context: ",
1462
+ contextName
1463
+ ] }),
1464
+ /* @__PURE__ */ jsxs4(Text4, { children: [
1465
+ "Shelby RPC endpoint? (current: ",
1466
+ currentShelbyRpc,
1467
+ ")"
1468
+ ] }),
1469
+ error && /* @__PURE__ */ jsxs4(Text4, { color: "red", children: [
1470
+ "Error: ",
1471
+ error
1472
+ ] }),
1473
+ /* @__PURE__ */ jsx4(
1474
+ TextInput4,
1475
+ {
1476
+ value: shelbyRpcEndpoint,
1477
+ placeholder: currentShelbyRpc,
1478
+ onChange: (value) => {
1479
+ setShelbyRpcEndpoint(value);
1480
+ setError("");
1481
+ },
1482
+ onSubmit: () => {
1483
+ if (shelbyRpcEndpoint && shelbyRpcEndpoint !== currentShelbyRpc) {
1484
+ const result = EndpointSchema.safeParse(shelbyRpcEndpoint);
1485
+ if (!result.success) {
1486
+ setError(result.error.errors[0].message);
1487
+ return;
1488
+ }
1489
+ }
1490
+ setError("");
1491
+ setStep("aptosApi");
1033
1492
  }
1034
- } catch (error) {
1035
- this.destroy(error);
1036
1493
  }
1037
- }
1038
- });
1039
- const validationTransform = new Transform({
1040
- transform(chunk, encoding, callback) {
1041
- bytesReceived += chunk.length;
1042
- callback(null, chunk);
1043
- },
1044
- flush(callback) {
1045
- if (bytesReceived !== expectedContentLength) {
1046
- callback(
1047
- new Error(
1048
- `Downloaded data size (${bytesReceived} bytes) does not match content-length header (${expectedContentLength} bytes). This might indicate a partial or corrupted download.`
1049
- )
1050
- );
1051
- } else {
1052
- callback();
1494
+ ),
1495
+ /* @__PURE__ */ jsx4(Text4, { color: "gray", children: "Press Enter to continue" })
1496
+ ] });
1497
+ }
1498
+ if (step === "aptosApi") {
1499
+ return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
1500
+ /* @__PURE__ */ jsxs4(Text4, { children: [
1501
+ "Aptos network? (current: ",
1502
+ currentAptosNetwork,
1503
+ ")"
1504
+ ] }),
1505
+ error && /* @__PURE__ */ jsxs4(Text4, { color: "red", children: [
1506
+ "Error: ",
1507
+ error
1508
+ ] }),
1509
+ /* @__PURE__ */ jsx4(
1510
+ TextInput4,
1511
+ {
1512
+ value: aptosNetwork,
1513
+ placeholder: currentAptosNetwork,
1514
+ onChange: (value) => {
1515
+ setAptosNetwork(value);
1516
+ setError("");
1517
+ },
1518
+ onSubmit: () => {
1519
+ if (aptosNetwork && aptosNetwork !== currentAptosNetwork) {
1520
+ const result = AptosNetworkSchema.safeParse(aptosNetwork);
1521
+ if (!result.success) {
1522
+ setError("Must be one of: mainnet, testnet, devnet, local");
1523
+ return;
1524
+ }
1525
+ }
1526
+ setError("");
1527
+ setStep("done");
1528
+ }
1053
1529
  }
1054
- }
1055
- });
1056
- sourceStream.pipe(validationTransform);
1057
- return {
1058
- stream: validationTransform,
1059
- contentLength: expectedContentLength
1060
- };
1530
+ ),
1531
+ /* @__PURE__ */ jsx4(Text4, { color: "gray", children: "Valid options: mainnet, testnet, devnet, local" }),
1532
+ /* @__PURE__ */ jsx4(Text4, { color: "gray", children: "Press Enter to save changes" })
1533
+ ] });
1061
1534
  }
1535
+ return null;
1062
1536
  };
1063
1537
 
1064
- // ../../packages/sdk/dist/chunk-FEBILXVJ.mjs
1065
- function fdUlongHash(_x) {
1066
- const value = typeof _x === "number" ? BigInt(_x) : _x;
1067
- const MASK_64 = (1n << 64n) - 1n;
1068
- let x = value & MASK_64;
1069
- x ^= x >> 33n;
1070
- x = x * 0xff51afd7ed558ccdn & MASK_64;
1071
- x ^= x >> 33n;
1072
- x = x * 0xc4ceb9fe1a85ec53n & MASK_64;
1073
- x ^= x >> 33n;
1074
- return x;
1075
- }
1076
-
1077
- // ../../packages/sdk/dist/chunk-7P6ASYW6.mjs
1078
- var __defProp = Object.defineProperty;
1079
- var __export = (target, all) => {
1080
- for (var name2 in all)
1081
- __defProp(target, name2, { get: all[name2], enumerable: true });
1082
- };
1538
+ // src/utils/config.ts
1539
+ import os from "os";
1540
+ import path from "path";
1541
+ import {
1542
+ AptosConfig,
1543
+ Ed25519Account,
1544
+ Ed25519PrivateKey as Ed25519PrivateKey2,
1545
+ NetworkToNetworkName
1546
+ } from "@aptos-labs/ts-sdk";
1547
+ import fs from "fs-extra";
1548
+ import YAML from "yaml";
1549
+ import { z as z5 } from "zod";
1083
1550
 
1084
- // ../../packages/sdk/dist/chunk-HHRQUHR7.mjs
1085
- import { Readable as Readable2 } from "stream";
1086
- var testUtil_exports = {};
1087
- __export(testUtil_exports, {
1088
- makeChunk: () => makeChunk,
1089
- makeStream: () => makeStream
1090
- });
1091
- function makeChunk(n) {
1092
- const c = Buffer.alloc(n);
1093
- for (let i = 0; i < n; ++i) {
1094
- c[i] = i % 256;
1095
- }
1096
- return c;
1097
- }
1098
- function makeStream(len) {
1099
- let position = 0;
1100
- const data = makeChunk(len);
1101
- return new Readable2({
1102
- read() {
1103
- if (position >= len) {
1104
- this.push(null);
1105
- return;
1106
- }
1107
- const divisor = Math.max(1, Math.floor(len / 4));
1108
- const deterministicRand = Number(
1109
- fdUlongHash(BigInt(position)) % BigInt(divisor)
1110
- );
1111
- const chunkSize = Math.max(64, deterministicRand);
1112
- const bytesToPush = Math.min(chunkSize, len - position);
1113
- this.push(Buffer.from(data.subarray(position, position + bytesToPush)));
1114
- position += bytesToPush;
1551
+ // tests/utils/mockConfig.ts
1552
+ var mockAccountAlice = generateEd25519Account();
1553
+ var mockAccountBob = generateEd25519Account();
1554
+ var mockConfig = {
1555
+ contexts: {
1556
+ devnet: {
1557
+ aptos_network: "devnet",
1558
+ shelby_rpc_endpoint: "https://shelby.rpc.devnet.example.com"
1559
+ },
1560
+ testnet: {
1561
+ aptos_network: "testnet",
1562
+ shelby_rpc_endpoint: "https://shelby.rpc.testnet.example.com"
1563
+ },
1564
+ mainnet: {
1565
+ aptos_network: "mainnet",
1566
+ shelby_rpc_endpoint: "https://shelby.rpc.mainnet.example.com"
1567
+ }
1568
+ },
1569
+ accounts: {
1570
+ alice: {
1571
+ address: mockAccountAlice.accountAddress.toString(),
1572
+ private_key: mockAccountAlice.privateKey.toAIP80String()
1573
+ },
1574
+ bob: {
1575
+ private_key: mockAccountBob.privateKey.toAIP80String(),
1576
+ address: mockAccountBob.accountAddress.toString()
1115
1577
  }
1116
- });
1117
- }
1578
+ },
1579
+ default_context: "devnet",
1580
+ default_account: "alice"
1581
+ };
1582
+
1583
+ // src/utils/constants.ts
1584
+ var DEFAULT_CONFIG_PATH = "~/.shelby/config.yaml";
1118
1585
 
1119
- // ../../packages/sdk/dist/chunk-E3QOKRQ4.mjs
1120
- var readableUtil_exports = {};
1121
- __export(readableUtil_exports, {
1122
- readInChunks: () => readInChunks,
1123
- zeroPadBuffer: () => zeroPadBuffer
1586
+ // src/utils/config.ts
1587
+ var ContextSchema = z5.object({
1588
+ aptos_network: AptosNetworkSchema,
1589
+ shelby_rpc_endpoint: EndpointSchema
1124
1590
  });
1125
- async function* readInChunks(r, chunkSize) {
1126
- let buffer = Buffer.alloc(chunkSize);
1127
- let bufferWriteOffset = 0;
1128
- let idx = 0;
1129
- for await (const readableChunk of r) {
1130
- let bufferRemain = chunkSize - bufferWriteOffset;
1131
- let st = 0;
1132
- let ed = Math.min(readableChunk.length, st + bufferRemain);
1133
- while (st < ed) {
1134
- const slice = readableChunk.slice(st, ed);
1135
- slice.copy(buffer, bufferWriteOffset);
1136
- bufferWriteOffset += slice.length;
1137
- if (bufferWriteOffset >= chunkSize) {
1138
- yield [idx++, buffer];
1139
- buffer = Buffer.alloc(chunkSize);
1140
- bufferWriteOffset = 0;
1141
- }
1142
- bufferRemain = chunkSize - bufferWriteOffset;
1143
- st = ed;
1144
- ed = Math.min(readableChunk.length, st + bufferRemain);
1145
- }
1146
- }
1147
- if (bufferWriteOffset > 0) {
1148
- yield [idx++, buffer.subarray(0, bufferWriteOffset)];
1591
+ var ConfigSchema = z5.object({
1592
+ contexts: z5.record(ContextSchema),
1593
+ accounts: z5.record(
1594
+ z5.object({
1595
+ address: z5.string().optional(),
1596
+ private_key: z5.string({ message: "private_key must be provided" })
1597
+ })
1598
+ ),
1599
+ default_context: z5.string(),
1600
+ default_account: z5.string()
1601
+ });
1602
+ function resolveConfigPath(configPath) {
1603
+ if (configPath.startsWith("~")) {
1604
+ return path.join(os.homedir(), configPath.slice(1));
1149
1605
  }
1606
+ return configPath;
1150
1607
  }
1151
- function zeroPadBuffer(buffer, desiredLength) {
1152
- if (buffer.length >= desiredLength) {
1153
- return buffer;
1608
+ function loadConfig(configPath = DEFAULT_CONFIG_PATH) {
1609
+ const resolvedPath = resolveConfigPath(configPath);
1610
+ const dir = path.dirname(resolvedPath);
1611
+ if (!fs.existsSync(resolvedPath)) {
1612
+ fs.mkdirpSync(dir);
1613
+ const yamlText = YAML.stringify(mockConfig);
1614
+ fs.writeFileSync(resolvedPath, yamlText, "utf8");
1615
+ return mockConfig;
1616
+ }
1617
+ const raw = fs.readFileSync(resolvedPath, "utf8");
1618
+ let parsed;
1619
+ try {
1620
+ parsed = YAML.parse(raw);
1621
+ } catch {
1622
+ throw new Error("Invalid config file");
1623
+ }
1624
+ try {
1625
+ return ConfigSchema.parse(parsed);
1626
+ } catch (err) {
1627
+ throw new Error(`Invalid config file: ${err.message}`);
1154
1628
  }
1155
- const paddedBuffer = Buffer.alloc(desiredLength);
1156
- buffer.copy(paddedBuffer);
1157
- return paddedBuffer;
1158
1629
  }
1159
-
1160
- // ../../packages/sdk/dist/chunk-USIL76JP.mjs
1161
- import { Buffer as Buffer2 } from "buffer";
1162
-
1163
- // ../../packages/reed-solomon/dist/index.mjs
1164
- import { createRequire } from "module";
1165
- import { dirname, join } from "path";
1166
- import { fileURLToPath } from "url";
1167
- var require2 = createRequire(import.meta.url);
1168
- var __dirname = dirname(fileURLToPath(import.meta.url));
1169
- var RS;
1170
- try {
1171
- RS = require2(join(__dirname, "binding.node"));
1172
- } catch {
1173
- RS = require2("@ronomon/reed-solomon");
1630
+ function saveConfig(config, configPath = "~/.shelby/config.yaml") {
1631
+ const resolvedPath = resolveConfigPath(configPath);
1632
+ fs.mkdirpSync(path.dirname(resolvedPath));
1633
+ ConfigSchema.parse(config);
1634
+ fs.writeFileSync(resolvedPath, YAML.stringify(config), "utf8");
1174
1635
  }
1175
-
1176
- // ../../packages/sdk/dist/chunk-USIL76JP.mjs
1177
- async function erasureEncode(data, k, m) {
1178
- const rawShardSize = Math.ceil(data.length / k);
1179
- const shardSize = Math.ceil(rawShardSize / 8) * 8;
1180
- const dataSize = shardSize * k;
1181
- const paritySize = shardSize * m;
1182
- const dataBuf = Buffer2.alloc(dataSize);
1183
- data.copy(dataBuf, 0);
1184
- const parityBuf = Buffer2.alloc(paritySize);
1185
- let sources = 0;
1186
- for (let i = 0; i < k; i++) sources |= 1 << i;
1187
- let targets = 0;
1188
- for (let i = k; i < k + m; i++) targets |= 1 << i;
1189
- const context = RS.create(k, m);
1190
- await new Promise((resolve2, reject) => {
1191
- RS.encode(
1192
- context,
1193
- sources,
1194
- targets,
1195
- dataBuf,
1196
- 0,
1197
- dataSize,
1198
- parityBuf,
1199
- 0,
1200
- paritySize,
1201
- (err) => err ? reject(err) : resolve2()
1202
- );
1203
- });
1204
- const shards = [];
1205
- for (let i = 0; i < k; i++) {
1206
- shards.push(dataBuf.slice(i * shardSize, i * shardSize + shardSize));
1636
+ function getCurrentAccount(config, accountName) {
1637
+ const name = accountName || config.default_account;
1638
+ if (!name) {
1639
+ throw new Error(`Account with name '${name}' not found in config`);
1207
1640
  }
1208
- for (let j = 0; j < m; j++) {
1209
- shards.push(parityBuf.slice(j * shardSize, j * shardSize + shardSize));
1641
+ const account = config.accounts[name];
1642
+ if (!account) {
1643
+ throw new Error(`Account '${name}' not found in config`);
1210
1644
  }
1211
- return shards;
1212
- }
1213
-
1214
- // ../../packages/sdk/dist/chunk-GLMRJPN7.mjs
1215
- import { createHash } from "crypto";
1216
- function concatHashes(parts) {
1217
- const combined = Buffer.concat(parts.map((part) => part.copy().digest()));
1218
- return createHash("sha256").update(combined);
1645
+ let privateKey;
1646
+ if (account.private_key) {
1647
+ privateKey = account.private_key;
1648
+ } else {
1649
+ throw new Error(`No private key found for account '${name}'`);
1650
+ }
1651
+ return {
1652
+ address: account.address,
1653
+ privateKey,
1654
+ account: new Ed25519Account({
1655
+ privateKey: new Ed25519PrivateKey2(privateKey)
1656
+ })
1657
+ };
1219
1658
  }
1220
- async function generateCommitments(fullData, onChunk, options) {
1221
- const blobCommitment = createHash("sha256");
1222
- const chunksetCommitments = [];
1223
- const chunksetCommitmentHashes = [];
1224
- let rawDataSize = 0;
1225
- const chunksetGen = readInChunks(
1226
- fullData,
1227
- options?.chunksetSize ?? getChunksetSizeBytes()
1228
- );
1229
- for await (let [chunksetIdx, chunksetData] of chunksetGen) {
1230
- const chunkCommitments = [];
1231
- rawDataSize += chunksetData.length;
1232
- chunksetData = zeroPadBuffer(
1233
- chunksetData,
1234
- options?.chunksetSize ?? getChunksetSizeBytes()
1235
- );
1236
- const chunks = await erasureEncode(
1237
- chunksetData,
1238
- options?.erasureK ?? ERASURE_K,
1239
- options?.erasureM ?? ERASURE_M
1659
+ function getCurrentShelbyConfig(config, opts = {
1660
+ context: config.default_context
1661
+ }) {
1662
+ const { context } = opts;
1663
+ const selectedContext = config.contexts[context ?? config.default_context];
1664
+ if (!selectedContext) {
1665
+ throw new Error(
1666
+ `Context '${context ?? config.default_context}' not found in config`
1240
1667
  );
1241
- let chunkIdx = 0;
1242
- for (const chunkData of chunks) {
1243
- if (onChunk !== void 0) {
1244
- await onChunk(chunksetIdx, chunkIdx, chunkData);
1245
- }
1246
- const chunkHash = createHash("sha256").update(chunkData);
1247
- chunkCommitments.push(chunkHash);
1248
- chunkIdx += 1;
1249
- }
1250
- const h = concatHashes(chunkCommitments);
1251
- chunksetCommitments.push({
1252
- chunkset_root: `0x${h.copy().digest("hex")}`,
1253
- chunk_commitments: chunkCommitments.map((buffer) => buffer.digest("hex"))
1254
- });
1255
- blobCommitment.update(chunksetData);
1256
- chunksetCommitmentHashes.push(h);
1668
+ }
1669
+ const aptosNetwork = NetworkToNetworkName[selectedContext.aptos_network];
1670
+ if (!aptosNetwork) {
1671
+ throw new Error(`Invalid Aptos network: ${selectedContext.aptos_network}`);
1257
1672
  }
1258
1673
  return {
1259
- schema_version: "1.3",
1260
- raw_data_size: rawDataSize,
1261
- blob_merkle_root: `0x${concatHashes(chunksetCommitmentHashes).digest("hex")}`,
1262
- chunkset_commitments: chunksetCommitments
1674
+ aptos: { config: new AptosConfig({ network: aptosNetwork }) },
1675
+ shelby: { baseUrl: selectedContext.shelby_rpc_endpoint }
1263
1676
  };
1264
1677
  }
1265
1678
 
1266
- // ../../packages/sdk/dist/chunk-AASWNUSM.mjs
1267
- import { Readable as Readable3 } from "stream";
1268
- import {
1269
- AccountAddress as AccountAddress3,
1270
- Aptos as Aptos2,
1271
- Hex,
1272
- MoveVector
1273
- } from "@aptos-labs/ts-sdk";
1274
- var ShelbyBlobClient = class _ShelbyBlobClient {
1275
- aptos;
1276
- deployer;
1277
- constructor(config) {
1278
- this.aptos = new Aptos2(config.aptos.config);
1279
- this.deployer = config.shelbyDeployer ?? AccountAddress3.fromString(SHELBY_DEPLOYER);
1280
- }
1281
- static createBlobKey(account, blobName) {
1282
- return `${account.toString()}.${blobName}`;
1283
- }
1284
- async getBlobMetadata(params) {
1285
- try {
1286
- const rawMetadata = await this.aptos.view({
1287
- payload: {
1288
- function: `${this.deployer.toString()}::prototype_interface::get_metadata`,
1289
- functionArguments: [
1290
- _ShelbyBlobClient.createBlobKey(params.account, params.name)
1291
- ]
1292
- }
1293
- });
1294
- const metadata = rawMetadata[0];
1295
- return {
1296
- blobMerkleRoot: Hex.fromHexInput(
1297
- metadata.blob_merkle_root
1298
- ).toUint8Array(),
1299
- owner: AccountAddress3.fromString(metadata.owner),
1300
- name: metadata.name,
1301
- size: metadata.size,
1302
- encoding: {
1303
- variant: "clay",
1304
- erasureK: metadata.encoding.num_data_chunks,
1305
- erasureM: metadata.encoding.num_parity_chunks,
1306
- chunksetSize: metadata.encoding.chunkset_size
1307
- },
1308
- expirationMicros: metadata.expiration_micros
1309
- };
1310
- } catch (error) {
1311
- if (error instanceof Error && // Depending on the network, the error message may show up differently.
1312
- (error.message?.includes("sub_status: Some(404)") || error.message?.includes("EBLOB_NOT_FOUND"))) {
1313
- return void 0;
1314
- }
1315
- throw error;
1316
- }
1317
- }
1318
- async getAccountBlobs(params) {
1319
- const rawBlobMetadatas = await this.aptos.view({
1320
- payload: {
1321
- function: `${this.deployer.toString()}::prototype_interface::get_blobs_for_owner`,
1322
- functionArguments: [params.account.toString()]
1323
- }
1324
- });
1325
- return rawBlobMetadatas[0].map((blob) => ({
1326
- blobMerkleRoot: Hex.fromHexInput(blob.blob_merkle_root).toUint8Array(),
1327
- owner: AccountAddress3.fromString(blob.owner),
1328
- name: blob.name,
1329
- size: blob.size,
1330
- encoding: {
1331
- variant: "clay",
1332
- erasureK: blob.encoding.num_data_chunks,
1333
- erasureM: blob.encoding.num_parity_chunks,
1334
- chunksetSize: blob.encoding.chunkset_size
1335
- },
1336
- expirationMicros: blob.expiration_micros
1337
- }));
1338
- }
1339
- /**
1340
- * Queries the blockchain for the chunks pertaining to a given blob.
1341
- *
1342
- * @param account - The account namespace the blob is stored in (e.g. "0x1")
1343
- * @param name - The name of the blob (e.g. "foo/bar")
1344
- * @returns The chunks that make up the blob.
1345
- */
1346
- async getBlobChunks(params) {
1347
- const chunks = await this.aptos.view({
1348
- payload: {
1349
- function: `${this.deployer.toString()}::prototype_interface::get_chunks`,
1350
- functionArguments: [
1351
- _ShelbyBlobClient.createBlobKey(params.account, params.name)
1352
- ]
1353
- }
1354
- });
1355
- return chunks[0].map((c) => ({
1356
- commitment: Hex.fromHexInput(c.commitment).toUint8Array(),
1357
- location: {
1358
- variant: c.location.__variant__ === "Stored" ? "stored" : "pending",
1359
- provider: AccountAddress3.fromString(c.location.provider)
1360
- }
1361
- }));
1362
- }
1363
- async writeBlobCommitments(params) {
1364
- let blobCommitments;
1365
- if ("blobCommitments" in params) {
1366
- blobCommitments = params.blobCommitments;
1367
- } else {
1368
- blobCommitments = await generateCommitments(
1369
- Readable3.from(params.data),
1370
- void 0,
1371
- params.options?.encoding
1372
- );
1373
- }
1374
- const transaction = await this.aptos.transaction.build.simple({
1375
- ...params.options?.build,
1376
- data: _ShelbyBlobClient.createWriteBlobCommitmentsPayload({
1377
- deployer: this.deployer,
1378
- account: params.account.accountAddress,
1379
- blobName: params.blobName,
1380
- blobMerkleRoot: blobCommitments.blob_merkle_root,
1381
- chunksetChunkCommitments: blobCommitments.chunkset_commitments.map(
1382
- (chunkset) => chunkset.chunk_commitments
1383
- ),
1384
- size: blobCommitments.raw_data_size,
1385
- lifetime: params.lifetime
1386
- // FIXME rename?
1387
- }),
1388
- sender: params.account.accountAddress
1389
- });
1390
- return {
1391
- blobCommitments,
1392
- transaction: await this.aptos.signAndSubmitTransaction({
1393
- signer: params.account,
1394
- transaction
1395
- })
1396
- };
1397
- }
1398
- async confirmBlobChunks(params) {
1399
- const transaction = await this.aptos.transaction.build.simple({
1400
- ...params.options?.build,
1401
- data: _ShelbyBlobClient.createConfirmBlobChunksPayload({
1402
- deployer: this.deployer,
1403
- account: params.account,
1404
- blobName: params.blobName,
1405
- signedChunksetChunkCommitments: params.signedChunksetChunkCommitments
1406
- }),
1407
- sender: params.signer.accountAddress
1408
- });
1409
- return {
1410
- transaction: await this.aptos.signAndSubmitTransaction({
1411
- signer: params.signer,
1412
- transaction
1413
- })
1414
- };
1415
- }
1416
- /**
1417
- * Creates a transaction payload to write blob commitments to the blockchain.
1418
- *
1419
- * @see https://github.com/JumpCrypto/shelby/blob/e009607aad330ccddb08d80bf9addfaadae7972b/move/prototype/move/sources/prototype_interface.move#L211-L220
1420
- */
1421
- static createWriteBlobCommitmentsPayload(params) {
1422
- return {
1423
- function: `${(params.deployer ?? SHELBY_DEPLOYER).toString()}::prototype_interface::write_commitments`,
1424
- functionArguments: [
1425
- _ShelbyBlobClient.createBlobKey(params.account, params.blobName),
1426
- params.size,
1427
- MoveVector.U8(params.blobMerkleRoot),
1428
- params.chunksetChunkCommitments.map(
1429
- (chunkset) => chunkset.map((chunkCommitment) => MoveVector.U8(chunkCommitment))
1430
- ),
1431
- params.lifetime ?? 0,
1432
- true
1433
- ]
1434
- };
1435
- }
1436
- /**
1437
- * Creates a transaction payload to confirm the chunks of a blob.
1438
- *
1439
- * @see https://github.com/JumpCrypto/shelby/blob/e009607aad330ccddb08d80bf9addfaadae7972b/move/prototype/move/sources/prototype_interface.move#L343-L349
1440
- */
1441
- static createConfirmBlobChunksPayload(params) {
1442
- return {
1443
- function: `${(params.deployer ?? SHELBY_DEPLOYER).toString()}::prototype_interface::write_complete`,
1444
- functionArguments: [
1445
- _ShelbyBlobClient.createBlobKey(params.account, params.blobName),
1446
- params.signedChunksetChunkCommitments.map(
1447
- (chunkset) => chunkset.map((chunk) => AccountAddress3.from(chunk.provider))
1448
- ),
1449
- params.signedChunksetChunkCommitments.map(
1450
- (chunkset) => chunkset.map((chunk) => MoveVector.U8(chunk.signedCommitment))
1451
- ),
1452
- true
1453
- ]
1454
- };
1679
+ // src/utils/paths.ts
1680
+ import path2 from "path";
1681
+ function normBlobName(pathModule, inputDirectoryName, filename, blobPrefix) {
1682
+ const blobNameWithoutInputDir = pathModule.relative(
1683
+ inputDirectoryName,
1684
+ filename
1685
+ );
1686
+ const blobNameWithPrefix = pathModule.join(
1687
+ blobPrefix,
1688
+ blobNameWithoutInputDir
1689
+ );
1690
+ const blobNameNormalized = pathModule.normalize(blobNameWithPrefix);
1691
+ const parts = blobNameNormalized.split(pathModule.sep);
1692
+ return path2.posix.join(...parts);
1693
+ }
1694
+ function denormBlobName(pathModule, blobPrefix, blobName, outputPrefix) {
1695
+ if (!pathModule.isAbsolute(outputPrefix)) {
1696
+ throw new Error(`Output prefix '${outputPrefix}' must be an absolute path`);
1455
1697
  }
1456
- };
1457
-
1458
- // ../../packages/sdk/dist/chunk-OG3JQI44.mjs
1459
- import { z as z5 } from "zod";
1460
- var ChunksetCommitmentSchema = z5.object({
1461
- // Chunkset root (vector commitment of child chunks)
1462
- chunkset_root: z5.string().nullable(),
1463
- // the size is known statically from the current configuration
1464
- chunk_commitments: z5.array(z5.string())
1465
- }).refine(
1466
- (data) => {
1467
- return data.chunk_commitments.length === ERASURE_K + ERASURE_M;
1468
- },
1469
- {
1470
- message: `Chunkset must have exactly ${ERASURE_K + ERASURE_M} chunks (ERASURE_K + ERASURE_M = ${ERASURE_K} + ${ERASURE_M})`,
1471
- path: ["chunk_commitments"]
1698
+ if (!blobName.startsWith(blobPrefix)) {
1699
+ throw new Error(
1700
+ `Blob name '${blobName}' does not start with prefix '${blobPrefix}'`
1701
+ );
1472
1702
  }
1473
- );
1474
- function expectedTotalChunksets(rawSize) {
1475
- return roundSize(rawSize) / getChunksetSizeBytes();
1476
- }
1477
- var BlobCommitmentsSchema = z5.object({
1478
- schema_version: z5.string(),
1479
- raw_data_size: z5.number(),
1480
- // FIXME I am not sure about this being here, or if it should be somewhere else
1481
- // I deleted the blob_commitment. What's the difference?
1482
- blob_merkle_root: z5.string(),
1483
- chunkset_commitments: z5.array(ChunksetCommitmentSchema)
1484
- }).refine(
1485
- (data) => {
1486
- return expectedTotalChunksets(data.raw_data_size) === data.chunkset_commitments.length;
1487
- },
1488
- {
1489
- message: "Total chunkset count mismatches with raw data size",
1490
- // FIXME put more details in here
1491
- path: ["chunkset_commitments"]
1703
+ const relativePath = blobName.slice(blobPrefix.length);
1704
+ const pathParts = relativePath.split("/").filter((part) => part.length > 0);
1705
+ if (pathParts.length === 0) {
1706
+ return outputPrefix;
1492
1707
  }
1493
- );
1494
-
1495
- // ../../packages/sdk/dist/chunk-IS2JVNMO.mjs
1496
- import { hashValues } from "@aptos-labs/ts-sdk";
1708
+ return pathModule.join(outputPrefix, ...pathParts);
1709
+ }
1497
1710
 
1498
1711
  // src/commands/account.tsx
1499
- import Table from "cli-table3";
1500
- import { render as render2 } from "ink";
1501
- import { z as z6 } from "zod";
1502
- import { jsx as jsx6 } from "react/jsx-runtime";
1712
+ import { jsx as jsx5 } from "react/jsx-runtime";
1503
1713
  var CreateAccountOptionsSchema = z6.object({
1504
1714
  name: z6.string().optional(),
1505
1715
  privateKey: z6.string().optional(),
@@ -1524,8 +1734,8 @@ function accountCommand(program) {
1524
1734
  "Aptos account address (hex-encoded)"
1525
1735
  ).action((options) => {
1526
1736
  CreateAccountOptionsSchema.parse(options);
1527
- const { name: name2, privateKey, address, scheme } = options;
1528
- const allPresent = name2 && privateKey && address && scheme;
1737
+ const { name, privateKey, address, scheme } = options;
1738
+ const allPresent = name && privateKey && address && scheme;
1529
1739
  const configPath = program.opts().configFile;
1530
1740
  let config;
1531
1741
  try {
@@ -1537,33 +1747,33 @@ function accountCommand(program) {
1537
1747
  }
1538
1748
  if (allPresent) {
1539
1749
  if (isValidAddress(address) && isValidEd25519PrivateKey(privateKey) && isValidScheme(scheme)) {
1540
- config.accounts[name2] = {
1750
+ config.accounts[name] = {
1541
1751
  private_key: privateKey
1542
1752
  };
1543
1753
  if (options.address) {
1544
- config.accounts[name2].address = address;
1754
+ config.accounts[name].address = address;
1545
1755
  }
1546
1756
  } else {
1547
1757
  throw new Error("Error invalid account address or private key");
1548
1758
  }
1549
1759
  } else {
1550
1760
  try {
1551
- const { unmount } = render2(
1552
- /* @__PURE__ */ jsx6(
1761
+ const { unmount } = render(
1762
+ /* @__PURE__ */ jsx5(
1553
1763
  AccountWizard,
1554
1764
  {
1555
1765
  onComplete: ({
1556
- name: name3,
1766
+ name: name2,
1557
1767
  address: address2,
1558
1768
  privateKey: privateKey2
1559
1769
  }) => {
1560
- config.accounts[name3] = {
1770
+ config.accounts[name2] = {
1561
1771
  private_key: privateKey2,
1562
1772
  address: address2
1563
1773
  };
1564
1774
  saveConfig(config, configPath);
1565
1775
  console.log(
1566
- `\u2705 Account ${name3} saved to ${resolveConfigPath(configPath)}`
1776
+ `\u2705 Account ${name2} saved to ${resolveConfigPath(configPath)}`
1567
1777
  );
1568
1778
  unmount();
1569
1779
  }
@@ -1592,11 +1802,11 @@ function accountCommand(program) {
1592
1802
  style: { head: ["cyan"] },
1593
1803
  colWidths: [20, 68, 22]
1594
1804
  });
1595
- for (const [name2, { address, private_key }] of Object.entries(
1805
+ for (const [name, { address, private_key }] of Object.entries(
1596
1806
  config.accounts
1597
1807
  )) {
1598
- const isDefault = name2 === config.default_account ? " (default)" : "";
1599
- const displayName = name2 + isDefault;
1808
+ const isDefault = name === config.default_account ? " (default)" : "";
1809
+ const displayName = name + isDefault;
1600
1810
  const maskedKey = private_key ? `${private_key.slice(0, 20)}...` : "";
1601
1811
  table.push([displayName, address || "", maskedKey]);
1602
1812
  }
@@ -1659,12 +1869,11 @@ function accountCommand(program) {
1659
1869
  context: program.opts().context
1660
1870
  });
1661
1871
  const activeAccount = getCurrentAccount(config, accountName).account;
1662
- const aptos = new Aptos3(shelbyConfig.aptos.config);
1663
- const blobClient = new ShelbyBlobClient({ aptos });
1872
+ const shelbyClient = new ShelbyNodeClient(shelbyConfig);
1664
1873
  console.log(
1665
1874
  `\u{1F50D} Retrieving blobs for ${accountName} (${activeAccount.accountAddress.toString()})`
1666
1875
  );
1667
- const blobs = await blobClient.getAccountBlobs({
1876
+ const blobs = await shelbyClient.coordination.getAccountBlobs({
1668
1877
  account: activeAccount.accountAddress
1669
1878
  });
1670
1879
  console.log(
@@ -1688,7 +1897,7 @@ function accountCommand(program) {
1688
1897
  table.push([
1689
1898
  blob.name,
1690
1899
  blob.size.toString(),
1691
- Hex2.fromHexInput(blob.blobMerkleRoot).toString(),
1900
+ Hex3.fromHexInput(blob.blobMerkleRoot).toString(),
1692
1901
  blob.encoding.variant,
1693
1902
  blob.encoding.erasureK.toString(),
1694
1903
  blob.encoding.erasureM.toString(),
@@ -1710,18 +1919,60 @@ function accountCommand(program) {
1710
1919
  });
1711
1920
  }
1712
1921
 
1922
+ // src/commands/commitment.ts
1923
+ import * as fs2 from "fs";
1924
+ import * as fsP from "fs/promises";
1925
+ import { Readable } from "stream";
1926
+ import { z as z7 } from "zod";
1927
+ var CommitmentOptionsSchema = z7.object({
1928
+ input: z7.string().nonempty("`--input` is required").refine(
1929
+ async (path5) => {
1930
+ const stat4 = await fsP.stat(path5);
1931
+ return stat4.isFile();
1932
+ },
1933
+ {
1934
+ message: "`--input` must be a file"
1935
+ }
1936
+ ),
1937
+ output: z7.string().nonempty("`--output` is required")
1938
+ });
1939
+ function commitmentCommand(program) {
1940
+ program.command("commitment").description(
1941
+ "Compute commitments for a file place into an output JSON file. Intended for debugging and introspection."
1942
+ ).requiredOption("-i, --input <path>", "Path to a file").requiredOption("-o, --output <path>", "Path to a file").action(async (rawOptions) => {
1943
+ const validatedOptions = await CommitmentOptionsSchema.parseAsync(rawOptions);
1944
+ const input = fs2.createReadStream(validatedOptions.input);
1945
+ const commitment = await generateCommitments(Readable.toWeb(input));
1946
+ await fsP.writeFile(validatedOptions.output, JSON.stringify(commitment));
1947
+ });
1948
+ }
1949
+
1713
1950
  // src/commands/context.tsx
1714
1951
  import Table2 from "cli-table3";
1715
- import { render as render3 } from "ink";
1716
- import { z as z7 } from "zod";
1717
- import { jsx as jsx7 } from "react/jsx-runtime";
1718
- var CreateContextOptionsSchema = z7.object({
1719
- name: z7.string().optional(),
1952
+ import { render as render2 } from "ink";
1953
+ import { z as z8 } from "zod";
1954
+
1955
+ // src/utils/url.ts
1956
+ function sanitizeRpcUrl(urlString) {
1957
+ const url = new URL(urlString);
1958
+ if (url.pathname === "/") {
1959
+ let result = `${url.protocol}//${url.host}`;
1960
+ if (url.search) result += url.search;
1961
+ if (url.hash) result += url.hash;
1962
+ return result;
1963
+ }
1964
+ return url.toString();
1965
+ }
1966
+
1967
+ // src/commands/context.tsx
1968
+ import { jsx as jsx6 } from "react/jsx-runtime";
1969
+ var CreateContextOptionsSchema = z8.object({
1970
+ name: z8.string().optional(),
1720
1971
  shelbyRpcEndpoint: EndpointSchema.optional(),
1721
1972
  aptosNetwork: AptosNetworkSchema.optional()
1722
1973
  // TODO: Add support for custom endpoints objects
1723
1974
  });
1724
- var UpdateContextOptionsSchema = z7.object({
1975
+ var UpdateContextOptionsSchema = z8.object({
1725
1976
  shelbyRpcEndpoint: EndpointSchema.optional(),
1726
1977
  aptosNetwork: AptosNetworkSchema.optional()
1727
1978
  // TODO: Add support for custom endpoints objects
@@ -1730,43 +1981,45 @@ function contextCommand(program) {
1730
1981
  const context = program.command("context").description("Manage network contexts (Shelby RPC & Aptos endpoints)");
1731
1982
  context.command("create").description("Create a new context").option("--name <context-name>", "Name of the context").option("--shelby-rpc-endpoint <url>", "URL of the Shelby RPC service").option("--aptos-network <network>", "Aptos network").action((options) => {
1732
1983
  CreateContextOptionsSchema.parse(options);
1733
- const { name: name2, shelbyRpcEndpoint, aptosNetwork } = options;
1984
+ const { name, shelbyRpcEndpoint, aptosNetwork } = options;
1734
1985
  const configPath = program.opts().configFile;
1735
1986
  let config;
1736
1987
  try {
1737
1988
  config = loadConfig(configPath);
1738
- } catch (error) {
1989
+ } catch (_error) {
1739
1990
  config = {
1740
1991
  contexts: {},
1741
1992
  accounts: {},
1742
- default_context: name2 || "",
1993
+ default_context: name || "",
1743
1994
  default_account: "default_account"
1744
1995
  };
1745
1996
  }
1746
- if (name2 && shelbyRpcEndpoint && aptosNetwork) {
1747
- config.contexts[name2] = {
1748
- shelby_rpc_endpoint: shelbyRpcEndpoint,
1997
+ if (name && shelbyRpcEndpoint && aptosNetwork) {
1998
+ const cleanedShelbyRpcEndpoint = sanitizeRpcUrl(shelbyRpcEndpoint);
1999
+ config.contexts[name] = {
2000
+ shelby_rpc_endpoint: cleanedShelbyRpcEndpoint,
1749
2001
  aptos_network: aptosNetwork
1750
2002
  };
1751
2003
  saveConfig(config, configPath);
1752
- console.log(`\u2705 Context '${name2}' created successfully`);
2004
+ console.log(`\u2705 Context '${name}' created successfully`);
1753
2005
  return;
1754
2006
  }
1755
- const { unmount } = render3(
1756
- /* @__PURE__ */ jsx7(
2007
+ const { unmount } = render2(
2008
+ /* @__PURE__ */ jsx6(
1757
2009
  ContextWizard,
1758
2010
  {
1759
2011
  onComplete: ({
1760
- name: name3,
2012
+ name: name2,
1761
2013
  shelbyRpcEndpoint: shelbyRpcEndpoint2,
1762
2014
  aptosNetwork: aptosNetwork2
1763
2015
  }) => {
1764
- config.contexts[name3] = {
1765
- shelby_rpc_endpoint: shelbyRpcEndpoint2,
2016
+ const cleanedShelbyRpcEndpoint = sanitizeRpcUrl(shelbyRpcEndpoint2);
2017
+ config.contexts[name2] = {
2018
+ shelby_rpc_endpoint: cleanedShelbyRpcEndpoint,
1766
2019
  aptos_network: aptosNetwork2
1767
2020
  };
1768
2021
  saveConfig(config, configPath);
1769
- console.log(`\u2705 Context '${name3}' created successfully`);
2022
+ console.log(`\u2705 Context '${name2}' created successfully`);
1770
2023
  unmount();
1771
2024
  process.exit(0);
1772
2025
  }
@@ -1792,7 +2045,7 @@ function contextCommand(program) {
1792
2045
  const currentContext = config.contexts[contextName];
1793
2046
  if (shelbyRpcEndpoint || aptosNetwork) {
1794
2047
  if (shelbyRpcEndpoint) {
1795
- config.contexts[contextName].shelby_rpc_endpoint = shelbyRpcEndpoint;
2048
+ config.contexts[contextName].shelby_rpc_endpoint = sanitizeRpcUrl(shelbyRpcEndpoint);
1796
2049
  }
1797
2050
  if (aptosNetwork) {
1798
2051
  config.contexts[contextName].aptos_network = aptosNetwork;
@@ -1801,8 +2054,8 @@ function contextCommand(program) {
1801
2054
  console.log(`\u2705 Context '${contextName}' updated successfully`);
1802
2055
  return;
1803
2056
  }
1804
- const { unmount } = render3(
1805
- /* @__PURE__ */ jsx7(
2057
+ const { unmount } = render2(
2058
+ /* @__PURE__ */ jsx6(
1806
2059
  UpdateContextWizard,
1807
2060
  {
1808
2061
  contextName,
@@ -1813,7 +2066,7 @@ function contextCommand(program) {
1813
2066
  aptosNetwork: aptosNetwork2
1814
2067
  }) => {
1815
2068
  if (shelbyRpcEndpoint2) {
1816
- config.contexts[contextName].shelby_rpc_endpoint = shelbyRpcEndpoint2;
2069
+ config.contexts[contextName].shelby_rpc_endpoint = sanitizeRpcUrl(shelbyRpcEndpoint2);
1817
2070
  }
1818
2071
  if (aptosNetwork2) {
1819
2072
  config.contexts[contextName].aptos_network = aptosNetwork2;
@@ -1900,22 +2153,21 @@ function contextCommand(program) {
1900
2153
 
1901
2154
  // src/commands/download.tsx
1902
2155
  import * as fsS from "fs";
1903
- import * as fs2 from "fs/promises";
2156
+ import * as fs3 from "fs/promises";
1904
2157
  import * as path3 from "path";
1905
- import { Transform as Transform2 } from "stream";
2158
+ import { Readable as Readable2, Transform } from "stream";
1906
2159
  import { pipeline } from "stream/promises";
1907
- import { Aptos as Aptos4 } from "@aptos-labs/ts-sdk";
1908
2160
  import ora from "ora";
1909
- import { z as z8 } from "zod";
2161
+ import { z as z9 } from "zod";
1910
2162
  var denormBlobName2 = (a, b, c) => denormBlobName(path3, a, b, c);
1911
2163
  var endsWithDirectorySeparator = (filePath) => {
1912
2164
  return filePath.endsWith("/") || filePath.endsWith("\\") || filePath.endsWith(path3.sep);
1913
2165
  };
1914
- var DownloadOptionsSchema = z8.object({
1915
- input: z8.string().min(1, "Input must be a valid blob name or directory prefix").describe("Blob name or directory prefix to download"),
1916
- output: z8.string().min(1, "Output must be a valid filepath").describe("Local path where to save the downloaded content"),
1917
- recursive: z8.boolean().default(false).describe("Download assuming canonical directory layout and recurse"),
1918
- force: z8.boolean().default(false).describe("Overwrite the output if it already exists")
2166
+ var DownloadOptionsSchema = z9.object({
2167
+ input: z9.string().min(1, "Input must be a valid blob name or directory prefix").describe("Blob name or directory prefix to download"),
2168
+ output: z9.string().min(1, "Output must be a valid filepath").describe("Local path where to save the downloaded content"),
2169
+ recursive: z9.boolean().default(false).describe("Download assuming canonical directory layout and recurse"),
2170
+ force: z9.boolean().default(false).describe("Overwrite the output if it already exists")
1919
2171
  }).refine(
1920
2172
  (data) => {
1921
2173
  if (data.recursive) {
@@ -1944,7 +2196,7 @@ var DownloadOptionsSchema = z8.object({
1944
2196
  async function validateOutput(options) {
1945
2197
  const parentDir = path3.dirname(options.output);
1946
2198
  try {
1947
- const parentStats = await fs2.stat(parentDir);
2199
+ const parentStats = await fs3.stat(parentDir);
1948
2200
  if (!parentStats.isDirectory()) {
1949
2201
  throw new Error(
1950
2202
  `Parent path '${parentDir}' exists but is not a directory. Cannot create output ${options.recursive ? "directory" : "file"} '${options.output}'.`
@@ -1961,7 +2213,7 @@ async function validateOutput(options) {
1961
2213
  if (options.force) return;
1962
2214
  let outputStats;
1963
2215
  try {
1964
- outputStats = await fs2.stat(options.output);
2216
+ outputStats = await fs3.stat(options.output);
1965
2217
  } catch (error) {
1966
2218
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
1967
2219
  return;
@@ -1980,7 +2232,7 @@ async function validateOutput(options) {
1980
2232
  );
1981
2233
  }
1982
2234
  if (options.recursive) {
1983
- const entries = await fs2.readdir(options.output);
2235
+ const entries = await fs3.readdir(options.output);
1984
2236
  if (entries.length > 0) {
1985
2237
  throw new Error(
1986
2238
  `Directory '${options.output}' exists and is not empty. Use --force to overwrite or choose an empty directory.`
@@ -1992,10 +2244,12 @@ async function validateOutput(options) {
1992
2244
  );
1993
2245
  }
1994
2246
  }
1995
- async function createFileList(options, nodeClient, blobClient, account) {
2247
+ async function createFileList(options, nodeClient, account) {
1996
2248
  const matchingBlobList = [];
1997
2249
  if (options.recursive) {
1998
- const allBlobs = await blobClient.getAccountBlobs({ account });
2250
+ const allBlobs = await nodeClient.coordination.getAccountBlobs({
2251
+ account
2252
+ });
1999
2253
  for (const blobMd of allBlobs) {
2000
2254
  if (!blobMd.name.startsWith(options.input)) continue;
2001
2255
  matchingBlobList.push(blobMd);
@@ -2006,12 +2260,12 @@ async function createFileList(options, nodeClient, blobClient, account) {
2006
2260
  );
2007
2261
  }
2008
2262
  } else {
2009
- const md = await blobClient.getBlobMetadata({
2263
+ const md = await nodeClient.coordination.getBlobMetadata({
2010
2264
  account,
2011
2265
  name: options.input
2012
2266
  });
2013
2267
  if (md === void 0) {
2014
- throw new Error(`Could not find a blob with name ${name}`);
2268
+ throw new Error(`Could not find a blob with name ${options.input}`);
2015
2269
  }
2016
2270
  matchingBlobList.push(md);
2017
2271
  }
@@ -2034,7 +2288,7 @@ async function createOutputDirectories(fileList) {
2034
2288
  }
2035
2289
  for (const dir of uniqueDirectories) {
2036
2290
  try {
2037
- await fs2.mkdir(dir, { recursive: true });
2291
+ await fs3.mkdir(dir, { recursive: true });
2038
2292
  } catch (error) {
2039
2293
  throw new Error(
2040
2294
  `Failed to create directory '${dir}': ${error instanceof Error ? error.message : error}`
@@ -2045,7 +2299,7 @@ async function createOutputDirectories(fileList) {
2045
2299
  function createProgressTransform(totalBytes, reporter) {
2046
2300
  const startTime = performance.now();
2047
2301
  let bytesDownloaded = 0;
2048
- return new Transform2({
2302
+ return new Transform({
2049
2303
  transform(chunk, _, callback) {
2050
2304
  bytesDownloaded += chunk.length;
2051
2305
  const now = performance.now();
@@ -2094,13 +2348,10 @@ function downloadCommand(program) {
2094
2348
  config,
2095
2349
  program.opts().account
2096
2350
  ).account;
2097
- const aptos = new Aptos4(shelbyConfig.aptos.config);
2098
2351
  const nodeClient = new ShelbyNodeClient(shelbyConfig);
2099
- const blobClient = new ShelbyBlobClient({ aptos });
2100
2352
  const fileList = await createFileList(
2101
2353
  options,
2102
2354
  nodeClient,
2103
- blobClient,
2104
2355
  activeAccount.accountAddress
2105
2356
  );
2106
2357
  for (const fileEntry of fileList) {
@@ -2110,7 +2361,7 @@ function downloadCommand(program) {
2110
2361
  }
2111
2362
  if (options.force) {
2112
2363
  console.log(`--force was set, so deleting ${options.output}`);
2113
- await fs2.rm(options.output, { recursive: true, force: true });
2364
+ await fs3.rm(options.output, { recursive: true, force: true });
2114
2365
  }
2115
2366
  const handleSigint = () => {
2116
2367
  spinner.fail("Quitting due to ctrl-C / SIGINT...");
@@ -2135,15 +2386,16 @@ function downloadCommand(program) {
2135
2386
  };
2136
2387
  for (const fileEntry of fileList) {
2137
2388
  const out = fsS.createWriteStream(fileEntry.filename);
2138
- const { stream } = await nodeClient.getBlob(
2139
- activeAccount.accountAddress,
2140
- fileEntry.blobname
2141
- );
2389
+ const { readable } = await nodeClient.rpc.getBlob({
2390
+ account: activeAccount.accountAddress,
2391
+ blobName: fileEntry.blobname
2392
+ });
2142
2393
  const reporter = (filePercent, rateMiB) => {
2143
2394
  spinner.text = `Downloading ${fileEntry.blobname}, ${filePercent}% at ${rateMiB} MiB/s .. (Overall: ${formatProgressPercent()}%, ${formatProgressRate()} MiB/s)`;
2144
2395
  };
2396
+ const nodeStream = Readable2.fromWeb(readable);
2145
2397
  await pipeline(
2146
- stream,
2398
+ nodeStream,
2147
2399
  createProgressTransform(fileEntry.sizeBytes, reporter),
2148
2400
  out
2149
2401
  );
@@ -2156,16 +2408,196 @@ function downloadCommand(program) {
2156
2408
  );
2157
2409
  }
2158
2410
 
2411
+ // src/commands/faucet.tsx
2412
+ import { execaSync } from "execa";
2413
+ import { z as z10 } from "zod";
2414
+ var FaucetOptionsSchema = z10.object({
2415
+ network: z10.enum(["devnet", "testnet", "mainnet"]).optional(),
2416
+ "no-open": z10.boolean().optional().default(false)
2417
+ });
2418
+ function faucetCommand(program) {
2419
+ program.command("faucet").description("Open the Shelby faucet web page to request tokens").option(
2420
+ "--network <network>",
2421
+ "Network to request tokens for (devnet, testnet)"
2422
+ ).option("--no-open", "Don't automatically open browser, just print the URL").action((options) => {
2423
+ try {
2424
+ const validatedOptions = FaucetOptionsSchema.parse(options);
2425
+ const configPath = program.opts().configFile;
2426
+ const config = loadConfig(configPath);
2427
+ const accountName = program.opts().account || config.default_account;
2428
+ const { account } = getCurrentAccount(config, accountName);
2429
+ const network = validatedOptions.network || "devnet";
2430
+ if (network === "mainnet") {
2431
+ throw new Error(
2432
+ "\u274C No faucet available for mainnet. Mainnet tokens must be obtained through other means."
2433
+ );
2434
+ }
2435
+ const faucetUrl = new URL("https://docs.shelby.xyz/docs/faucet");
2436
+ faucetUrl.searchParams.set(
2437
+ "address",
2438
+ account.accountAddress.toString()
2439
+ );
2440
+ faucetUrl.searchParams.set("network", network);
2441
+ const urlString = faucetUrl.toString();
2442
+ if (validatedOptions["no-open"]) {
2443
+ console.log("\u{1F310} Faucet URL:");
2444
+ console.log(urlString);
2445
+ console.log(
2446
+ "\nCopy and paste this URL into your browser to request tokens."
2447
+ );
2448
+ } else {
2449
+ console.log(`\u{1F4A7} Opening Shelby faucet for ${network}...`);
2450
+ console.log(
2451
+ `\u{1F3E6} Pre-filled address: ${account.accountAddress.toString()}`
2452
+ );
2453
+ try {
2454
+ openBrowser(urlString);
2455
+ console.log("\u2705 Browser opened successfully!");
2456
+ } catch (_error) {
2457
+ console.log("\u274C Failed to open browser automatically.");
2458
+ console.log("\u{1F310} Please copy and open this URL manually:");
2459
+ console.log(urlString);
2460
+ }
2461
+ }
2462
+ } catch (error) {
2463
+ console.error(
2464
+ `\u274C Faucet command failed: ${error instanceof Error ? error.message : String(error)}`
2465
+ );
2466
+ process.exit(1);
2467
+ }
2468
+ });
2469
+ }
2470
+ function openBrowser(url) {
2471
+ const platform = process.platform;
2472
+ try {
2473
+ if (platform === "darwin") {
2474
+ execaSync("open", [url]);
2475
+ } else if (platform === "win32") {
2476
+ execaSync("start", [url], { shell: true });
2477
+ } else {
2478
+ execaSync("xdg-open", [url]);
2479
+ }
2480
+ } catch (error) {
2481
+ throw new Error(
2482
+ `Failed to open browser: ${error instanceof Error ? error.message : String(error)}`
2483
+ );
2484
+ }
2485
+ }
2486
+
2487
+ // src/commands/init.tsx
2488
+ import { render as render3 } from "ink";
2489
+ import { jsx as jsx7 } from "react/jsx-runtime";
2490
+ function initCommand(program) {
2491
+ program.command("init").description(
2492
+ "Bootstrap your Shelby config via an interactive wizard or flags"
2493
+ ).option(
2494
+ "--setup-default-contexts",
2495
+ "Create devnet, testnet, mainnet contexts",
2496
+ false
2497
+ ).option("--context <name>", "Custom context name").option(
2498
+ "--shelby-rpc-endpoint <url>",
2499
+ "Shelby RPC endpoint for this context"
2500
+ ).option(
2501
+ "--aptos-api-endpoint <url>",
2502
+ "Aptos REST API endpoint for this context"
2503
+ ).option(
2504
+ "--account <name>",
2505
+ "Account name to create/update",
2506
+ "default_account"
2507
+ ).option(
2508
+ "--signature-scheme <scheme>",
2509
+ // "Signature scheme (ed25519 or secp256k1)",
2510
+ "Signature scheme (ed25519)",
2511
+ ED25519_NAME
2512
+ ).option("--private-key <key>", "Raw private key").action((options) => {
2513
+ const configPath = program.opts().configFile || "~/.shelby/config.yaml";
2514
+ if (options.setupDefaultContexts || options.context && options.shelbyRpcEndpoint && options.aptosNetwork) {
2515
+ let config;
2516
+ try {
2517
+ config = loadConfig(configPath);
2518
+ } catch (_error) {
2519
+ config = {
2520
+ contexts: {},
2521
+ accounts: {},
2522
+ default_context: options.setupDefaultContexts ? "devnet" : options.context,
2523
+ default_account: options.account
2524
+ };
2525
+ }
2526
+ if (options.setupDefaultContexts) {
2527
+ config.contexts.local = {
2528
+ aptos_network: "local",
2529
+ shelby_rpc_endpoint: "http://localhost:9090"
2530
+ };
2531
+ config.contexts.devnet = {
2532
+ aptos_network: "devnet",
2533
+ shelby_rpc_endpoint: "https://shelby.rpc.devnet.example.com"
2534
+ };
2535
+ config.contexts.testnet = {
2536
+ aptos_network: "testnet",
2537
+ shelby_rpc_endpoint: "https://shelby.rpc.testnet.example.com"
2538
+ };
2539
+ config.contexts.mainnet = {
2540
+ aptos_network: "mainnet",
2541
+ shelby_rpc_endpoint: "https://shelby.rpc.mainnet.example.com"
2542
+ };
2543
+ }
2544
+ if (options.context && options.shelbyRpcEndpoint && options.aptosNetwork) {
2545
+ config.contexts[options.context] = {
2546
+ aptos_network: options.aptosNetwork,
2547
+ shelby_rpc_endpoint: options.shelbyRpcEndpoint
2548
+ };
2549
+ }
2550
+ if (options.privateKey) {
2551
+ config.accounts[options.account] = {
2552
+ private_key: options.privateKey
2553
+ };
2554
+ }
2555
+ saveConfig(config, configPath);
2556
+ console.log(
2557
+ `\u2705 Configuration saved to ${resolveConfigPath(configPath)}`
2558
+ );
2559
+ } else {
2560
+ const { unmount } = render3(
2561
+ /* @__PURE__ */ jsx7(
2562
+ InitWizard,
2563
+ {
2564
+ onComplete: (config) => {
2565
+ saveConfig(config, configPath);
2566
+ console.log(
2567
+ `\u2705 Configuration saved to ${resolveConfigPath(configPath)}`
2568
+ );
2569
+ if (config.default_account && config.accounts[config.default_account]?.private_key?.startsWith("ed25519-priv-")) {
2570
+ console.log(
2571
+ "\n\u2139\uFE0F To fund your new account on-chain (devnet/testnet only):"
2572
+ );
2573
+ console.log(" 1. Import the private key into Aptos CLI:");
2574
+ console.log(
2575
+ ` aptos init --profile ${config.default_account} --private-key ${config.accounts[config.default_account].private_key} --network ${config.default_context}`
2576
+ );
2577
+ console.log(" 2. Run the faucet:");
2578
+ console.log(
2579
+ ` aptos account fund-with-faucet --profile ${config.default_account}`
2580
+ );
2581
+ }
2582
+ unmount();
2583
+ process.exit(0);
2584
+ }
2585
+ }
2586
+ )
2587
+ );
2588
+ }
2589
+ });
2590
+ }
2591
+
2159
2592
  // src/commands/upload.tsx
2160
- import * as fs3 from "fs/promises";
2593
+ import * as fs4 from "fs/promises";
2161
2594
  import * as path4 from "path";
2162
- import { Readable as Readable4 } from "stream";
2163
- import { Aptos as Aptos5 } from "@aptos-labs/ts-sdk";
2595
+ import { Aptos as Aptos3 } from "@aptos-labs/ts-sdk";
2164
2596
  import { glob } from "glob";
2165
- import { Box as Box5, Text as Text5, render as render4 } from "ink";
2597
+ import { Box as Box5, render as render4, Text as Text5 } from "ink";
2166
2598
  import SelectInput2 from "ink-select-input";
2167
2599
  import ora2 from "ora";
2168
- import { z as z9 } from "zod";
2600
+ import { z as z11 } from "zod";
2169
2601
 
2170
2602
  // src/utils/errors.ts
2171
2603
  var ERROR_CODES = {
@@ -2238,7 +2670,7 @@ var handleError = (error) => {
2238
2670
  // src/commands/upload.tsx
2239
2671
  import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
2240
2672
  var normBlobName2 = (i, f, b) => normBlobName(path4, i, f, b);
2241
- var flexibleDateSchema = z9.string().transform((val) => {
2673
+ var flexibleDateSchema = z11.string().transform((val) => {
2242
2674
  if (/^\d+$/.test(val)) {
2243
2675
  const timestamp = Number.parseInt(val, 10);
2244
2676
  if (timestamp > 0 && timestamp < 4102444800) {
@@ -2251,18 +2683,18 @@ var flexibleDateSchema = z9.string().transform((val) => {
2251
2683
  }
2252
2684
  return ret;
2253
2685
  });
2254
- var UploadOptionsSchema = z9.object({
2255
- input: z9.string().nonempty("`--input` is required"),
2256
- output: z9.string().nonempty("`output` is required"),
2686
+ var UploadOptionsSchema = z11.object({
2687
+ input: z11.string().nonempty("`--input` is required"),
2688
+ output: z11.string().nonempty("`output` is required"),
2257
2689
  expiration: flexibleDateSchema,
2258
- recursive: z9.boolean().optional().default(false),
2259
- assumeYes: z9.boolean().optional().default(false),
2260
- outputCommitments: z9.string().optional()
2690
+ recursive: z11.boolean().optional().default(false),
2691
+ assumeYes: z11.boolean().optional().default(false),
2692
+ outputCommitments: z11.string().optional()
2261
2693
  }).superRefine(async (data, ctx) => {
2262
- const stats = await fs3.stat(data.input);
2694
+ const stats = await fs4.stat(data.input);
2263
2695
  if (!stats.isFile() && !stats.isDirectory()) {
2264
2696
  ctx.addIssue({
2265
- code: z9.ZodIssueCode.custom,
2697
+ code: z11.ZodIssueCode.custom,
2266
2698
  message: "`--input` must be a file or a directory",
2267
2699
  path: ["input"]
2268
2700
  });
@@ -2271,7 +2703,7 @@ var UploadOptionsSchema = z9.object({
2271
2703
  if (stats.isDirectory()) {
2272
2704
  if (!data.output.endsWith("/")) {
2273
2705
  ctx.addIssue({
2274
- code: z9.ZodIssueCode.custom,
2706
+ code: z11.ZodIssueCode.custom,
2275
2707
  message: "When input is a directory, output must end with '/'",
2276
2708
  path: ["output"]
2277
2709
  });
@@ -2280,7 +2712,7 @@ var UploadOptionsSchema = z9.object({
2280
2712
  const blobNameResult = BlobNameSchema.safeParse(data.output);
2281
2713
  if (!blobNameResult.success) {
2282
2714
  ctx.addIssue({
2283
- code: z9.ZodIssueCode.custom,
2715
+ code: z11.ZodIssueCode.custom,
2284
2716
  message: "When input is a file, output must be a valid blob name (cannot end with '/')",
2285
2717
  path: ["output"]
2286
2718
  });
@@ -2288,7 +2720,7 @@ var UploadOptionsSchema = z9.object({
2288
2720
  }
2289
2721
  });
2290
2722
  async function createFilelist(options) {
2291
- const stats = await fs3.stat(options.input);
2723
+ const stats = await fs4.stat(options.input);
2292
2724
  if (stats.isFile()) {
2293
2725
  const blobname = normBlobName2(options.input, options.input, options.output);
2294
2726
  const blobNameValidation = BlobNameSchema.safeParse(blobname);
@@ -2309,7 +2741,7 @@ async function createFilelist(options) {
2309
2741
  nodir: true
2310
2742
  });
2311
2743
  for await (const file of result) {
2312
- const stats2 = await fs3.stat(file);
2744
+ const stats2 = await fs4.stat(file);
2313
2745
  const blobname = normBlobName2(options.input, file, options.output);
2314
2746
  const blobNameValidation = BlobNameSchema.safeParse(blobname);
2315
2747
  if (!blobNameValidation.success) {
@@ -2399,13 +2831,12 @@ function uploadCommand(program) {
2399
2831
  const shelbyConfig = getCurrentShelbyConfig(config, {
2400
2832
  context: program.opts().context
2401
2833
  });
2402
- const shelbyNodeClient = new ShelbyNodeClient(shelbyConfig);
2403
2834
  const activeAccount = getCurrentAccount(
2404
2835
  config,
2405
2836
  program.opts().account
2406
2837
  ).account;
2407
- const aptos = new Aptos5(shelbyConfig.aptos.config);
2408
- const shelbyBlobClient = new ShelbyBlobClient({ aptos });
2838
+ const aptos = new Aptos3(shelbyConfig.aptos.config);
2839
+ const shelbyClient = new ShelbyNodeClient(shelbyConfig);
2409
2840
  const handleSigint = () => {
2410
2841
  spinner.fail("Quitting due to ctrl-C / SIGINT...");
2411
2842
  process.exit(1);
@@ -2433,30 +2864,29 @@ function uploadCommand(program) {
2433
2864
  for (const entry of filelist) {
2434
2865
  totalSize += entry.sizeBytes;
2435
2866
  }
2436
- let hasUploadedBlob = false;
2867
+ const hasUploadedBlob = false;
2437
2868
  for (const entry of filelist) {
2438
2869
  spinner.text = `Reading ${entry.filename}.. (Overall: ${formatProgressPercent()}%, ${formatProgressRate()} MiB/s)`;
2439
2870
  try {
2440
- const blobData = await fs3.readFile(entry.filename);
2871
+ const blobData = await fs4.readFile(entry.filename);
2441
2872
  if (blobData.length !== entry.sizeBytes) {
2442
2873
  throw new Error(
2443
2874
  `Size of file ${entry.filename} changed after initial scan. Original size was ${entry.sizeBytes} but it is now ${blobData.length}`
2444
2875
  );
2445
2876
  }
2446
2877
  spinner.text = `Committing ${entry.filename} to L1.. (Overall: ${formatProgressPercent()}%, ${formatProgressRate()} MiB/s)`;
2447
- const existingBlobMetadata = await shelbyBlobClient.getBlobMetadata({
2878
+ const existingBlobMetadata = await shelbyClient.coordination.getBlobMetadata({
2448
2879
  account: activeAccount.accountAddress,
2449
2880
  name: entry.blobname
2450
2881
  });
2451
- const blobCommitments = await generateCommitments(
2452
- Readable4.from(blobData)
2453
- );
2882
+ const blobCommitments = await generateCommitments(blobData);
2454
2883
  if (!existingBlobMetadata) {
2455
- const { transaction: pendingWriteBlobCommitmentsTransaction } = await shelbyBlobClient.writeBlobCommitments({
2884
+ const { transaction: pendingWriteBlobCommitmentsTransaction } = await shelbyClient.coordination.registerBlob({
2456
2885
  account: activeAccount,
2457
2886
  blobName: entry.blobname,
2458
- lifetime: validatedOptions.expiration.getTime() * 1e3,
2459
- blobCommitments
2887
+ blobMerkleRoot: blobCommitments.blob_merkle_root,
2888
+ size: blobData.length,
2889
+ expirationMicros: validatedOptions.expiration.getTime() * 1e3
2460
2890
  });
2461
2891
  await aptos.waitForTransaction({
2462
2892
  transactionHash: pendingWriteBlobCommitmentsTransaction.hash
@@ -2467,29 +2897,6 @@ function uploadCommand(program) {
2467
2897
  if (validatedOptions.outputCommitments) {
2468
2898
  outputCommitments[entry.filename] = blobCommitments;
2469
2899
  }
2470
- const existingBlobChunks = await shelbyBlobClient.getBlobChunks({
2471
- account: activeAccount.accountAddress,
2472
- name: entry.blobname
2473
- });
2474
- if (existingBlobChunks.length === 0) {
2475
- console.error(
2476
- `Blob ${entry.blobname} does not exist on L1, an error occurred when uploading commitments...`
2477
- );
2478
- process.exit(1);
2479
- }
2480
- if (!existingBlobChunks.every(
2481
- (chunk) => chunk.location.variant === "stored"
2482
- )) {
2483
- spinner.text = `Uploading ${entry.filename} to Shelby RPC.. (Overall: ${formatProgressPercent()}%, ${formatProgressRate()} MiB/s)`;
2484
- await shelbyNodeClient.putBlob(
2485
- activeAccount.accountAddress,
2486
- entry.blobname,
2487
- blobData
2488
- );
2489
- hasUploadedBlob = true;
2490
- } else {
2491
- spinner.text = "All blob chunks have been stored on L1, skipping upload to Shelby RPC...";
2492
- }
2493
2900
  amountUploaded += blobData.length;
2494
2901
  } catch (error) {
2495
2902
  const { displayMessage } = handleError(error);
@@ -2498,7 +2905,7 @@ function uploadCommand(program) {
2498
2905
  }
2499
2906
  }
2500
2907
  if (validatedOptions.outputCommitments) {
2501
- await fs3.writeFile(
2908
+ await fs4.writeFile(
2502
2909
  validatedOptions.outputCommitments,
2503
2910
  JSON.stringify(outputCommitments)
2504
2911
  );
@@ -2513,33 +2920,6 @@ function uploadCommand(program) {
2513
2920
  });
2514
2921
  }
2515
2922
 
2516
- // src/commands/commitment.ts
2517
- import * as fs4 from "fs";
2518
- import * as fsP from "fs/promises";
2519
- import { z as z10 } from "zod";
2520
- var CommitmentOptionsSchema = z10.object({
2521
- input: z10.string().nonempty("`--input` is required").refine(
2522
- async (path5) => {
2523
- const stat4 = await fsP.stat(path5);
2524
- return stat4.isFile();
2525
- },
2526
- {
2527
- message: "`--input` must be a file"
2528
- }
2529
- ),
2530
- output: z10.string().nonempty("`--output` is required")
2531
- });
2532
- function commitmentCommand(program) {
2533
- program.command("commitment").description(
2534
- "Compute commitments for a file place into an output JSON file. Intended for debugging and introspection."
2535
- ).requiredOption("-i, --input <path>", "Path to a file").requiredOption("-o, --output <path>", "Path to a file").action(async (rawOptions) => {
2536
- const validatedOptions = await CommitmentOptionsSchema.parseAsync(rawOptions);
2537
- const input = fs4.createReadStream(validatedOptions.input);
2538
- const commitment = await generateCommitments(input);
2539
- await fsP.writeFile(validatedOptions.output, JSON.stringify(commitment));
2540
- });
2541
- }
2542
-
2543
2923
  // src/cli.tsx
2544
2924
  function createProgram() {
2545
2925
  const config = loadConfig();
@@ -2563,6 +2943,7 @@ function createProgram() {
2563
2943
  accountCommand(program);
2564
2944
  contextCommand(program);
2565
2945
  downloadCommand(program);
2946
+ faucetCommand(program);
2566
2947
  uploadCommand(program);
2567
2948
  commitmentCommand(program);
2568
2949
  return program;