UNPKG

@ethersphere/bee-js

Version:
163 lines (162 loc) 7.81 kB
"use strict"; 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;