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 { ProtocolsQuery, RecordsCount, RecordsQuery, RecordsRead, RecordsSubscribe } from '@enbox/dwn-sdk-js';
import { getDwnServiceEndpointUrls } from './utils.js';
/**
 * A lightweight DWN API that creates **unsigned** (anonymous) DWN messages and
 * sends them to remote DWNs via RPC.
 *
 * This class does not require a vault, agent DID, signing keys, or any identity
 * infrastructure. It leverages the DWN SDK's native support for optional
 * `signer` on read-path operations (RecordsQuery, RecordsRead, RecordsSubscribe,
 * RecordsCount, ProtocolsQuery).
 *
 * Anonymous queries return only published records. Anonymous reads succeed for
 * published records and for protocol records with `{ who: 'anyone', can: ['read'] }`.
 *
 * @example
 * ```ts
 * const resolver = new UniversalResolver({ didResolvers: [DidDht, DidJwk] });
 * const rpcClient = new Web5RpcClient();
 * const anonymousDwn = new AnonymousDwnApi({ didResolver: resolver, rpcClient });
 *
 * const reply = await anonymousDwn.recordsQuery('did:dht:alice...', {
 *   filter: { protocol: 'https://social.example/posts', protocolPath: 'post' },
 * });
 * ```
 */
export class AnonymousDwnApi {
    constructor({ didResolver, rpcClient }) {
        this._didResolver = didResolver;
        this._rpcClient = rpcClient;
    }
    /**
     * Send an anonymous (unsigned) `RecordsQuery` to a remote DWN.
     *
     * Only published records are returned by the remote DWN.
     *
     * @param target - The DID whose DWN will be queried.
     * @param params - Query parameters (filter, sort, pagination).
     * @returns The raw `RecordsQueryReply` from the remote DWN.
     */
    recordsQuery(target, params) {
        return __awaiter(this, void 0, void 0, function* () {
            const recordsQuery = yield RecordsQuery.create({
                filter: params.filter,
                dateSort: params.dateSort,
                pagination: params.pagination,
                messageTimestamp: params.messageTimestamp,
                // No signer — creates an unsigned message.
            });
            return yield this.sendRequest(target, recordsQuery.message);
        });
    }
    /**
     * Send an anonymous (unsigned) `RecordsRead` to a remote DWN.
     *
     * Succeeds for published records and for protocol records with
     * `{ who: 'anyone', can: ['read'] }` rules.
     *
     * @param target - The DID whose DWN will be read from.
     * @param params - Read parameters (filter).
     * @returns The raw `RecordsReadReply` from the remote DWN.
     */
    recordsRead(target, params) {
        return __awaiter(this, void 0, void 0, function* () {
            const recordsRead = yield RecordsRead.create({
                filter: params.filter,
                messageTimestamp: params.messageTimestamp,
                // No signer — creates an unsigned message.
            });
            return yield this.sendRequest(target, recordsRead.message);
        });
    }
    /**
     * Send an anonymous (unsigned) `RecordsSubscribe` to a remote DWN.
     *
     * Only published record events are received.
     *
     * @param target - The DID whose DWN to subscribe to.
     * @param params - Subscribe parameters (filter).
     * @param handler - Callback for incoming subscription messages (events and EOSE).
     * @returns The raw `RecordsSubscribeReply` from the remote DWN.
     */
    recordsSubscribe(target, params, handler) {
        return __awaiter(this, void 0, void 0, function* () {
            const recordsSubscribe = yield RecordsSubscribe.create({
                filter: params.filter,
                dateSort: params.dateSort,
                pagination: params.pagination,
                messageTimestamp: params.messageTimestamp,
                // No signer — creates an unsigned message.
            });
            return yield this.sendRequest(target, recordsSubscribe.message, undefined, handler);
        });
    }
    /**
     * Send an anonymous (unsigned) `RecordsCount` to a remote DWN.
     *
     * Only published records are counted.
     *
     * @param target - The DID whose DWN to count records in.
     * @param params - Count parameters (filter).
     * @returns The raw `RecordsCountReply` from the remote DWN.
     */
    recordsCount(target, params) {
        return __awaiter(this, void 0, void 0, function* () {
            const recordsCount = yield RecordsCount.create({
                filter: params.filter,
                messageTimestamp: params.messageTimestamp,
                // No signer — creates an unsigned message.
            });
            return yield this.sendRequest(target, recordsCount.message);
        });
    }
    /**
     * Send an anonymous (unsigned) `ProtocolsQuery` to a remote DWN.
     *
     * Only published protocol definitions are returned.
     *
     * @param target - The DID whose DWN to query protocols from.
     * @param params - Optional query parameters (protocol filter).
     * @returns The raw `ProtocolsQueryReply` from the remote DWN.
     */
    protocolsQuery(target, params) {
        return __awaiter(this, void 0, void 0, function* () {
            const protocolsQuery = yield ProtocolsQuery.create({
                filter: params === null || params === void 0 ? void 0 : params.filter,
                messageTimestamp: params === null || params === void 0 ? void 0 : params.messageTimestamp,
                // No signer — creates an unsigned message.
            });
            return yield this.sendRequest(target, protocolsQuery.message);
        });
    }
    /**
     * Resolve the target DID's DWN service endpoints and send an unsigned
     * message to the first one that responds.
     *
     * Follows the same retry-over-endpoints pattern as `AgentDwnApi.sendDwnRpcRequest()`.
     */
    sendRequest(target, message, data, subscriptionHandler) {
        return __awaiter(this, void 0, void 0, function* () {
            const dwnEndpointUrls = yield getDwnServiceEndpointUrls(target, this._didResolver);
            const errorMessages = [];
            for (let dwnUrl of dwnEndpointUrls) {
                try {
                    // For subscriptions, upgrade to WebSocket transport if available.
                    if (subscriptionHandler !== undefined) {
                        const serverInfo = yield this._rpcClient.getServerInfo(dwnUrl);
                        if (!serverInfo.webSocketSupport) {
                            errorMessages.push({ url: dwnUrl, message: 'WebSocket support is not enabled on the server.' });
                            continue;
                        }
                        const parsedUrl = new URL(dwnUrl);
                        parsedUrl.protocol = parsedUrl.protocol === 'http:' ? 'ws:' : 'wss:';
                        dwnUrl = parsedUrl.toString();
                    }
                    const reply = yield this._rpcClient.sendDwnRequest({
                        dwnUrl,
                        targetDid: target,
                        message,
                        data,
                        subscriptionHandler: subscriptionHandler,
                    });
                    return reply;
                }
                catch (error) {
                    errorMessages.push({
                        url: dwnUrl,
                        message: (error instanceof Error) ? error.message : 'Unknown error',
                    });
                }
            }
            throw new Error(`AnonymousDwnApi: Failed to send request to '${target}': ${JSON.stringify(errorMessages)}`);
        });
    }
}
//# sourceMappingURL=anonymous-dwn-api.js.map