"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (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; }; 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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeFeedWriter = exports.makeFeedReader = exports.downloadFeedUpdate = exports.getFeedUpdateChunkReference = exports.updateFeed = exports.findNextIndex = void 0; const hash_1 = require("../utils/hash"); const serialize_1 = require("../chunk/serialize"); const feed_1 = require("../modules/feed"); const soc_1 = require("../chunk/soc"); const types_1 = require("../types"); const bytes_1 = require("../utils/bytes"); const error_1 = require("../utils/error"); const hex_1 = require("../utils/hex"); const uint64_1 = require("../utils/uint64"); const chunkAPI = __importStar(require("../modules/chunk")); const eth_1 = require("../utils/eth"); const type_1 = require("../utils/type"); const identifier_1 = require("./identifier"); const reference_1 = require("../utils/reference"); const TIMESTAMP_PAYLOAD_OFFSET = 0; const TIMESTAMP_PAYLOAD_SIZE = 8; const REFERENCE_PAYLOAD_OFFSET = TIMESTAMP_PAYLOAD_SIZE; function findNextIndex(ky, owner, topic, options) { return __awaiter(this, void 0, void 0, function* () { try { const feedUpdate = yield (0, feed_1.fetchLatestFeedUpdate)(ky, owner, topic, options); return (0, hex_1.makeHexString)(feedUpdate.feedIndexNext, types_1.FEED_INDEX_HEX_LENGTH); } catch (e) { if (e instanceof error_1.BeeResponseError && e.status === 404) { return (0, hex_1.bytesToHex)((0, bytes_1.makeBytes)(8)); } throw e; } }); } exports.findNextIndex = findNextIndex; function updateFeed(ky, signer, topic, reference, postageBatchId, options, index = 'latest') { var _a; return __awaiter(this, void 0, void 0, function* () { const ownerHex = (0, eth_1.makeHexEthAddress)(signer.address); const nextIndex = index === 'latest' ? yield findNextIndex(ky, ownerHex, topic, options) : index; const identifier = (0, identifier_1.makeFeedIdentifier)(topic, nextIndex); const at = (_a = options === null || options === void 0 ? void 0 : options.at) !== null && _a !== void 0 ? _a : Date.now() / 1000.0; const timestamp = (0, uint64_1.writeUint64BigEndian)(at); const payloadBytes = (0, serialize_1.serializeBytes)(timestamp, reference); return (0, soc_1.uploadSingleOwnerChunkData)(ky, signer, postageBatchId, identifier, payloadBytes, options); }); } exports.updateFeed = updateFeed; function getFeedUpdateChunkReference(owner, topic, index) { const identifier = (0, identifier_1.makeFeedIdentifier)(topic, index); return (0, hash_1.keccak256Hash)(identifier, owner); } exports.getFeedUpdateChunkReference = getFeedUpdateChunkReference; function downloadFeedUpdate(ky, owner, topic, index) { return __awaiter(this, void 0, void 0, function* () { const address = getFeedUpdateChunkReference(owner, topic, index); const addressHex = (0, hex_1.bytesToHex)(address); const data = yield chunkAPI.download(ky, addressHex); const soc = (0, soc_1.makeSingleOwnerChunkFromData)(data, address); const payload = soc.payload(); const timestampBytes = (0, bytes_1.bytesAtOffset)(payload, TIMESTAMP_PAYLOAD_OFFSET, TIMESTAMP_PAYLOAD_SIZE); const timestamp = (0, uint64_1.readUint64BigEndian)(timestampBytes); const reference = (0, reference_1.makeBytesReference)(payload, REFERENCE_PAYLOAD_OFFSET); return { timestamp, reference, }; }); } exports.downloadFeedUpdate = downloadFeedUpdate; function makeFeedReader(ky, type, topic, owner) { return { type, owner, topic, download(options) { return __awaiter(this, void 0, void 0, function* () { if (!(options === null || options === void 0 ? void 0 : options.index)) { return (0, feed_1.fetchLatestFeedUpdate)(ky, owner, topic, Object.assign(Object.assign({}, options), { type })); } const update = yield downloadFeedUpdate(ky, (0, hex_1.hexToBytes)(owner), topic, options.index); return { reference: (0, hex_1.bytesToHex)(update.reference), feedIndex: options.index, feedIndexNext: '', }; }); }, }; } exports.makeFeedReader = makeFeedReader; function makeFeedWriter(ky, type, topic, signer) { const upload = (postageBatchId, reference, options) => __awaiter(this, void 0, void 0, function* () { (0, type_1.assertAddress)(postageBatchId); const canonicalReference = (0, reference_1.makeBytesReference)(reference); return updateFeed(ky, signer, topic, canonicalReference, postageBatchId, Object.assign(Object.assign({}, options), { type })); }); return Object.assign(Object.assign({}, makeFeedReader(ky, type, topic, (0, eth_1.makeHexEthAddress)(signer.address))), { upload }); } exports.makeFeedWriter = makeFeedWriter;