New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

skynet-js

Package Overview
Dependencies
Maintainers
3
Versions
68
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

skynet-js - npm Package Compare versions

Comparing version 4.0.11-beta to 4.0.12-beta

dist/cjs/mysky/encrypted_files.d.ts

6

dist/cjs/client.d.ts

@@ -1,2 +0,2 @@

import { AxiosResponse } from "axios";
import { AxiosResponse, ResponseType } from "axios";
import type { Method } from "axios";

@@ -32,2 +32,3 @@ import { uploadFile, uploadLargeFile, uploadDirectory, uploadDirectoryRequest, uploadSmallFile, uploadSmallFileRequest, uploadLargeFileRequest } from "./upload";

* @property [headers] - Any request headers to set.
* @property [responseType] - The response type.
* @property [transformRequest] - A function that allows manually transforming the request.

@@ -44,2 +45,3 @@ * @property [transformResponse] - A function that allows manually transforming the response.

extraPath?: string;
responseType?: ResponseType;
transformRequest?: (data: unknown) => string;

@@ -83,2 +85,3 @@ transformResponse?: (data: string) => Record<string, unknown>;

getEntryLink: (userID: string, path: string) => Promise<string>;
getJSONEncrypted: (userID: string, pathSeed: string, customOptions?: import("./skydb").CustomGetJSONOptions | undefined) => Promise<import("./mysky/encrypted_files").EncryptedJSONResponse>;
};

@@ -90,2 +93,3 @@ db: {

setDataLink: (privateKey: string, dataKey: string, dataLink: string, customOptions?: import("./skydb").CustomSetJSONOptions | undefined) => Promise<void>;
getRawBytes: (publicKey: string, dataKey: string, customOptions?: import("./skydb").CustomGetJSONOptions | undefined) => Promise<import("./skydb").RawBytesResponse>;
};

@@ -92,0 +96,0 @@ registry: {

@@ -63,2 +63,3 @@ "use strict";

getEntryLink: file_1.getEntryLink.bind(this),
getJSONEncrypted: file_1.getJSONEncrypted.bind(this),
};

@@ -71,2 +72,3 @@ // SkyDB

setDataLink: skydb_1.setDataLink.bind(this),
getRawBytes: skydb_1.getRawBytes.bind(this),
};

@@ -165,2 +167,3 @@ // SkyDB helpers

onUploadProgress,
responseType: config.responseType,
transformRequest: config.transformRequest,

@@ -167,0 +170,0 @@ transformResponse: config.transformResponse,

@@ -22,2 +22,3 @@ /// <reference types="node" />

};
export declare const HASH_LENGTH = 32;
/**

@@ -69,2 +70,9 @@ * Derives a child seed from the given master seed and sub seed.

export declare function hashRegistryEntry(registryEntry: RegistryEntry, hashedDataKeyHex: boolean): Uint8Array;
/**
* Hashes the given string or byte array using sha512.
*
* @param message - The string or byte array to hash.
* @returns - The resulting hash.
*/
export declare function sha512(message: Uint8Array | string): Uint8Array;
//# sourceMappingURL=crypto.d.ts.map

@@ -6,3 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.hashRegistryEntry = exports.hashDataKey = exports.hashAll = exports.genKeyPairFromSeed = exports.genKeyPairAndSeed = exports.deriveChildSeed = void 0;
exports.sha512 = exports.hashRegistryEntry = exports.hashDataKey = exports.hashAll = exports.genKeyPairFromSeed = exports.genKeyPairAndSeed = exports.deriveChildSeed = exports.HASH_LENGTH = void 0;
const sjcl_1 = require("sjcl");

@@ -15,2 +15,3 @@ const blakejs_1 = require("blakejs");

const encoding_1 = require("./utils/encoding");
exports.HASH_LENGTH = 32;
/**

@@ -74,8 +75,7 @@ * Returns a blake2b 256bit hasher. See `NewHash` in Sia.

const hasher = newHash();
for (let i = 0; i < args.length; i++) {
blakejs_1.blake2bUpdate(hasher, args[i]);
}
args.forEach((arg) => blakejs_1.blake2bUpdate(hasher, arg));
return blakejs_1.blake2bFinal(hasher);
}
exports.hashAll = hashAll;
// TODO: Is this the same as hashString?
/**

@@ -111,2 +111,17 @@ * Hash the given data key.

/**
* Hashes the given string or byte array using sha512.
*
* @param message - The string or byte array to hash.
* @returns - The resulting hash.
*/
function sha512(message) {
if (typeof message === "string") {
return tweetnacl_1.hash(string_1.stringToUint8ArrayUtf8(message));
}
else {
return tweetnacl_1.hash(message);
}
}
exports.sha512 = sha512;
/**
* Generates a random seed of the given length in bytes.

@@ -113,0 +128,0 @@ *

@@ -0,1 +1,2 @@

import { ResponseType } from "axios";
import { SkynetClient } from "./client";

@@ -11,2 +12,3 @@ import { JsonData } from "./skydb";

* @property [range] - The Range request header to set for the download. Not applicable for in-borwser downloads.
* @property [responseType] - The response type.
* @property [query] - A query object to convert to a query parameter string and append to the URL.

@@ -20,2 +22,3 @@ * @property [subdomain=false] - Whether to return the final skylink in subdomain format.

range?: string;
responseType?: ResponseType;
subdomain?: boolean;

@@ -80,2 +83,3 @@ };

range: undefined;
responseType: undefined;
query: undefined;

@@ -82,0 +86,0 @@ subdomain: boolean;

@@ -16,2 +16,3 @@ "use strict";

range: undefined,
responseType: undefined,
query: undefined,

@@ -18,0 +19,0 @@ subdomain: false,

import { SkynetClient } from "./client";
import { EntryData } from "./mysky";
import { EncryptedJSONResponse } from "./mysky/encrypted_files";
import { CustomGetEntryOptions } from "./registry";

@@ -38,2 +39,13 @@ import { CustomGetJSONOptions, JSONResponse } from "./skydb";

export declare function getEntryData(this: SkynetClient, userID: string, path: string, customOptions?: CustomGetEntryOptions): Promise<EntryData>;
/**
* Gets Encrypted JSON set with MySky at the given data path for the given
* public user ID.
*
* @param this - SkynetClient
* @param userID - The MySky public user ID.
* @param pathSeed - The share-able secret path seed.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - An object containing the decrypted json data.
*/
export declare function getJSONEncrypted(this: SkynetClient, userID: string, pathSeed: string, customOptions?: CustomGetJSONOptions): Promise<EncryptedJSONResponse>;
//# sourceMappingURL=file.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getEntryData = exports.getEntryLink = exports.getJSON = void 0;
exports.getJSONEncrypted = exports.getEntryData = exports.getEntryLink = exports.getJSON = void 0;
const encrypted_files_1 = require("./mysky/encrypted_files");
const tweak_1 = require("./mysky/tweak");

@@ -8,2 +9,5 @@ const registry_1 = require("./registry");

const validation_1 = require("./utils/validation");
// ====
// JSON
// ====
/**

@@ -28,3 +32,3 @@ * Gets Discoverable JSON set with MySky at the given data path for the given

};
const dataKey = tweak_1.deriveDiscoverableTweak(path);
const dataKey = tweak_1.deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -34,2 +38,5 @@ return await this.db.getJSON(userID, dataKey, opts);

exports.getJSON = getJSON;
// =====
// Entry
// =====
/**

@@ -48,3 +55,3 @@ * Gets the entry link for the entry set with MySky at the given data path, for

validation_1.validateString("path", path, "parameter");
const dataKey = tweak_1.deriveDiscoverableTweak(path);
const dataKey = tweak_1.deriveDiscoverableFileTweak(path);
// Do not hash the tweak anymore.

@@ -74,3 +81,3 @@ const opts = { ...registry_1.defaultGetEntryOptions, hashedDataKeyHex: true };

};
const dataKey = tweak_1.deriveDiscoverableTweak(path);
const dataKey = tweak_1.deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -84,1 +91,37 @@ const { entry } = await this.registry.getEntry(userID, dataKey, opts);

exports.getEntryData = getEntryData;
// ===============
// Encrypted Files
// ===============
/**
* Gets Encrypted JSON set with MySky at the given data path for the given
* public user ID.
*
* @param this - SkynetClient
* @param userID - The MySky public user ID.
* @param pathSeed - The share-able secret path seed.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - An object containing the decrypted json data.
*/
async function getJSONEncrypted(userID, pathSeed,
// TODO: Take a new options type?
customOptions) {
validation_1.validateString("userID", userID, "parameter");
validation_1.validateStringLen("pathSeed", pathSeed, "parameter", 64);
validation_1.validateOptionalObject("customOptions", customOptions, "parameter", skydb_1.defaultGetJSONOptions);
const opts = {
...skydb_1.defaultGetJSONOptions,
...this.customOptions,
...customOptions,
hashedDataKeyHex: true, // Do not hash the tweak anymore.
};
// Fetch the raw encrypted JSON data.
const dataKey = encrypted_files_1.deriveEncryptedFileTweak(pathSeed);
const { data } = await this.db.getRawBytes(userID, dataKey, opts);
if (data === null) {
return { data: null };
}
const key = encrypted_files_1.deriveEncryptedFileKeyEntropy(pathSeed);
const json = encrypted_files_1.decryptJSONFile(data, key);
return { data: json };
}
exports.getJSONEncrypted = getJSONEncrypted;

10

dist/cjs/index.d.ts
export { SkynetClient } from "./client";
export { deriveChildSeed, genKeyPairAndSeed, genKeyPairFromSeed } from "./crypto";
export { HASH_LENGTH, deriveChildSeed, genKeyPairAndSeed, genKeyPairFromSeed } from "./crypto";
export { getSkylinkUrlForPortal } from "./download";
export { getEntryUrlForPortal, signEntry } from "./registry";
export { DacLibrary, mySkyDomain, mySkyDevDomain } from "./mysky";
export { DacLibrary, MySky, mySkyDomain, mySkyDevDomain } from "./mysky";
export { deriveEncryptedFileKeyEntropy, deriveEncryptedFileSeed, deriveEncryptedFileTweak, ENCRYPTION_PATH_SEED_LENGTH, } from "./mysky/encrypted_files";
export { deriveDiscoverableFileTweak } from "./mysky/tweak";
export { convertSkylinkToBase32, convertSkylinkToBase64 } from "./skylink/format";

@@ -17,8 +19,8 @@ export { parseSkylink } from "./skylink/parse";

export type { CustomDownloadOptions, ResolveHnsResponse } from "./download";
export type { CustomConnectorOptions, MySky } from "./mysky";
export type { CustomConnectorOptions } from "./mysky";
export type { CustomPinOptions, PinResponse } from "./pin";
export type { CustomGetEntryOptions, CustomSetEntryOptions, SignedRegistryEntry, RegistryEntry } from "./registry";
export type { CustomGetJSONOptions, CustomSetJSONOptions, JsonData, JSONResponse } from "./skydb";
export type { CustomGetJSONOptions, CustomSetJSONOptions, JsonData, JSONResponse, RawBytesResponse } from "./skydb";
export type { CustomUploadOptions, UploadRequestResponse } from "./upload";
export type { ParseSkylinkOptions } from "./skylink/parse";
//# sourceMappingURL=index.d.ts.map
"use strict";
/* istanbul ignore file */
Object.defineProperty(exports, "__esModule", { value: true });
exports.PermLegacySkyID = exports.PermDiscoverable = exports.PermHidden = exports.PermWrite = exports.PermRead = exports.PermType = exports.PermCategory = exports.Permission = exports.uriSkynetPrefix = exports.uriHandshakePrefix = exports.getFullDomainUrlForPortal = exports.extractDomainForPortal = exports.defaultSkynetPortalUrl = exports.defaultPortalUrl = exports.uint8ArrayToStringUtf8 = exports.stringToUint8ArrayUtf8 = exports.MAX_REVISION = exports.getRootDirectory = exports.getRelativeFilePath = exports.isSkylinkV2 = exports.isSkylinkV1 = exports.parseSkylink = exports.convertSkylinkToBase64 = exports.convertSkylinkToBase32 = exports.mySkyDevDomain = exports.mySkyDomain = exports.DacLibrary = exports.signEntry = exports.getEntryUrlForPortal = exports.getSkylinkUrlForPortal = exports.genKeyPairFromSeed = exports.genKeyPairAndSeed = exports.deriveChildSeed = exports.SkynetClient = void 0;
exports.PermLegacySkyID = exports.PermDiscoverable = exports.PermHidden = exports.PermWrite = exports.PermRead = exports.PermType = exports.PermCategory = exports.Permission = exports.uriSkynetPrefix = exports.uriHandshakePrefix = exports.getFullDomainUrlForPortal = exports.extractDomainForPortal = exports.defaultSkynetPortalUrl = exports.defaultPortalUrl = exports.uint8ArrayToStringUtf8 = exports.stringToUint8ArrayUtf8 = exports.MAX_REVISION = exports.getRootDirectory = exports.getRelativeFilePath = exports.isSkylinkV2 = exports.isSkylinkV1 = exports.parseSkylink = exports.convertSkylinkToBase64 = exports.convertSkylinkToBase32 = exports.deriveDiscoverableFileTweak = exports.ENCRYPTION_PATH_SEED_LENGTH = exports.deriveEncryptedFileTweak = exports.deriveEncryptedFileSeed = exports.deriveEncryptedFileKeyEntropy = exports.mySkyDevDomain = exports.mySkyDomain = exports.MySky = exports.DacLibrary = exports.signEntry = exports.getEntryUrlForPortal = exports.getSkylinkUrlForPortal = exports.genKeyPairFromSeed = exports.genKeyPairAndSeed = exports.deriveChildSeed = exports.HASH_LENGTH = exports.SkynetClient = void 0;
var client_1 = require("./client");
Object.defineProperty(exports, "SkynetClient", { enumerable: true, get: function () { return client_1.SkynetClient; } });
var crypto_1 = require("./crypto");
Object.defineProperty(exports, "HASH_LENGTH", { enumerable: true, get: function () { return crypto_1.HASH_LENGTH; } });
Object.defineProperty(exports, "deriveChildSeed", { enumerable: true, get: function () { return crypto_1.deriveChildSeed; } });

@@ -18,4 +19,12 @@ Object.defineProperty(exports, "genKeyPairAndSeed", { enumerable: true, get: function () { return crypto_1.genKeyPairAndSeed; } });

Object.defineProperty(exports, "DacLibrary", { enumerable: true, get: function () { return mysky_1.DacLibrary; } });
Object.defineProperty(exports, "MySky", { enumerable: true, get: function () { return mysky_1.MySky; } });
Object.defineProperty(exports, "mySkyDomain", { enumerable: true, get: function () { return mysky_1.mySkyDomain; } });
Object.defineProperty(exports, "mySkyDevDomain", { enumerable: true, get: function () { return mysky_1.mySkyDevDomain; } });
var encrypted_files_1 = require("./mysky/encrypted_files");
Object.defineProperty(exports, "deriveEncryptedFileKeyEntropy", { enumerable: true, get: function () { return encrypted_files_1.deriveEncryptedFileKeyEntropy; } });
Object.defineProperty(exports, "deriveEncryptedFileSeed", { enumerable: true, get: function () { return encrypted_files_1.deriveEncryptedFileSeed; } });
Object.defineProperty(exports, "deriveEncryptedFileTweak", { enumerable: true, get: function () { return encrypted_files_1.deriveEncryptedFileTweak; } });
Object.defineProperty(exports, "ENCRYPTION_PATH_SEED_LENGTH", { enumerable: true, get: function () { return encrypted_files_1.ENCRYPTION_PATH_SEED_LENGTH; } });
var tweak_1 = require("./mysky/tweak");
Object.defineProperty(exports, "deriveDiscoverableFileTweak", { enumerable: true, get: function () { return tweak_1.deriveDiscoverableFileTweak; } });
var format_1 = require("./skylink/format");

@@ -22,0 +31,0 @@ Object.defineProperty(exports, "convertSkylinkToBase32", { enumerable: true, get: function () { return format_1.convertSkylinkToBase32; } });

@@ -5,3 +5,2 @@ export type { CustomConnectorOptions } from "./connector";

import { Permission } from "skynet-mysky-utils";
import type { CustomUserIDOptions } from "skynet-mysky-utils";
import { Connector, CustomConnectorOptions } from "./connector";

@@ -13,2 +12,3 @@ import { SkynetClient } from "../client";

import { Signature } from "../crypto";
import { EncryptedJSONResponse } from "./encrypted_files";
export declare const mySkyDomain = "skynet-mysky.hns";

@@ -61,5 +61,6 @@ export declare const mySkyDevDomain = "skynet-mysky-dev.hns";

requestLoginAccess(): Promise<boolean>;
userID(opts?: CustomUserIDOptions): Promise<string>;
userID(): Promise<string>;
/**
* Gets Discoverable JSON at the given path through MySky, if the user has given Read permissions to do so.
* Gets Discoverable JSON at the given path through MySky, if the user has
* given Discoverable Read permissions to do so.
*

@@ -69,2 +70,3 @@ * @param path - The data path.

* @returns - An object containing the json data as well as the skylink for the data.
* @throws - Will throw if the user does not have Discoverable Read permission on the path.
*/

@@ -81,3 +83,4 @@ getJSON(path: string, customOptions?: CustomGetJSONOptions): Promise<JSONResponse>;

/**
* Sets Discoverable JSON at the given path through MySky, if the user has given Write permissions to do so.
* Sets Discoverable JSON at the given path through MySky, if the user has
* given Discoverable Write permissions to do so.
*

@@ -88,2 +91,3 @@ * @param path - The data path.

* @returns - An object containing the json data as well as the skylink for the data.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/

@@ -98,6 +102,8 @@ setJSON(path: string, json: JsonData, customOptions?: CustomSetJSONOptions): Promise<JSONResponse>;

* @returns - An empty promise.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/
setDataLink(path: string, dataLink: string, customOptions?: CustomSetJSONOptions): Promise<void>;
/**
* Deletes Discoverable JSON at the given path through MySky, if the user has given Write permissions to do so.
* Deletes Discoverable JSON at the given path through MySky, if the user has
* given Discoverable Write permissions to do so.
*

@@ -108,6 +114,8 @@ * @param path - The data path.

* @throws - Will throw if the revision is already the maximum value.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/
deleteJSON(path: string, customOptions?: CustomSetJSONOptions): Promise<void>;
/**
* Gets the raw registry entry data for the given path, if the user has given READ permissions.
* Gets the raw registry entry data for the given path, if the user has given
* Discoverable Read permissions.
*

@@ -117,6 +125,8 @@ * @param path - The data path.

* @returns - The entry data.
* @throws - Will throw if the user does not have Discoverable Read permission on the path.
*/
getEntryData(path: string, customOptions?: CustomGetEntryOptions): Promise<EntryData>;
/**
* Sets the entry data at the given path, if the user has given WRITE permissions.
* Sets the entry data at the given path, if the user has given Discoverable
* Write permissions.
*

@@ -128,4 +138,36 @@ * @param path - The data path.

* @throws - Will throw if the length of the data is > 70 bytes.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/
setEntryData(path: string, data: Uint8Array, customOptions?: CustomSetJSONOptions): Promise<EntryData>;
/**
* Lets you get the share-able path seed, which can be passed to
* file.getJSONEncrypted. Requires Hidden Read permission on the path.
*
* @param path - The given path.
* @param isDirectory - Whether the path is a directory.
* @returns - The seed for the path.
* @throws - Will throw if the user does not have Hidden Read permission on the path.
*/
getEncryptedFileSeed(path: string, isDirectory: boolean): Promise<string>;
/**
* Gets Encrypted JSON at the given path through MySky, if the user has given
* Hidden Read permissions to do so.
*
* @param path - The data path.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - An object containing the decrypted json data.
* @throws - Will throw if the user does not have Hidden Read permission on the path.
*/
getJSONEncrypted(path: string, customOptions?: CustomGetJSONOptions): Promise<EncryptedJSONResponse>;
/**
* Sets Encrypted JSON at the given path through MySky, if the user has given
* Hidden Write permissions to do so.
*
* @param path - The data path.
* @param json - The json to encrypt and set.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - An object containing the original json data.
* @throws - Will throw if the user does not have Hidden Write permission on the path.
*/
setJSONEncrypted(path: string, json: JsonData, customOptions?: CustomSetJSONOptions): Promise<EncryptedJSONResponse>;
protected catchError(errorMsg: string): Promise<void>;

@@ -137,3 +179,4 @@ protected launchUI(): Promise<Window>;

protected signRegistryEntry(entry: RegistryEntry, path: string): Promise<Signature>;
protected signEncryptedRegistryEntry(entry: RegistryEntry, path: string): Promise<Signature>;
}
//# sourceMappingURL=index.d.ts.map

@@ -17,2 +17,3 @@ "use strict";

const sia_1 = require("../skylink/sia");
const encrypted_files_1 = require("./encrypted_files");
exports.mySkyDomain = "skynet-mysky.hns";

@@ -193,7 +194,8 @@ exports.mySkyDevDomain = "skynet-mysky-dev.hns";

}
async userID(opts) {
return await this.connector.connection.remoteHandle().call("userID", opts);
async userID() {
return await this.connector.connection.remoteHandle().call("userID");
}
/**
* Gets Discoverable JSON at the given path through MySky, if the user has given Read permissions to do so.
* Gets Discoverable JSON at the given path through MySky, if the user has
* given Discoverable Read permissions to do so.
*

@@ -203,2 +205,3 @@ * @param path - The data path.

* @returns - An object containing the json data as well as the skylink for the data.
* @throws - Will throw if the user does not have Discoverable Read permission on the path.
*/

@@ -214,3 +217,3 @@ async getJSON(path, customOptions) {

const publicKey = await this.userID();
const dataKey = tweak_1.deriveDiscoverableTweak(path);
const dataKey = tweak_1.deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -229,3 +232,3 @@ return await this.connector.client.db.getJSON(publicKey, dataKey, opts);

const publicKey = await this.userID();
const dataKey = tweak_1.deriveDiscoverableTweak(path);
const dataKey = tweak_1.deriveDiscoverableFileTweak(path);
// Do not hash the tweak anymore.

@@ -236,3 +239,4 @@ const opts = { ...registry_1.defaultGetEntryOptions, hashedDataKeyHex: true };

/**
* Sets Discoverable JSON at the given path through MySky, if the user has given Write permissions to do so.
* Sets Discoverable JSON at the given path through MySky, if the user has
* given Discoverable Write permissions to do so.
*

@@ -243,2 +247,3 @@ * @param path - The data path.

* @returns - An object containing the json data as well as the skylink for the data.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/

@@ -255,3 +260,3 @@ async setJSON(path, json, customOptions) {

const publicKey = await this.userID();
const dataKey = tweak_1.deriveDiscoverableTweak(path);
const dataKey = tweak_1.deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -271,2 +276,3 @@ const [entry, dataLink] = await skydb_1.getOrCreateRegistryEntry(this.connector.client, publicKey, dataKey, json, opts);

* @returns - An empty promise.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/

@@ -283,3 +289,3 @@ async setDataLink(path, dataLink, customOptions) {

const publicKey = await this.userID();
const dataKey = tweak_1.deriveDiscoverableTweak(path);
const dataKey = tweak_1.deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -293,3 +299,4 @@ const getEntryOpts = options_1.extractOptions(opts, registry_1.defaultGetEntryOptions);

/**
* Deletes Discoverable JSON at the given path through MySky, if the user has given Write permissions to do so.
* Deletes Discoverable JSON at the given path through MySky, if the user has
* given Discoverable Write permissions to do so.
*

@@ -300,2 +307,3 @@ * @param path - The data path.

* @throws - Will throw if the revision is already the maximum value.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/

@@ -311,3 +319,3 @@ async deleteJSON(path, customOptions) {

const publicKey = await this.userID();
const dataKey = tweak_1.deriveDiscoverableTweak(path);
const dataKey = tweak_1.deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -321,3 +329,4 @@ const getEntryOpts = options_1.extractOptions(opts, registry_1.defaultGetEntryOptions);

/**
* Gets the raw registry entry data for the given path, if the user has given READ permissions.
* Gets the raw registry entry data for the given path, if the user has given
* Discoverable Read permissions.
*

@@ -327,2 +336,3 @@ * @param path - The data path.

* @returns - The entry data.
* @throws - Will throw if the user does not have Discoverable Read permission on the path.
*/

@@ -338,3 +348,3 @@ async getEntryData(path, customOptions) {

const publicKey = await this.userID();
const dataKey = tweak_1.deriveDiscoverableTweak(path);
const dataKey = tweak_1.deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -348,3 +358,4 @@ const { entry } = await this.connector.client.registry.getEntry(publicKey, dataKey, opts);

/**
* Sets the entry data at the given path, if the user has given WRITE permissions.
* Sets the entry data at the given path, if the user has given Discoverable
* Write permissions.
*

@@ -356,2 +367,3 @@ * @param path - The data path.

* @throws - Will throw if the length of the data is > 70 bytes.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/

@@ -361,3 +373,3 @@ async setEntryData(path, data, customOptions) {

validation_1.validateUint8Array("data", data, "parameter");
validation_1.validateOptionalObject("customOptions", customOptions, "parameter", registry_1.defaultGetEntryOptions);
validation_1.validateOptionalObject("customOptions", customOptions, "parameter", registry_1.defaultSetEntryOptions);
if (data.length > exports.MAX_ENTRY_LENGTH) {

@@ -372,3 +384,3 @@ validation_1.throwValidationError("data", data, "parameter", `'Uint8Array' of length <= ${exports.MAX_ENTRY_LENGTH}, was length ${data.length}`);

const publicKey = await this.userID();
const dataKey = tweak_1.deriveDiscoverableTweak(path);
const dataKey = tweak_1.deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -382,2 +394,82 @@ const getEntryOpts = options_1.extractOptions(opts, registry_1.defaultGetEntryOptions);

}
// ===============
// Encrypted Files
// ===============
/**
* Lets you get the share-able path seed, which can be passed to
* file.getJSONEncrypted. Requires Hidden Read permission on the path.
*
* @param path - The given path.
* @param isDirectory - Whether the path is a directory.
* @returns - The seed for the path.
* @throws - Will throw if the user does not have Hidden Read permission on the path.
*/
async getEncryptedFileSeed(path, isDirectory) {
validation_1.validateString("path", path, "parameter");
validation_1.validateBoolean("isDirectory", isDirectory, "parameter");
return await this.connector.connection.remoteHandle().call("getEncryptedFileSeed", path, isDirectory);
}
/**
* Gets Encrypted JSON at the given path through MySky, if the user has given
* Hidden Read permissions to do so.
*
* @param path - The data path.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - An object containing the decrypted json data.
* @throws - Will throw if the user does not have Hidden Read permission on the path.
*/
async getJSONEncrypted(path, customOptions) {
validation_1.validateString("path", path, "parameter");
validation_1.validateOptionalObject("customOptions", customOptions, "parameter", skydb_1.defaultGetJSONOptions);
const opts = {
...skydb_1.defaultGetJSONOptions,
...this.connector.client.customOptions,
...customOptions,
hashedDataKeyHex: true, // Do not hash the tweak anymore.
};
// Call MySky which checks for read permissions on the path.
const [publicKey, pathSeed] = await Promise.all([this.userID(), this.getEncryptedFileSeed(path, false)]);
// Fetch the raw encrypted JSON data.
const dataKey = encrypted_files_1.deriveEncryptedFileTweak(pathSeed);
const { data } = await this.connector.client.db.getRawBytes(publicKey, dataKey, opts);
if (data === null) {
return { data: null };
}
const encryptionKey = encrypted_files_1.deriveEncryptedFileKeyEntropy(pathSeed);
const json = encrypted_files_1.decryptJSONFile(data, encryptionKey);
return { data: json };
}
/**
* Sets Encrypted JSON at the given path through MySky, if the user has given
* Hidden Write permissions to do so.
*
* @param path - The data path.
* @param json - The json to encrypt and set.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - An object containing the original json data.
* @throws - Will throw if the user does not have Hidden Write permission on the path.
*/
async setJSONEncrypted(path, json, customOptions) {
validation_1.validateString("path", path, "parameter");
validation_1.validateObject("json", json, "parameter");
validation_1.validateOptionalObject("customOptions", customOptions, "parameter", skydb_1.defaultSetJSONOptions);
const opts = {
...skydb_1.defaultSetJSONOptions,
...this.connector.client.customOptions,
...customOptions,
};
// Call MySky which checks for read permissions on the path.
const [publicKey, pathSeed] = await Promise.all([this.userID(), this.getEncryptedFileSeed(path, false)]);
const dataKey = encrypted_files_1.deriveEncryptedFileTweak(pathSeed);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.
const encryptionKey = encrypted_files_1.deriveEncryptedFileKeyEntropy(pathSeed);
// Pad and encrypt json file.
const data = encrypted_files_1.encryptJSONFile(json, { version: encrypted_files_1.ENCRYPTED_JSON_RESPONSE_VERSION }, encryptionKey);
const entry = await skydb_1.getOrCreateRawBytesRegistryEntry(this.connector.client, publicKey, dataKey, data, opts);
// Call MySky which checks for write permissions on the path.
const signature = await this.signEncryptedRegistryEntry(entry, path);
const setEntryOpts = options_1.extractOptions(opts, registry_1.defaultSetEntryOptions);
await this.connector.client.registry.postSignedEntry(publicKey, entry, signature, setEntryOpts);
return { data: json };
}
// ================

@@ -432,4 +524,7 @@ // Internal Methods

}
async signEncryptedRegistryEntry(entry, path) {
return await this.connector.connection.remoteHandle().call("signEncryptedRegistryEntry", entry, path);
}
}
exports.MySky = MySky;
MySky.instance = null;

@@ -0,1 +1,8 @@

/**
* Derives the discoverable file tweak for the given path.
*
* @param path - The given path.
* @returns - The hex-encoded tweak.
*/
export declare function deriveDiscoverableFileTweak(path: string): string;
export declare class DiscoverableBucketTweak {

@@ -22,9 +29,2 @@ version: number;

export declare function hashPathComponent(component: string): Uint8Array;
/**
* Derives the discoverable file tweak for the given path.
*
* @param path - The given path.
* @returns - The hex-encoded tweak.
*/
export declare function deriveDiscoverableTweak(path: string): string;
//# sourceMappingURL=tweak.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deriveDiscoverableTweak = exports.hashPathComponent = exports.splitPath = exports.DiscoverableBucketTweak = void 0;
exports.hashPathComponent = exports.splitPath = exports.DiscoverableBucketTweak = exports.deriveDiscoverableFileTweak = void 0;
const crypto_1 = require("../crypto");
const string_1 = require("../utils/string");
const discoverableBucketTweakVersion = 1;
/**
* Derives the discoverable file tweak for the given path.
*
* @param path - The given path.
* @returns - The hex-encoded tweak.
*/
function deriveDiscoverableFileTweak(path) {
const dbt = new DiscoverableBucketTweak(path);
const bytes = dbt.getHash();
return string_1.toHexString(bytes);
}
exports.deriveDiscoverableFileTweak = deriveDiscoverableFileTweak;
class DiscoverableBucketTweak {

@@ -47,2 +59,3 @@ constructor(path) {

*/
// TODO: Can we replace with hashString?
function hashPathComponent(component) {

@@ -52,13 +65,1 @@ return crypto_1.hashAll(string_1.stringToUint8ArrayUtf8(component));

exports.hashPathComponent = hashPathComponent;
/**
* Derives the discoverable file tweak for the given path.
*
* @param path - The given path.
* @returns - The hex-encoded tweak.
*/
function deriveDiscoverableTweak(path) {
const dbt = new DiscoverableBucketTweak(path);
const bytes = dbt.getHash();
return string_1.toHexString(bytes);
}
exports.deriveDiscoverableTweak = deriveDiscoverableTweak;

@@ -6,2 +6,6 @@ import { SkynetClient } from "./client";

export declare type JsonData = Record<string, unknown>;
export declare type JsonFullData = {
_data: JsonData;
_v: number;
};
/**

@@ -21,2 +25,3 @@ * Custom get JSON options.

range: undefined;
responseType: undefined;
query: undefined;

@@ -38,3 +43,12 @@ subdomain: boolean;

endpointLargeUpload: string;
customFilename: string;
customFilename: string; /**
* Gets the JSON object corresponding to the publicKey and dataKey.
*
* @param this - SkynetClient
* @param publicKey - The user public key.
* @param dataKey - The key of the data to fetch for the given user.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - The returned JSON and corresponding data link.
* @throws - Will throw if the returned signature does not match the returned entry, or if the skylink in the entry is invalid.
*/
largeFileSize: number;

@@ -53,2 +67,3 @@ retryDelays: number[];

range: undefined;
responseType: undefined;
query: undefined;

@@ -62,2 +77,6 @@ subdomain: boolean;

};
export declare type RawBytesResponse = {
data: Uint8Array | null;
dataLink: string | null;
};
/**

@@ -101,9 +120,32 @@ * Gets the JSON object corresponding to the publicKey and dataKey.

* @param privateKey - The user private key.
* @param dataKey - The key of the data to fetch for the given user.
* @param dataKey - The data key.
* @param dataLink - The data link to set at the entry.
* @param [customOptions] - Additional settings that can optionally be set.
* @throws - Will throw if the input keys are not valid strings
* @throws - Will throw if the input keys are not valid strings.
*/
export declare function setDataLink(this: SkynetClient, privateKey: string, dataKey: string, dataLink: string, customOptions?: CustomSetJSONOptions): Promise<void>;
/**
* Gets the raw bytes corresponding to the publicKey and dataKey. The caller is responsible for setting any metadata in the bytes.
*
* @param this - SkynetClient
* @param publicKey - The user public key.
* @param dataKey - The key of the data to fetch for the given user.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - The returned bytes.
* @throws - Will throw if the returned signature does not match the returned entry, or if the skylink in the entry is invalid.
*/
export declare function getRawBytes(this: SkynetClient, publicKey: string, dataKey: string, customOptions?: CustomGetJSONOptions): Promise<RawBytesResponse>;
/**
* Gets the registry entry for the given raw bytes or creates the entry if it doesn't exist.
*
* @param client - The Skynet client.
* @param publicKey - The user public key.
* @param dataKey - The dat akey.
* @param data - The raw byte data to set.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - The registry entry and corresponding data link.
* @throws - Will throw if the revision is already the maximum value.
*/
export declare function getOrCreateRawBytesRegistryEntry(client: SkynetClient, publicKey: string, dataKey: string, data: Uint8Array, customOptions?: CustomSetJSONOptions): Promise<RegistryEntry>;
/**
* Gets the next entry for the given public key and data key, setting the data to be the given data and the revision number accordingly.

@@ -140,2 +182,11 @@ *

export declare function getNextRevisionFromEntry(entry: RegistryEntry | null): bigint;
/**
* Checks whether the raw data link matches the cached data link, if provided.
*
* @param rawDataLink - The raw, unformatted data link.
* @param cachedDataLink - The cached data link, if provided.
* @returns - Whether the cached data link is a match.
* @throws - Will throw if the given cached data link is not a valid skylink.
*/
export declare function checkCachedDataLink(rawDataLink: string, cachedDataLink?: string): boolean;
//# sourceMappingURL=skydb.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getNextRevisionFromEntry = exports.getOrCreateRegistryEntry = exports.getNextRegistryEntry = exports.setDataLink = exports.deleteJSON = exports.setJSON = exports.getJSON = exports.defaultSetJSONOptions = exports.defaultGetJSONOptions = void 0;
exports.checkCachedDataLink = exports.getNextRevisionFromEntry = exports.getOrCreateRegistryEntry = exports.getNextRegistryEntry = exports.getOrCreateRawBytesRegistryEntry = exports.getRawBytes = exports.setDataLink = exports.deleteJSON = exports.setJSON = exports.getJSON = exports.defaultSetJSONOptions = exports.defaultGetJSONOptions = void 0;
const tweetnacl_1 = require("tweetnacl");

@@ -30,2 +30,5 @@ const download_1 = require("./download");

};
// ====
// JSON
// ====
/**

@@ -50,29 +53,12 @@ * Gets the JSON object corresponding to the publicKey and dataKey.

// Lookup the registry entry.
const getEntryOpts = options_1.extractOptions(opts, registry_1.defaultGetEntryOptions);
const { entry } = await this.registry.getEntry(publicKey, dataKey, getEntryOpts);
if (entry === null || array_1.areEqualUint8Arrays(entry.data, sia_1.EMPTY_SKYLINK)) {
const entry = await getSkyDBRegistryEntry(this, publicKey, dataKey, opts);
if (entry === null) {
return { data: null, dataLink: null };
}
validation_1.validateUint8Array("entry.data", entry.data, "returned entry data");
// Determine the data link.
// TODO: Can this still be an entry link which hasn't yet resolved to a data link?
let rawDataLink = "";
if (entry.data.length === sia_1.BASE64_ENCODED_SKYLINK_SIZE) {
// Legacy data, convert to string.
rawDataLink = string_1.uint8ArrayToStringUtf8(entry.data);
}
else if (entry.data.length === sia_1.RAW_SKYLINK_SIZE) {
// Convert the bytes to a base64 skylink.
rawDataLink = encoding_1.encodeSkylinkBase64(entry.data);
}
else {
validation_1.throwValidationError("entry.data", entry.data, "returned entry data", `length ${sia_1.RAW_SKYLINK_SIZE} bytes`);
}
const dataLink = format_1.formatSkylink(rawDataLink);
const { rawDataLink, dataLink } = parseDataLink(entry.data, true);
// If a cached data link is provided and the data link hasn't changed, return.
if (opts.cachedDataLink) {
const cachedDataLink = validation_1.validateSkylinkString("opts.cachedDataLink", opts.cachedDataLink, "optional parameter");
if (rawDataLink === cachedDataLink) {
return { data: null, dataLink };
}
if (checkCachedDataLink(rawDataLink, opts.cachedDataLink)) {
return { data: null, dataLink };
}

@@ -86,3 +72,3 @@ // Download the data in the returned data link.

if (!(data["_data"] && data["_v"])) {
// Legacy data prior to v4, return as-is.
// Legacy data prior to skynet-js v4, return as-is.
return { data, dataLink };

@@ -157,6 +143,6 @@ }

* @param privateKey - The user private key.
* @param dataKey - The key of the data to fetch for the given user.
* @param dataKey - The data key.
* @param dataLink - The data link to set at the entry.
* @param [customOptions] - Additional settings that can optionally be set.
* @throws - Will throw if the input keys are not valid strings
* @throws - Will throw if the input keys are not valid strings.
*/

@@ -181,3 +167,100 @@ async function setDataLink(privateKey, dataKey, dataLink, customOptions) {

exports.setDataLink = setDataLink;
// =========
// Raw Bytes
// =========
/**
* Gets the raw bytes corresponding to the publicKey and dataKey. The caller is responsible for setting any metadata in the bytes.
*
* @param this - SkynetClient
* @param publicKey - The user public key.
* @param dataKey - The key of the data to fetch for the given user.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - The returned bytes.
* @throws - Will throw if the returned signature does not match the returned entry, or if the skylink in the entry is invalid.
*/
// TODO: Should we expose this in the API?
async function getRawBytes(publicKey, dataKey,
// TODO: Take a new options type?
customOptions) {
validation_1.validateOptionalObject("customOptions", customOptions, "parameter", exports.defaultGetJSONOptions);
// Rest of validation is done in `getEntry`.
const opts = {
...exports.defaultGetJSONOptions,
...this.customOptions,
...customOptions,
};
// Lookup the registry entry.
const entry = await getSkyDBRegistryEntry(this, publicKey, dataKey, opts);
if (entry === null) {
return { data: null, dataLink: null };
}
// Determine the data link.
// TODO: Can this still be an entry link which hasn't yet resolved to a data link?
const { rawDataLink, dataLink } = parseDataLink(entry.data, false);
// If a cached data link is provided and the data link hasn't changed, return.
if (checkCachedDataLink(rawDataLink, opts.cachedDataLink)) {
return { data: null, dataLink };
}
// Download the data in the returned data link.
const downloadOpts = { ...options_1.extractOptions(opts, download_1.defaultDownloadOptions), responseType: "arraybuffer" };
const { data: buffer } = await this.getFileContent(dataLink, downloadOpts);
return { data: new Uint8Array(buffer), dataLink };
}
exports.getRawBytes = getRawBytes;
/* istanbul ignore next */
/**
* Gets the registry entry for the given raw bytes or creates the entry if it doesn't exist.
*
* @param client - The Skynet client.
* @param publicKey - The user public key.
* @param dataKey - The dat akey.
* @param data - The raw byte data to set.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - The registry entry and corresponding data link.
* @throws - Will throw if the revision is already the maximum value.
*/
// TODO: Rename & refactor after the SkyDB caching refactor.
async function getOrCreateRawBytesRegistryEntry(client, publicKey, dataKey, data, customOptions) {
// Not publicly available, don't validate input.
const opts = {
...exports.defaultSetJSONOptions,
...client.customOptions,
...customOptions,
};
// Create the data to upload to acquire its skylink.
let dataKeyHex = dataKey;
if (!opts.hashedDataKeyHex) {
dataKeyHex = string_1.toHexString(string_1.stringToUint8ArrayUtf8(dataKey));
}
const file = new File([data], `dk:${dataKeyHex}`, { type: "application/octet-stream" });
// Start file upload, do not block.
const uploadOpts = options_1.extractOptions(opts, upload_1.defaultUploadOptions);
const skyfilePromise = client.uploadFile(file, uploadOpts);
// Fetch the current value to find out the revision.
//
// Start getEntry, do not block.
const getEntryOpts = options_1.extractOptions(opts, registry_1.defaultGetEntryOptions);
const entryPromise = client.registry.getEntry(publicKey, dataKey, getEntryOpts);
// Block until both getEntry and uploadFile are finished.
const [signedEntry, skyfile] = await Promise.all([
entryPromise,
skyfilePromise,
]);
const revision = getNextRevisionFromEntry(signedEntry.entry);
// Build the registry entry.
const dataLink = string_1.trimUriPrefix(skyfile.skylink, url_1.uriSkynetPrefix);
const rawDataLink = encoding_1.decodeSkylinkBase64(dataLink);
validation_1.validateUint8ArrayLen("rawDataLink", rawDataLink, "skylink byte array", sia_1.RAW_SKYLINK_SIZE);
const entry = {
dataKey,
data: rawDataLink,
revision,
};
return entry;
}
exports.getOrCreateRawBytesRegistryEntry = getOrCreateRawBytesRegistryEntry;
// =======
// Helpers
// =======
/**
* Gets the next entry for the given public key and data key, setting the data to be the given data and the revision number accordingly.

@@ -287,1 +370,57 @@ *

exports.getNextRevisionFromEntry = getNextRevisionFromEntry;
/**
* Checks whether the raw data link matches the cached data link, if provided.
*
* @param rawDataLink - The raw, unformatted data link.
* @param cachedDataLink - The cached data link, if provided.
* @returns - Whether the cached data link is a match.
* @throws - Will throw if the given cached data link is not a valid skylink.
*/
function checkCachedDataLink(rawDataLink, cachedDataLink) {
if (cachedDataLink) {
cachedDataLink = validation_1.validateSkylinkString("cachedDataLink", cachedDataLink, "optional parameter");
return rawDataLink === cachedDataLink;
}
return false;
}
exports.checkCachedDataLink = checkCachedDataLink;
/**
* Gets the registry entry, returning null if the entry contains an empty skylink (the deletion sentinel).
*
* @param client - The Skynet Client
* @param publicKey - The user public key.
* @param dataKey - The key of the data to fetch for the given user.
* @param opts - Additional settings.
* @returns - The registry entry, or null if not found or deleted.
*/
async function getSkyDBRegistryEntry(client, publicKey, dataKey, opts) {
const getEntryOpts = options_1.extractOptions(opts, registry_1.defaultGetEntryOptions);
const { entry } = await client.registry.getEntry(publicKey, dataKey, getEntryOpts);
if (entry === null || array_1.areEqualUint8Arrays(entry.data, sia_1.EMPTY_SKYLINK)) {
return null;
}
return entry;
}
/**
* Parses a data link out of the given registry entry data.
*
* @param data - The raw registry entry data.
* @param legacy - Whether to check for possible legacy skylink data, encoded as base64.
* @returns - The raw, unformatted data link and the formatted data link.
* @throws - Will throw if the data is not of the expected length for a skylink.
*/
function parseDataLink(data, legacy) {
let rawDataLink = "";
if (legacy && data.length === sia_1.BASE64_ENCODED_SKYLINK_SIZE) {
// Legacy data, convert to string for backwards compatibility.
rawDataLink = string_1.uint8ArrayToStringUtf8(data);
}
else if (data.length === sia_1.RAW_SKYLINK_SIZE) {
// Convert the bytes to a base64 skylink.
rawDataLink = encoding_1.encodeSkylinkBase64(data);
}
else {
validation_1.throwValidationError("entry.data", data, "returned entry data", `length ${sia_1.RAW_SKYLINK_SIZE} bytes`);
}
return { rawDataLink, dataLink: format_1.formatSkylink(rawDataLink) };
}

@@ -57,6 +57,3 @@ "use strict";

static fromBytes(data) {
// Sanity check the size of the given data.
if (data.length !== exports.RAW_SKYLINK_SIZE) {
throw new Error("Failed to load skylink data");
}
validation_1.validateUint8ArrayLen("data", data, "parameter", exports.RAW_SKYLINK_SIZE);
const view = new DataView(data.buffer);

@@ -63,0 +60,0 @@ // Load the bitfield.

@@ -172,3 +172,6 @@ "use strict";

onError: (error) => {
reject(error);
// @ts-expect-error tus-client-js Error is not typed correctly.
const res = error.originalResponse;
const message = res ? res.getBody() || error : error;
reject(new Error(message.trim()));
},

@@ -175,0 +178,0 @@ onSuccess: async () => {

@@ -11,2 +11,11 @@ /**

/**
* Validates the given value as a boolean.
*
* @param name - The name of the value.
* @param value - The actual value.
* @param valueKind - The kind of value that is being checked (e.g. "parameter", "response field", etc.)
* @throws - Will throw if not a valid boolean.
*/
export declare function validateBoolean(name: string, value: unknown, valueKind: string): void;
/**
* Validates the given value as an object.

@@ -13,0 +22,0 @@ *

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.throwValidationError = exports.validateUint8ArrayLen = exports.validateUint8Array = exports.validateHexString = exports.validateStringLen = exports.validateString = exports.validateSkylinkString = exports.validateNumber = exports.validateOptionalObject = exports.validateObject = exports.validateBigint = void 0;
exports.throwValidationError = exports.validateUint8ArrayLen = exports.validateUint8Array = exports.validateHexString = exports.validateStringLen = exports.validateString = exports.validateSkylinkString = exports.validateNumber = exports.validateOptionalObject = exports.validateObject = exports.validateBoolean = exports.validateBigint = void 0;
const parse_1 = require("../skylink/parse");

@@ -21,2 +21,16 @@ const string_1 = require("./string");

/**
* Validates the given value as a boolean.
*
* @param name - The name of the value.
* @param value - The actual value.
* @param valueKind - The kind of value that is being checked (e.g. "parameter", "response field", etc.)
* @throws - Will throw if not a valid boolean.
*/
function validateBoolean(name, value, valueKind) {
if (typeof value !== "boolean") {
throwValidationError(name, value, valueKind, "type 'boolean'");
}
}
exports.validateBoolean = validateBoolean;
/**
* Validates the given value as an object.

@@ -23,0 +37,0 @@ *

@@ -1,2 +0,2 @@

import { AxiosResponse } from "axios";
import { AxiosResponse, ResponseType } from "axios";
import type { Method } from "axios";

@@ -32,2 +32,3 @@ import { uploadFile, uploadLargeFile, uploadDirectory, uploadDirectoryRequest, uploadSmallFile, uploadSmallFileRequest, uploadLargeFileRequest } from "./upload";

* @property [headers] - Any request headers to set.
* @property [responseType] - The response type.
* @property [transformRequest] - A function that allows manually transforming the request.

@@ -44,2 +45,3 @@ * @property [transformResponse] - A function that allows manually transforming the response.

extraPath?: string;
responseType?: ResponseType;
transformRequest?: (data: unknown) => string;

@@ -83,2 +85,3 @@ transformResponse?: (data: string) => Record<string, unknown>;

getEntryLink: (userID: string, path: string) => Promise<string>;
getJSONEncrypted: (userID: string, pathSeed: string, customOptions?: import("./skydb").CustomGetJSONOptions | undefined) => Promise<import("./mysky/encrypted_files").EncryptedJSONResponse>;
};

@@ -90,2 +93,3 @@ db: {

setDataLink: (privateKey: string, dataKey: string, dataLink: string, customOptions?: import("./skydb").CustomSetJSONOptions | undefined) => Promise<void>;
getRawBytes: (publicKey: string, dataKey: string, customOptions?: import("./skydb").CustomGetJSONOptions | undefined) => Promise<import("./skydb").RawBytesResponse>;
};

@@ -92,0 +96,0 @@ registry: {

import axios from "axios";
import { uploadFile, uploadLargeFile, uploadDirectory, uploadDirectoryRequest, uploadSmallFile, uploadSmallFileRequest, uploadLargeFileRequest, } from "./upload";
import { downloadFile, downloadFileHns, getSkylinkUrl, getHnsUrl, getHnsresUrl, getMetadata, getFileContent, getFileContentHns, getFileContentRequest, openFile, openFileHns, resolveHns, } from "./download";
import { getEntryData, getEntryLink as fileGetEntryLink, getJSON as fileGetJSON } from "./file";
import { getJSONEncrypted, getEntryData, getEntryLink as fileGetEntryLink, getJSON as fileGetJSON } from "./file";
import { pinSkylink } from "./pin";
import { getEntry, getEntryUrl, getEntryLink, setEntry, postSignedEntry } from "./registry";
import { deleteJSON, getJSON, setJSON, setDataLink } from "./skydb";
import { deleteJSON, getJSON, setJSON, setDataLink, getRawBytes } from "./skydb";
import { addUrlQuery, defaultPortalUrl, makeUrl } from "./utils/url";

@@ -57,2 +57,3 @@ import { loadMySky } from "./mysky";

getEntryLink: fileGetEntryLink.bind(this),
getJSONEncrypted: getJSONEncrypted.bind(this),
};

@@ -65,2 +66,3 @@ // SkyDB

setDataLink: setDataLink.bind(this),
getRawBytes: getRawBytes.bind(this),
};

@@ -159,2 +161,3 @@ // SkyDB helpers

onUploadProgress,
responseType: config.responseType,
transformRequest: config.transformRequest,

@@ -161,0 +164,0 @@ transformResponse: config.transformResponse,

@@ -22,2 +22,3 @@ /// <reference types="node" />

};
export declare const HASH_LENGTH = 32;
/**

@@ -69,2 +70,9 @@ * Derives a child seed from the given master seed and sub seed.

export declare function hashRegistryEntry(registryEntry: RegistryEntry, hashedDataKeyHex: boolean): Uint8Array;
/**
* Hashes the given string or byte array using sha512.
*
* @param message - The string or byte array to hash.
* @returns - The resulting hash.
*/
export declare function sha512(message: Uint8Array | string): Uint8Array;
//# sourceMappingURL=crypto.d.ts.map
import { misc, codec } from "sjcl";
import { blake2bFinal, blake2bInit, blake2bUpdate } from "blakejs";
import randomBytes from "randombytes";
import { sign } from "tweetnacl";
import { hexToUint8Array, toHexString } from "./utils/string";
import { hash, sign } from "tweetnacl";
import { hexToUint8Array, stringToUint8ArrayUtf8, toHexString } from "./utils/string";
import { validateNumber, validateString } from "./utils/validation";
import { encodeBigintAsUint64, encodePrefixedBytes, encodeUtf8String } from "./utils/encoding";
export const HASH_LENGTH = 32;
/**

@@ -63,7 +64,6 @@ * Returns a blake2b 256bit hasher. See `NewHash` in Sia.

const hasher = newHash();
for (let i = 0; i < args.length; i++) {
blake2bUpdate(hasher, args[i]);
}
args.forEach((arg) => blake2bUpdate(hasher, arg));
return blake2bFinal(hasher);
}
// TODO: Is this the same as hashString?
/**

@@ -97,2 +97,16 @@ * Hash the given data key.

/**
* Hashes the given string or byte array using sha512.
*
* @param message - The string or byte array to hash.
* @returns - The resulting hash.
*/
export function sha512(message) {
if (typeof message === "string") {
return hash(stringToUint8ArrayUtf8(message));
}
else {
return hash(message);
}
}
/**
* Generates a random seed of the given length in bytes.

@@ -99,0 +113,0 @@ *

@@ -0,1 +1,2 @@

import { ResponseType } from "axios";
import { SkynetClient } from "./client";

@@ -11,2 +12,3 @@ import { JsonData } from "./skydb";

* @property [range] - The Range request header to set for the download. Not applicable for in-borwser downloads.
* @property [responseType] - The response type.
* @property [query] - A query object to convert to a query parameter string and append to the URL.

@@ -20,2 +22,3 @@ * @property [subdomain=false] - Whether to return the final skylink in subdomain format.

range?: string;
responseType?: ResponseType;
subdomain?: boolean;

@@ -80,2 +83,3 @@ };

range: undefined;
responseType: undefined;
query: undefined;

@@ -82,0 +86,0 @@ subdomain: boolean;

@@ -13,2 +13,3 @@ import { convertSkylinkToBase32, formatSkylink } from "./skylink/format";

range: undefined,
responseType: undefined,
query: undefined,

@@ -15,0 +16,0 @@ subdomain: false,

import { SkynetClient } from "./client";
import { EntryData } from "./mysky";
import { EncryptedJSONResponse } from "./mysky/encrypted_files";
import { CustomGetEntryOptions } from "./registry";

@@ -38,2 +39,13 @@ import { CustomGetJSONOptions, JSONResponse } from "./skydb";

export declare function getEntryData(this: SkynetClient, userID: string, path: string, customOptions?: CustomGetEntryOptions): Promise<EntryData>;
/**
* Gets Encrypted JSON set with MySky at the given data path for the given
* public user ID.
*
* @param this - SkynetClient
* @param userID - The MySky public user ID.
* @param pathSeed - The share-able secret path seed.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - An object containing the decrypted json data.
*/
export declare function getJSONEncrypted(this: SkynetClient, userID: string, pathSeed: string, customOptions?: CustomGetJSONOptions): Promise<EncryptedJSONResponse>;
//# sourceMappingURL=file.d.ts.map

@@ -1,5 +0,9 @@

import { deriveDiscoverableTweak } from "./mysky/tweak";
import { decryptJSONFile, deriveEncryptedFileKeyEntropy, deriveEncryptedFileTweak, } from "./mysky/encrypted_files";
import { deriveDiscoverableFileTweak } from "./mysky/tweak";
import { defaultGetEntryOptions } from "./registry";
import { defaultGetJSONOptions } from "./skydb";
import { validateOptionalObject, validateString } from "./utils/validation";
import { validateOptionalObject, validateString, validateStringLen } from "./utils/validation";
// ====
// JSON
// ====
/**

@@ -24,6 +28,9 @@ * Gets Discoverable JSON set with MySky at the given data path for the given

};
const dataKey = deriveDiscoverableTweak(path);
const dataKey = deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.
return await this.db.getJSON(userID, dataKey, opts);
}
// =====
// Entry
// =====
/**

@@ -42,3 +49,3 @@ * Gets the entry link for the entry set with MySky at the given data path, for

validateString("path", path, "parameter");
const dataKey = deriveDiscoverableTweak(path);
const dataKey = deriveDiscoverableFileTweak(path);
// Do not hash the tweak anymore.

@@ -67,3 +74,3 @@ const opts = { ...defaultGetEntryOptions, hashedDataKeyHex: true };

};
const dataKey = deriveDiscoverableTweak(path);
const dataKey = deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -76,1 +83,36 @@ const { entry } = await this.registry.getEntry(userID, dataKey, opts);

}
// ===============
// Encrypted Files
// ===============
/**
* Gets Encrypted JSON set with MySky at the given data path for the given
* public user ID.
*
* @param this - SkynetClient
* @param userID - The MySky public user ID.
* @param pathSeed - The share-able secret path seed.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - An object containing the decrypted json data.
*/
export async function getJSONEncrypted(userID, pathSeed,
// TODO: Take a new options type?
customOptions) {
validateString("userID", userID, "parameter");
validateStringLen("pathSeed", pathSeed, "parameter", 64);
validateOptionalObject("customOptions", customOptions, "parameter", defaultGetJSONOptions);
const opts = {
...defaultGetJSONOptions,
...this.customOptions,
...customOptions,
hashedDataKeyHex: true, // Do not hash the tweak anymore.
};
// Fetch the raw encrypted JSON data.
const dataKey = deriveEncryptedFileTweak(pathSeed);
const { data } = await this.db.getRawBytes(userID, dataKey, opts);
if (data === null) {
return { data: null };
}
const key = deriveEncryptedFileKeyEntropy(pathSeed);
const json = decryptJSONFile(data, key);
return { data: json };
}
export { SkynetClient } from "./client";
export { deriveChildSeed, genKeyPairAndSeed, genKeyPairFromSeed } from "./crypto";
export { HASH_LENGTH, deriveChildSeed, genKeyPairAndSeed, genKeyPairFromSeed } from "./crypto";
export { getSkylinkUrlForPortal } from "./download";
export { getEntryUrlForPortal, signEntry } from "./registry";
export { DacLibrary, mySkyDomain, mySkyDevDomain } from "./mysky";
export { DacLibrary, MySky, mySkyDomain, mySkyDevDomain } from "./mysky";
export { deriveEncryptedFileKeyEntropy, deriveEncryptedFileSeed, deriveEncryptedFileTweak, ENCRYPTION_PATH_SEED_LENGTH, } from "./mysky/encrypted_files";
export { deriveDiscoverableFileTweak } from "./mysky/tweak";
export { convertSkylinkToBase32, convertSkylinkToBase64 } from "./skylink/format";

@@ -17,8 +19,8 @@ export { parseSkylink } from "./skylink/parse";

export type { CustomDownloadOptions, ResolveHnsResponse } from "./download";
export type { CustomConnectorOptions, MySky } from "./mysky";
export type { CustomConnectorOptions } from "./mysky";
export type { CustomPinOptions, PinResponse } from "./pin";
export type { CustomGetEntryOptions, CustomSetEntryOptions, SignedRegistryEntry, RegistryEntry } from "./registry";
export type { CustomGetJSONOptions, CustomSetJSONOptions, JsonData, JSONResponse } from "./skydb";
export type { CustomGetJSONOptions, CustomSetJSONOptions, JsonData, JSONResponse, RawBytesResponse } from "./skydb";
export type { CustomUploadOptions, UploadRequestResponse } from "./upload";
export type { ParseSkylinkOptions } from "./skylink/parse";
//# sourceMappingURL=index.d.ts.map
/* istanbul ignore file */
export { SkynetClient } from "./client";
export { deriveChildSeed, genKeyPairAndSeed, genKeyPairFromSeed } from "./crypto";
export { HASH_LENGTH, deriveChildSeed, genKeyPairAndSeed, genKeyPairFromSeed } from "./crypto";
export { getSkylinkUrlForPortal } from "./download";
export { getEntryUrlForPortal, signEntry } from "./registry";
export { DacLibrary, mySkyDomain, mySkyDevDomain } from "./mysky";
export { DacLibrary, MySky, mySkyDomain, mySkyDevDomain } from "./mysky";
export { deriveEncryptedFileKeyEntropy, deriveEncryptedFileSeed, deriveEncryptedFileTweak, ENCRYPTION_PATH_SEED_LENGTH, } from "./mysky/encrypted_files";
export { deriveDiscoverableFileTweak } from "./mysky/tweak";
export { convertSkylinkToBase32, convertSkylinkToBase64 } from "./skylink/format";

@@ -8,0 +10,0 @@ export { parseSkylink } from "./skylink/parse";

@@ -5,3 +5,2 @@ export type { CustomConnectorOptions } from "./connector";

import { Permission } from "skynet-mysky-utils";
import type { CustomUserIDOptions } from "skynet-mysky-utils";
import { Connector, CustomConnectorOptions } from "./connector";

@@ -13,2 +12,3 @@ import { SkynetClient } from "../client";

import { Signature } from "../crypto";
import { EncryptedJSONResponse } from "./encrypted_files";
export declare const mySkyDomain = "skynet-mysky.hns";

@@ -61,5 +61,6 @@ export declare const mySkyDevDomain = "skynet-mysky-dev.hns";

requestLoginAccess(): Promise<boolean>;
userID(opts?: CustomUserIDOptions): Promise<string>;
userID(): Promise<string>;
/**
* Gets Discoverable JSON at the given path through MySky, if the user has given Read permissions to do so.
* Gets Discoverable JSON at the given path through MySky, if the user has
* given Discoverable Read permissions to do so.
*

@@ -69,2 +70,3 @@ * @param path - The data path.

* @returns - An object containing the json data as well as the skylink for the data.
* @throws - Will throw if the user does not have Discoverable Read permission on the path.
*/

@@ -81,3 +83,4 @@ getJSON(path: string, customOptions?: CustomGetJSONOptions): Promise<JSONResponse>;

/**
* Sets Discoverable JSON at the given path through MySky, if the user has given Write permissions to do so.
* Sets Discoverable JSON at the given path through MySky, if the user has
* given Discoverable Write permissions to do so.
*

@@ -88,2 +91,3 @@ * @param path - The data path.

* @returns - An object containing the json data as well as the skylink for the data.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/

@@ -98,6 +102,8 @@ setJSON(path: string, json: JsonData, customOptions?: CustomSetJSONOptions): Promise<JSONResponse>;

* @returns - An empty promise.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/
setDataLink(path: string, dataLink: string, customOptions?: CustomSetJSONOptions): Promise<void>;
/**
* Deletes Discoverable JSON at the given path through MySky, if the user has given Write permissions to do so.
* Deletes Discoverable JSON at the given path through MySky, if the user has
* given Discoverable Write permissions to do so.
*

@@ -108,6 +114,8 @@ * @param path - The data path.

* @throws - Will throw if the revision is already the maximum value.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/
deleteJSON(path: string, customOptions?: CustomSetJSONOptions): Promise<void>;
/**
* Gets the raw registry entry data for the given path, if the user has given READ permissions.
* Gets the raw registry entry data for the given path, if the user has given
* Discoverable Read permissions.
*

@@ -117,6 +125,8 @@ * @param path - The data path.

* @returns - The entry data.
* @throws - Will throw if the user does not have Discoverable Read permission on the path.
*/
getEntryData(path: string, customOptions?: CustomGetEntryOptions): Promise<EntryData>;
/**
* Sets the entry data at the given path, if the user has given WRITE permissions.
* Sets the entry data at the given path, if the user has given Discoverable
* Write permissions.
*

@@ -128,4 +138,36 @@ * @param path - The data path.

* @throws - Will throw if the length of the data is > 70 bytes.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/
setEntryData(path: string, data: Uint8Array, customOptions?: CustomSetJSONOptions): Promise<EntryData>;
/**
* Lets you get the share-able path seed, which can be passed to
* file.getJSONEncrypted. Requires Hidden Read permission on the path.
*
* @param path - The given path.
* @param isDirectory - Whether the path is a directory.
* @returns - The seed for the path.
* @throws - Will throw if the user does not have Hidden Read permission on the path.
*/
getEncryptedFileSeed(path: string, isDirectory: boolean): Promise<string>;
/**
* Gets Encrypted JSON at the given path through MySky, if the user has given
* Hidden Read permissions to do so.
*
* @param path - The data path.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - An object containing the decrypted json data.
* @throws - Will throw if the user does not have Hidden Read permission on the path.
*/
getJSONEncrypted(path: string, customOptions?: CustomGetJSONOptions): Promise<EncryptedJSONResponse>;
/**
* Sets Encrypted JSON at the given path through MySky, if the user has given
* Hidden Write permissions to do so.
*
* @param path - The data path.
* @param json - The json to encrypt and set.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - An object containing the original json data.
* @throws - Will throw if the user does not have Hidden Write permission on the path.
*/
setJSONEncrypted(path: string, json: JsonData, customOptions?: CustomSetJSONOptions): Promise<EncryptedJSONResponse>;
protected catchError(errorMsg: string): Promise<void>;

@@ -137,3 +179,4 @@ protected launchUI(): Promise<Window>;

protected signRegistryEntry(entry: RegistryEntry, path: string): Promise<Signature>;
protected signEncryptedRegistryEntry(entry: RegistryEntry, path: string): Promise<Signature>;
}
//# sourceMappingURL=index.d.ts.map

@@ -7,8 +7,9 @@ /* istanbul ignore file */

import { defaultGetEntryOptions, defaultSetEntryOptions } from "../registry";
import { defaultGetJSONOptions, defaultSetJSONOptions, getOrCreateRegistryEntry, getNextRegistryEntry, } from "../skydb";
import { deriveDiscoverableTweak } from "./tweak";
import { defaultGetJSONOptions, defaultSetJSONOptions, getOrCreateRegistryEntry, getNextRegistryEntry, getOrCreateRawBytesRegistryEntry, } from "../skydb";
import { deriveDiscoverableFileTweak } from "./tweak";
import { popupCenter } from "./utils";
import { extractOptions } from "../utils/options";
import { throwValidationError, validateObject, validateOptionalObject, validateString, validateUint8Array, } from "../utils/validation";
import { throwValidationError, validateBoolean, validateObject, validateOptionalObject, validateString, validateUint8Array, } from "../utils/validation";
import { decodeSkylink, RAW_SKYLINK_SIZE } from "../skylink/sia";
import { decryptJSONFile, deriveEncryptedFileKeyEntropy, deriveEncryptedFileTweak, ENCRYPTED_JSON_RESPONSE_VERSION, encryptJSONFile, } from "./encrypted_files";
export const mySkyDomain = "skynet-mysky.hns";

@@ -188,7 +189,8 @@ export const mySkyDevDomain = "skynet-mysky-dev.hns";

}
async userID(opts) {
return await this.connector.connection.remoteHandle().call("userID", opts);
async userID() {
return await this.connector.connection.remoteHandle().call("userID");
}
/**
* Gets Discoverable JSON at the given path through MySky, if the user has given Read permissions to do so.
* Gets Discoverable JSON at the given path through MySky, if the user has
* given Discoverable Read permissions to do so.
*

@@ -198,2 +200,3 @@ * @param path - The data path.

* @returns - An object containing the json data as well as the skylink for the data.
* @throws - Will throw if the user does not have Discoverable Read permission on the path.
*/

@@ -209,3 +212,3 @@ async getJSON(path, customOptions) {

const publicKey = await this.userID();
const dataKey = deriveDiscoverableTweak(path);
const dataKey = deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -224,3 +227,3 @@ return await this.connector.client.db.getJSON(publicKey, dataKey, opts);

const publicKey = await this.userID();
const dataKey = deriveDiscoverableTweak(path);
const dataKey = deriveDiscoverableFileTweak(path);
// Do not hash the tweak anymore.

@@ -231,3 +234,4 @@ const opts = { ...defaultGetEntryOptions, hashedDataKeyHex: true };

/**
* Sets Discoverable JSON at the given path through MySky, if the user has given Write permissions to do so.
* Sets Discoverable JSON at the given path through MySky, if the user has
* given Discoverable Write permissions to do so.
*

@@ -238,2 +242,3 @@ * @param path - The data path.

* @returns - An object containing the json data as well as the skylink for the data.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/

@@ -250,3 +255,3 @@ async setJSON(path, json, customOptions) {

const publicKey = await this.userID();
const dataKey = deriveDiscoverableTweak(path);
const dataKey = deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -266,2 +271,3 @@ const [entry, dataLink] = await getOrCreateRegistryEntry(this.connector.client, publicKey, dataKey, json, opts);

* @returns - An empty promise.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/

@@ -278,3 +284,3 @@ async setDataLink(path, dataLink, customOptions) {

const publicKey = await this.userID();
const dataKey = deriveDiscoverableTweak(path);
const dataKey = deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -288,3 +294,4 @@ const getEntryOpts = extractOptions(opts, defaultGetEntryOptions);

/**
* Deletes Discoverable JSON at the given path through MySky, if the user has given Write permissions to do so.
* Deletes Discoverable JSON at the given path through MySky, if the user has
* given Discoverable Write permissions to do so.
*

@@ -295,2 +302,3 @@ * @param path - The data path.

* @throws - Will throw if the revision is already the maximum value.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/

@@ -306,3 +314,3 @@ async deleteJSON(path, customOptions) {

const publicKey = await this.userID();
const dataKey = deriveDiscoverableTweak(path);
const dataKey = deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -316,3 +324,4 @@ const getEntryOpts = extractOptions(opts, defaultGetEntryOptions);

/**
* Gets the raw registry entry data for the given path, if the user has given READ permissions.
* Gets the raw registry entry data for the given path, if the user has given
* Discoverable Read permissions.
*

@@ -322,2 +331,3 @@ * @param path - The data path.

* @returns - The entry data.
* @throws - Will throw if the user does not have Discoverable Read permission on the path.
*/

@@ -333,3 +343,3 @@ async getEntryData(path, customOptions) {

const publicKey = await this.userID();
const dataKey = deriveDiscoverableTweak(path);
const dataKey = deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -343,3 +353,4 @@ const { entry } = await this.connector.client.registry.getEntry(publicKey, dataKey, opts);

/**
* Sets the entry data at the given path, if the user has given WRITE permissions.
* Sets the entry data at the given path, if the user has given Discoverable
* Write permissions.
*

@@ -351,2 +362,3 @@ * @param path - The data path.

* @throws - Will throw if the length of the data is > 70 bytes.
* @throws - Will throw if the user does not have Discoverable Write permission on the path.
*/

@@ -356,3 +368,3 @@ async setEntryData(path, data, customOptions) {

validateUint8Array("data", data, "parameter");
validateOptionalObject("customOptions", customOptions, "parameter", defaultGetEntryOptions);
validateOptionalObject("customOptions", customOptions, "parameter", defaultSetEntryOptions);
if (data.length > MAX_ENTRY_LENGTH) {

@@ -367,3 +379,3 @@ throwValidationError("data", data, "parameter", `'Uint8Array' of length <= ${MAX_ENTRY_LENGTH}, was length ${data.length}`);

const publicKey = await this.userID();
const dataKey = deriveDiscoverableTweak(path);
const dataKey = deriveDiscoverableFileTweak(path);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.

@@ -377,2 +389,82 @@ const getEntryOpts = extractOptions(opts, defaultGetEntryOptions);

}
// ===============
// Encrypted Files
// ===============
/**
* Lets you get the share-able path seed, which can be passed to
* file.getJSONEncrypted. Requires Hidden Read permission on the path.
*
* @param path - The given path.
* @param isDirectory - Whether the path is a directory.
* @returns - The seed for the path.
* @throws - Will throw if the user does not have Hidden Read permission on the path.
*/
async getEncryptedFileSeed(path, isDirectory) {
validateString("path", path, "parameter");
validateBoolean("isDirectory", isDirectory, "parameter");
return await this.connector.connection.remoteHandle().call("getEncryptedFileSeed", path, isDirectory);
}
/**
* Gets Encrypted JSON at the given path through MySky, if the user has given
* Hidden Read permissions to do so.
*
* @param path - The data path.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - An object containing the decrypted json data.
* @throws - Will throw if the user does not have Hidden Read permission on the path.
*/
async getJSONEncrypted(path, customOptions) {
validateString("path", path, "parameter");
validateOptionalObject("customOptions", customOptions, "parameter", defaultGetJSONOptions);
const opts = {
...defaultGetJSONOptions,
...this.connector.client.customOptions,
...customOptions,
hashedDataKeyHex: true, // Do not hash the tweak anymore.
};
// Call MySky which checks for read permissions on the path.
const [publicKey, pathSeed] = await Promise.all([this.userID(), this.getEncryptedFileSeed(path, false)]);
// Fetch the raw encrypted JSON data.
const dataKey = deriveEncryptedFileTweak(pathSeed);
const { data } = await this.connector.client.db.getRawBytes(publicKey, dataKey, opts);
if (data === null) {
return { data: null };
}
const encryptionKey = deriveEncryptedFileKeyEntropy(pathSeed);
const json = decryptJSONFile(data, encryptionKey);
return { data: json };
}
/**
* Sets Encrypted JSON at the given path through MySky, if the user has given
* Hidden Write permissions to do so.
*
* @param path - The data path.
* @param json - The json to encrypt and set.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - An object containing the original json data.
* @throws - Will throw if the user does not have Hidden Write permission on the path.
*/
async setJSONEncrypted(path, json, customOptions) {
validateString("path", path, "parameter");
validateObject("json", json, "parameter");
validateOptionalObject("customOptions", customOptions, "parameter", defaultSetJSONOptions);
const opts = {
...defaultSetJSONOptions,
...this.connector.client.customOptions,
...customOptions,
};
// Call MySky which checks for read permissions on the path.
const [publicKey, pathSeed] = await Promise.all([this.userID(), this.getEncryptedFileSeed(path, false)]);
const dataKey = deriveEncryptedFileTweak(pathSeed);
opts.hashedDataKeyHex = true; // Do not hash the tweak anymore.
const encryptionKey = deriveEncryptedFileKeyEntropy(pathSeed);
// Pad and encrypt json file.
const data = encryptJSONFile(json, { version: ENCRYPTED_JSON_RESPONSE_VERSION }, encryptionKey);
const entry = await getOrCreateRawBytesRegistryEntry(this.connector.client, publicKey, dataKey, data, opts);
// Call MySky which checks for write permissions on the path.
const signature = await this.signEncryptedRegistryEntry(entry, path);
const setEntryOpts = extractOptions(opts, defaultSetEntryOptions);
await this.connector.client.registry.postSignedEntry(publicKey, entry, signature, setEntryOpts);
return { data: json };
}
// ================

@@ -427,3 +519,6 @@ // Internal Methods

}
async signEncryptedRegistryEntry(entry, path) {
return await this.connector.connection.remoteHandle().call("signEncryptedRegistryEntry", entry, path);
}
}
MySky.instance = null;

@@ -0,1 +1,8 @@

/**
* Derives the discoverable file tweak for the given path.
*
* @param path - The given path.
* @returns - The hex-encoded tweak.
*/
export declare function deriveDiscoverableFileTweak(path: string): string;
export declare class DiscoverableBucketTweak {

@@ -22,9 +29,2 @@ version: number;

export declare function hashPathComponent(component: string): Uint8Array;
/**
* Derives the discoverable file tweak for the given path.
*
* @param path - The given path.
* @returns - The hex-encoded tweak.
*/
export declare function deriveDiscoverableTweak(path: string): string;
//# sourceMappingURL=tweak.d.ts.map
import { hashAll } from "../crypto";
import { stringToUint8ArrayUtf8, toHexString } from "../utils/string";
const discoverableBucketTweakVersion = 1;
/**
* Derives the discoverable file tweak for the given path.
*
* @param path - The given path.
* @returns - The hex-encoded tweak.
*/
export function deriveDiscoverableFileTweak(path) {
const dbt = new DiscoverableBucketTweak(path);
const bytes = dbt.getHash();
return toHexString(bytes);
}
export class DiscoverableBucketTweak {

@@ -42,15 +53,5 @@ constructor(path) {

*/
// TODO: Can we replace with hashString?
export function hashPathComponent(component) {
return hashAll(stringToUint8ArrayUtf8(component));
}
/**
* Derives the discoverable file tweak for the given path.
*
* @param path - The given path.
* @returns - The hex-encoded tweak.
*/
export function deriveDiscoverableTweak(path) {
const dbt = new DiscoverableBucketTweak(path);
const bytes = dbt.getHash();
return toHexString(bytes);
}

@@ -6,2 +6,6 @@ import { SkynetClient } from "./client";

export declare type JsonData = Record<string, unknown>;
export declare type JsonFullData = {
_data: JsonData;
_v: number;
};
/**

@@ -21,2 +25,3 @@ * Custom get JSON options.

range: undefined;
responseType: undefined;
query: undefined;

@@ -38,3 +43,12 @@ subdomain: boolean;

endpointLargeUpload: string;
customFilename: string;
customFilename: string; /**
* Gets the JSON object corresponding to the publicKey and dataKey.
*
* @param this - SkynetClient
* @param publicKey - The user public key.
* @param dataKey - The key of the data to fetch for the given user.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - The returned JSON and corresponding data link.
* @throws - Will throw if the returned signature does not match the returned entry, or if the skylink in the entry is invalid.
*/
largeFileSize: number;

@@ -53,2 +67,3 @@ retryDelays: number[];

range: undefined;
responseType: undefined;
query: undefined;

@@ -62,2 +77,6 @@ subdomain: boolean;

};
export declare type RawBytesResponse = {
data: Uint8Array | null;
dataLink: string | null;
};
/**

@@ -101,9 +120,32 @@ * Gets the JSON object corresponding to the publicKey and dataKey.

* @param privateKey - The user private key.
* @param dataKey - The key of the data to fetch for the given user.
* @param dataKey - The data key.
* @param dataLink - The data link to set at the entry.
* @param [customOptions] - Additional settings that can optionally be set.
* @throws - Will throw if the input keys are not valid strings
* @throws - Will throw if the input keys are not valid strings.
*/
export declare function setDataLink(this: SkynetClient, privateKey: string, dataKey: string, dataLink: string, customOptions?: CustomSetJSONOptions): Promise<void>;
/**
* Gets the raw bytes corresponding to the publicKey and dataKey. The caller is responsible for setting any metadata in the bytes.
*
* @param this - SkynetClient
* @param publicKey - The user public key.
* @param dataKey - The key of the data to fetch for the given user.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - The returned bytes.
* @throws - Will throw if the returned signature does not match the returned entry, or if the skylink in the entry is invalid.
*/
export declare function getRawBytes(this: SkynetClient, publicKey: string, dataKey: string, customOptions?: CustomGetJSONOptions): Promise<RawBytesResponse>;
/**
* Gets the registry entry for the given raw bytes or creates the entry if it doesn't exist.
*
* @param client - The Skynet client.
* @param publicKey - The user public key.
* @param dataKey - The dat akey.
* @param data - The raw byte data to set.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - The registry entry and corresponding data link.
* @throws - Will throw if the revision is already the maximum value.
*/
export declare function getOrCreateRawBytesRegistryEntry(client: SkynetClient, publicKey: string, dataKey: string, data: Uint8Array, customOptions?: CustomSetJSONOptions): Promise<RegistryEntry>;
/**
* Gets the next entry for the given public key and data key, setting the data to be the given data and the revision number accordingly.

@@ -140,2 +182,11 @@ *

export declare function getNextRevisionFromEntry(entry: RegistryEntry | null): bigint;
/**
* Checks whether the raw data link matches the cached data link, if provided.
*
* @param rawDataLink - The raw, unformatted data link.
* @param cachedDataLink - The cached data link, if provided.
* @returns - Whether the cached data link is a match.
* @throws - Will throw if the given cached data link is not a valid skylink.
*/
export declare function checkCachedDataLink(rawDataLink: string, cachedDataLink?: string): boolean;
//# sourceMappingURL=skydb.d.ts.map

@@ -12,3 +12,3 @@ import { sign } from "tweetnacl";

import { defaultBaseOptions, extractOptions } from "./utils/options";
import { throwValidationError, validateHexString, validateObject, validateOptionalObject, validateSkylinkString, validateString, validateUint8Array, validateUint8ArrayLen, } from "./utils/validation";
import { throwValidationError, validateHexString, validateObject, validateOptionalObject, validateSkylinkString, validateString, validateUint8ArrayLen, } from "./utils/validation";
import { areEqualUint8Arrays } from "./utils/array";

@@ -28,2 +28,5 @@ const JSON_RESPONSE_VERSION = 2;

};
// ====
// JSON
// ====
/**

@@ -48,29 +51,12 @@ * Gets the JSON object corresponding to the publicKey and dataKey.

// Lookup the registry entry.
const getEntryOpts = extractOptions(opts, defaultGetEntryOptions);
const { entry } = await this.registry.getEntry(publicKey, dataKey, getEntryOpts);
if (entry === null || areEqualUint8Arrays(entry.data, EMPTY_SKYLINK)) {
const entry = await getSkyDBRegistryEntry(this, publicKey, dataKey, opts);
if (entry === null) {
return { data: null, dataLink: null };
}
validateUint8Array("entry.data", entry.data, "returned entry data");
// Determine the data link.
// TODO: Can this still be an entry link which hasn't yet resolved to a data link?
let rawDataLink = "";
if (entry.data.length === BASE64_ENCODED_SKYLINK_SIZE) {
// Legacy data, convert to string.
rawDataLink = uint8ArrayToStringUtf8(entry.data);
}
else if (entry.data.length === RAW_SKYLINK_SIZE) {
// Convert the bytes to a base64 skylink.
rawDataLink = encodeSkylinkBase64(entry.data);
}
else {
throwValidationError("entry.data", entry.data, "returned entry data", `length ${RAW_SKYLINK_SIZE} bytes`);
}
const dataLink = formatSkylink(rawDataLink);
const { rawDataLink, dataLink } = parseDataLink(entry.data, true);
// If a cached data link is provided and the data link hasn't changed, return.
if (opts.cachedDataLink) {
const cachedDataLink = validateSkylinkString("opts.cachedDataLink", opts.cachedDataLink, "optional parameter");
if (rawDataLink === cachedDataLink) {
return { data: null, dataLink };
}
if (checkCachedDataLink(rawDataLink, opts.cachedDataLink)) {
return { data: null, dataLink };
}

@@ -84,3 +70,3 @@ // Download the data in the returned data link.

if (!(data["_data"] && data["_v"])) {
// Legacy data prior to v4, return as-is.
// Legacy data prior to skynet-js v4, return as-is.
return { data, dataLink };

@@ -152,6 +138,6 @@ }

* @param privateKey - The user private key.
* @param dataKey - The key of the data to fetch for the given user.
* @param dataKey - The data key.
* @param dataLink - The data link to set at the entry.
* @param [customOptions] - Additional settings that can optionally be set.
* @throws - Will throw if the input keys are not valid strings
* @throws - Will throw if the input keys are not valid strings.
*/

@@ -175,3 +161,98 @@ export async function setDataLink(privateKey, dataKey, dataLink, customOptions) {

}
// =========
// Raw Bytes
// =========
/**
* Gets the raw bytes corresponding to the publicKey and dataKey. The caller is responsible for setting any metadata in the bytes.
*
* @param this - SkynetClient
* @param publicKey - The user public key.
* @param dataKey - The key of the data to fetch for the given user.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - The returned bytes.
* @throws - Will throw if the returned signature does not match the returned entry, or if the skylink in the entry is invalid.
*/
// TODO: Should we expose this in the API?
export async function getRawBytes(publicKey, dataKey,
// TODO: Take a new options type?
customOptions) {
validateOptionalObject("customOptions", customOptions, "parameter", defaultGetJSONOptions);
// Rest of validation is done in `getEntry`.
const opts = {
...defaultGetJSONOptions,
...this.customOptions,
...customOptions,
};
// Lookup the registry entry.
const entry = await getSkyDBRegistryEntry(this, publicKey, dataKey, opts);
if (entry === null) {
return { data: null, dataLink: null };
}
// Determine the data link.
// TODO: Can this still be an entry link which hasn't yet resolved to a data link?
const { rawDataLink, dataLink } = parseDataLink(entry.data, false);
// If a cached data link is provided and the data link hasn't changed, return.
if (checkCachedDataLink(rawDataLink, opts.cachedDataLink)) {
return { data: null, dataLink };
}
// Download the data in the returned data link.
const downloadOpts = { ...extractOptions(opts, defaultDownloadOptions), responseType: "arraybuffer" };
const { data: buffer } = await this.getFileContent(dataLink, downloadOpts);
return { data: new Uint8Array(buffer), dataLink };
}
/* istanbul ignore next */
/**
* Gets the registry entry for the given raw bytes or creates the entry if it doesn't exist.
*
* @param client - The Skynet client.
* @param publicKey - The user public key.
* @param dataKey - The dat akey.
* @param data - The raw byte data to set.
* @param [customOptions] - Additional settings that can optionally be set.
* @returns - The registry entry and corresponding data link.
* @throws - Will throw if the revision is already the maximum value.
*/
// TODO: Rename & refactor after the SkyDB caching refactor.
export async function getOrCreateRawBytesRegistryEntry(client, publicKey, dataKey, data, customOptions) {
// Not publicly available, don't validate input.
const opts = {
...defaultSetJSONOptions,
...client.customOptions,
...customOptions,
};
// Create the data to upload to acquire its skylink.
let dataKeyHex = dataKey;
if (!opts.hashedDataKeyHex) {
dataKeyHex = toHexString(stringToUint8ArrayUtf8(dataKey));
}
const file = new File([data], `dk:${dataKeyHex}`, { type: "application/octet-stream" });
// Start file upload, do not block.
const uploadOpts = extractOptions(opts, defaultUploadOptions);
const skyfilePromise = client.uploadFile(file, uploadOpts);
// Fetch the current value to find out the revision.
//
// Start getEntry, do not block.
const getEntryOpts = extractOptions(opts, defaultGetEntryOptions);
const entryPromise = client.registry.getEntry(publicKey, dataKey, getEntryOpts);
// Block until both getEntry and uploadFile are finished.
const [signedEntry, skyfile] = await Promise.all([
entryPromise,
skyfilePromise,
]);
const revision = getNextRevisionFromEntry(signedEntry.entry);
// Build the registry entry.
const dataLink = trimUriPrefix(skyfile.skylink, uriSkynetPrefix);
const rawDataLink = decodeSkylinkBase64(dataLink);
validateUint8ArrayLen("rawDataLink", rawDataLink, "skylink byte array", RAW_SKYLINK_SIZE);
const entry = {
dataKey,
data: rawDataLink,
revision,
};
return entry;
}
// =======
// Helpers
// =======
/**
* Gets the next entry for the given public key and data key, setting the data to be the given data and the revision number accordingly.

@@ -278,1 +359,56 @@ *

}
/**
* Checks whether the raw data link matches the cached data link, if provided.
*
* @param rawDataLink - The raw, unformatted data link.
* @param cachedDataLink - The cached data link, if provided.
* @returns - Whether the cached data link is a match.
* @throws - Will throw if the given cached data link is not a valid skylink.
*/
export function checkCachedDataLink(rawDataLink, cachedDataLink) {
if (cachedDataLink) {
cachedDataLink = validateSkylinkString("cachedDataLink", cachedDataLink, "optional parameter");
return rawDataLink === cachedDataLink;
}
return false;
}
/**
* Gets the registry entry, returning null if the entry contains an empty skylink (the deletion sentinel).
*
* @param client - The Skynet Client
* @param publicKey - The user public key.
* @param dataKey - The key of the data to fetch for the given user.
* @param opts - Additional settings.
* @returns - The registry entry, or null if not found or deleted.
*/
async function getSkyDBRegistryEntry(client, publicKey, dataKey, opts) {
const getEntryOpts = extractOptions(opts, defaultGetEntryOptions);
const { entry } = await client.registry.getEntry(publicKey, dataKey, getEntryOpts);
if (entry === null || areEqualUint8Arrays(entry.data, EMPTY_SKYLINK)) {
return null;
}
return entry;
}
/**
* Parses a data link out of the given registry entry data.
*
* @param data - The raw registry entry data.
* @param legacy - Whether to check for possible legacy skylink data, encoded as base64.
* @returns - The raw, unformatted data link and the formatted data link.
* @throws - Will throw if the data is not of the expected length for a skylink.
*/
function parseDataLink(data, legacy) {
let rawDataLink = "";
if (legacy && data.length === BASE64_ENCODED_SKYLINK_SIZE) {
// Legacy data, convert to string for backwards compatibility.
rawDataLink = uint8ArrayToStringUtf8(data);
}
else if (data.length === RAW_SKYLINK_SIZE) {
// Convert the bytes to a base64 skylink.
rawDataLink = encodeSkylinkBase64(data);
}
else {
throwValidationError("entry.data", data, "returned entry data", `length ${RAW_SKYLINK_SIZE} bytes`);
}
return { rawDataLink, dataLink: formatSkylink(rawDataLink) };
}

@@ -54,6 +54,3 @@ import { hashAll } from "../crypto";

static fromBytes(data) {
// Sanity check the size of the given data.
if (data.length !== RAW_SKYLINK_SIZE) {
throw new Error("Failed to load skylink data");
}
validateUint8ArrayLen("data", data, "parameter", RAW_SKYLINK_SIZE);
const view = new DataView(data.buffer);

@@ -60,0 +57,0 @@ // Load the bitfield.

@@ -165,3 +165,6 @@ import { Upload } from "tus-js-client";

onError: (error) => {
reject(error);
// @ts-expect-error tus-client-js Error is not typed correctly.
const res = error.originalResponse;
const message = res ? res.getBody() || error : error;
reject(new Error(message.trim()));
},

@@ -168,0 +171,0 @@ onSuccess: async () => {

@@ -11,2 +11,11 @@ /**

/**
* Validates the given value as a boolean.
*
* @param name - The name of the value.
* @param value - The actual value.
* @param valueKind - The kind of value that is being checked (e.g. "parameter", "response field", etc.)
* @throws - Will throw if not a valid boolean.
*/
export declare function validateBoolean(name: string, value: unknown, valueKind: string): void;
/**
* Validates the given value as an object.

@@ -13,0 +22,0 @@ *

@@ -17,2 +17,15 @@ import { parseSkylink } from "../skylink/parse";

/**
* Validates the given value as a boolean.
*
* @param name - The name of the value.
* @param value - The actual value.
* @param valueKind - The kind of value that is being checked (e.g. "parameter", "response field", etc.)
* @throws - Will throw if not a valid boolean.
*/
export function validateBoolean(name, value, valueKind) {
if (typeof value !== "boolean") {
throwValidationError(name, value, valueKind, "type 'boolean'");
}
}
/**
* Validates the given value as an object.

@@ -19,0 +32,0 @@ *

{
"name": "skynet-js",
"version": "4.0.11-beta",
"version": "4.0.12-beta",
"description": "Sia Skynet Javascript Client",

@@ -5,0 +5,0 @@ "main": "dist/cjs/index.js",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc