biketrack-app/node_modules/@ethersphere/bee-js/dist/mjs/chunk/soc.js

179 lines
6.0 KiB
JavaScript
Raw Normal View History

2022-07-11 10:27:11 +02:00
var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { bytesAtOffset, bytesEqual, flexBytesAtOffset } from "../utils/bytes.js";
import { bmtHash } from "./bmt.js";
import { recoverAddress, sign } from "./signer.js";
import { keccak256Hash } from "../utils/hash.js";
import { SPAN_SIZE } from "./span.js";
import { serializeBytes } from "./serialize.js";
import { BeeError } from "../utils/error.js";
import { makeContentAddressedChunk, MAX_PAYLOAD_SIZE, MIN_PAYLOAD_SIZE, assertValidChunkData } from "./cac.js";
import { bytesToHex } from "../utils/hex.js";
import * as socAPI from "../modules/soc.js";
import * as chunkAPI from "../modules/chunk.js";
import { assertAddress } from "../utils/type.js";
const IDENTIFIER_SIZE = 32;
const SIGNATURE_SIZE = 65;
const SOC_IDENTIFIER_OFFSET = 0;
const SOC_SIGNATURE_OFFSET = SOC_IDENTIFIER_OFFSET + IDENTIFIER_SIZE;
const SOC_SPAN_OFFSET = SOC_SIGNATURE_OFFSET + SIGNATURE_SIZE;
const SOC_PAYLOAD_OFFSET = SOC_SPAN_OFFSET + SPAN_SIZE;
function recoverChunkOwner(data) {
const cacData = data.slice(SOC_SPAN_OFFSET);
const chunkAddress = bmtHash(cacData);
const signature = bytesAtOffset(data, SOC_SIGNATURE_OFFSET, SIGNATURE_SIZE);
const identifier = bytesAtOffset(data, SOC_IDENTIFIER_OFFSET, IDENTIFIER_SIZE);
const digest = keccak256Hash(identifier, chunkAddress);
const ownerAddress = recoverAddress(signature, digest);
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
*/
export function makeSingleOwnerChunkFromData(data, address) {
const ownerAddress = recoverChunkOwner(data);
const identifier = bytesAtOffset(data, SOC_IDENTIFIER_OFFSET, IDENTIFIER_SIZE);
const socAddress = keccak256Hash(identifier, ownerAddress);
if (!bytesEqual(address, socAddress)) {
throw new BeeError('SOC Data does not match given address!');
}
const signature = () => bytesAtOffset(data, SOC_SIGNATURE_OFFSET, SIGNATURE_SIZE);
const span = () => bytesAtOffset(data, SOC_SPAN_OFFSET, SPAN_SIZE);
const payload = () => flexBytesAtOffset(data, SOC_PAYLOAD_OFFSET, MIN_PAYLOAD_SIZE, MAX_PAYLOAD_SIZE);
return {
data,
identifier: () => identifier,
signature,
span,
payload,
address: () => socAddress,
owner: () => ownerAddress
};
}
export function makeSOCAddress(identifier, address) {
return keccak256Hash(identifier, address);
}
/**
* 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 singer interface for signing the chunk
*/
export function makeSingleOwnerChunk(chunk, identifier, signer) {
return __awaiter(this, void 0, void 0, function* () {
const chunkAddress = chunk.address();
assertValidChunkData(chunk.data, chunkAddress);
const digest = keccak256Hash(identifier, chunkAddress);
const signature = yield sign(signer, digest);
const data = serializeBytes(identifier, signature, chunk.span(), chunk.payload());
const address = makeSOCAddress(identifier, signer.address);
return {
data,
identifier: () => identifier,
signature: () => signature,
span: () => chunk.span(),
payload: () => chunk.payload(),
address: () => address,
owner: () => signer.address
};
});
}
/**
* Helper function to upload a chunk.
*
* It uses the Chunk API and calculates the address before uploading.
*
* @param ky Ky instance
* @param chunk A chunk object
* @param postageBatchId Postage BatchId that will be assigned to uploaded data
* @param options Upload options
*/
export function uploadSingleOwnerChunk(ky, chunk, postageBatchId, options) {
return __awaiter(this, void 0, void 0, function* () {
const owner = bytesToHex(chunk.owner());
const identifier = bytesToHex(chunk.identifier());
const signature = bytesToHex(chunk.signature());
const data = serializeBytes(chunk.span(), chunk.payload());
return socAPI.upload(ky, owner, identifier, signature, data, postageBatchId, options);
});
}
/**
* Helper function to create and upload SOC.
*
* @param ky Ky instance
* @param signer The singer interface for signing the chunk
* @param postageBatchId
* @param identifier The identifier of the chunk
* @param data The chunk data
* @param options
*/
export function uploadSingleOwnerChunkData(ky, signer, postageBatchId, identifier, data, options) {
return __awaiter(this, void 0, void 0, function* () {
assertAddress(postageBatchId);
const cac = makeContentAddressedChunk(data);
const soc = yield makeSingleOwnerChunk(cac, identifier, signer);
return uploadSingleOwnerChunk(ky, soc, postageBatchId, options);
});
}
/**
* Helper function to download SOC.
*
* @param url The url of the Bee service
* @param ownerAddress The singer interface for signing the chunk
* @param identifier The identifier of the chunk
*/
export function downloadSingleOwnerChunk(ky, ownerAddress, identifier) {
return __awaiter(this, void 0, void 0, function* () {
const address = makeSOCAddress(identifier, ownerAddress);
const data = yield chunkAPI.download(ky, bytesToHex(address));
return makeSingleOwnerChunkFromData(data, address);
});
}