@ethersphere/bee-js
Version:
Javascript client for Bee
163 lines (162 loc) • 7.81 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.downloadSingleOwnerChunk = exports.uploadSingleOwnerChunkWithWrappedChunk = exports.uploadSingleOwnerChunkData = exports.uploadSingleOwnerChunk = exports.makeSingleOwnerChunk = exports.makeSOCAddress = exports.makeSingleOwnerChunkFromData = void 0;
const cafe_utility_1 = require("cafe-utility");
const chunkAPI = __importStar(require("../modules/chunk"));
const socAPI = __importStar(require("../modules/soc"));
const bytes_1 = require("../utils/bytes");
const error_1 = require("../utils/error");
const typed_bytes_1 = require("../utils/typed-bytes");
const bmt_1 = require("./bmt");
const cac_1 = require("./cac");
const SOC_SIGNATURE_OFFSET = typed_bytes_1.Identifier.LENGTH;
const SOC_SPAN_OFFSET = SOC_SIGNATURE_OFFSET + typed_bytes_1.Signature.LENGTH;
const SOC_PAYLOAD_OFFSET = SOC_SPAN_OFFSET + typed_bytes_1.Span.LENGTH;
function recoverChunkOwner(data) {
const cacData = data.slice(SOC_SPAN_OFFSET);
const chunkAddress = (0, bmt_1.calculateChunkAddress)(cacData);
const signature = typed_bytes_1.Signature.fromSlice(data, SOC_SIGNATURE_OFFSET);
const identifier = bytes_1.Bytes.fromSlice(data, 0, typed_bytes_1.Identifier.LENGTH);
const digest = cafe_utility_1.Binary.concatBytes(identifier.toUint8Array(), chunkAddress.toUint8Array());
const ownerAddress = signature.recoverPublicKey(digest).address();
return ownerAddress;
}
/**
* Verifies if the data is a valid single owner chunk
*
* @param data The chunk data
* @param address The address of the single owner chunk
*
* @returns a single owner chunk or throws error
*/
function makeSingleOwnerChunkFromData(data, address) {
data = data instanceof bytes_1.Bytes ? data.toUint8Array() : data;
address = new typed_bytes_1.Reference(address);
const ownerAddress = recoverChunkOwner(data);
const identifier = bytes_1.Bytes.fromSlice(data, 0, typed_bytes_1.Identifier.LENGTH);
const socAddress = new typed_bytes_1.Reference(cafe_utility_1.Binary.keccak256(cafe_utility_1.Binary.concatBytes(identifier.toUint8Array(), ownerAddress.toUint8Array())));
if (!cafe_utility_1.Binary.equals(address.toUint8Array(), socAddress.toUint8Array())) {
throw new error_1.BeeError('SOC Data does not match given address!');
}
const signature = typed_bytes_1.Signature.fromSlice(data, SOC_SIGNATURE_OFFSET);
const span = typed_bytes_1.Span.fromSlice(data, SOC_SPAN_OFFSET);
const payload = bytes_1.Bytes.fromSlice(data, SOC_PAYLOAD_OFFSET);
return {
data,
identifier,
signature,
span,
payload,
address: socAddress,
owner: ownerAddress,
};
}
exports.makeSingleOwnerChunkFromData = makeSingleOwnerChunkFromData;
function makeSOCAddress(identifier, address) {
return new typed_bytes_1.Reference(cafe_utility_1.Binary.keccak256(cafe_utility_1.Binary.concatBytes(identifier.toUint8Array(), address.toUint8Array())));
}
exports.makeSOCAddress = makeSOCAddress;
/**
* Creates a single owner chunk object
*
* @param chunk A chunk object used for the span and payload
* @param identifier The identifier of the chunk
* @param signer The signer interface for signing the chunk
*/
function makeSingleOwnerChunk(chunk, identifier, signer) {
identifier = new typed_bytes_1.Identifier(identifier);
signer = new typed_bytes_1.PrivateKey(signer);
const address = makeSOCAddress(identifier, signer.publicKey().address());
const signature = signer.sign(cafe_utility_1.Binary.concatBytes(identifier.toUint8Array(), chunk.address.toUint8Array()));
const data = cafe_utility_1.Binary.concatBytes(identifier.toUint8Array(), signature.toUint8Array(), chunk.data);
const span = typed_bytes_1.Span.fromSlice(chunk.data, 0);
const payload = bytes_1.Bytes.fromSlice(chunk.data, typed_bytes_1.Span.LENGTH);
return {
data,
identifier,
signature,
span,
payload,
address,
owner: signer.publicKey().address(),
};
}
exports.makeSingleOwnerChunk = makeSingleOwnerChunk;
/**
* Helper function to upload a chunk.
*
* It uses the Chunk API and calculates the address before uploading.
*
* @param requestOptions Options for making requests
* @param chunk A chunk object
* @param stamp Postage BatchId that will be assigned to uploaded data
* @param options Upload options
*/
async function uploadSingleOwnerChunk(requestOptions, chunk, stamp, options) {
const data = cafe_utility_1.Binary.concatBytes(chunk.span.toUint8Array(), chunk.payload.toUint8Array());
return socAPI.upload(requestOptions, chunk.owner, chunk.identifier, chunk.signature, data, stamp, options);
}
exports.uploadSingleOwnerChunk = uploadSingleOwnerChunk;
/**
* Helper function to create and upload SOC.
*
* @param requestOptions Options for making requests
* @param signer The signer interface for signing the chunk
* @param postageBatchId
* @param identifier The identifier of the chunk
* @param data The chunk data
* @param options
*/
async function uploadSingleOwnerChunkData(requestOptions, signer, stamp, identifier, data, options) {
signer = new typed_bytes_1.PrivateKey(signer);
identifier = new typed_bytes_1.Identifier(identifier);
const cac = (0, cac_1.makeContentAddressedChunk)(data);
const soc = makeSingleOwnerChunk(cac, identifier, signer);
return uploadSingleOwnerChunk(requestOptions, soc, stamp, options);
}
exports.uploadSingleOwnerChunkData = uploadSingleOwnerChunkData;
async function uploadSingleOwnerChunkWithWrappedChunk(requestOptions, signer, stamp, identifier, rootChunk, options) {
signer = new typed_bytes_1.PrivateKey(signer);
identifier = new typed_bytes_1.Identifier(identifier);
const soc = makeSingleOwnerChunk((0, cac_1.asContentAddressedChunk)(rootChunk), identifier, signer);
return uploadSingleOwnerChunk(requestOptions, soc, stamp, options);
}
exports.uploadSingleOwnerChunkWithWrappedChunk = uploadSingleOwnerChunkWithWrappedChunk;
/**
* Helper function to download SOC.
*
* @param url The url of the Bee service
* @param ownerAddress The signer interface for signing the chunk
* @param identifier The identifier of the chunk
*/
async function downloadSingleOwnerChunk(requestOptions, ownerAddress, identifier) {
identifier = new typed_bytes_1.Identifier(identifier);
ownerAddress = new typed_bytes_1.EthAddress(ownerAddress);
const address = makeSOCAddress(identifier, ownerAddress);
const cac = await chunkAPI.download(requestOptions, address.toHex());
return makeSingleOwnerChunkFromData(cac, address);
}
exports.downloadSingleOwnerChunk = downloadSingleOwnerChunk;