"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.callContractView = exports.getContract = exports.getNft = exports.getNftBalance = exports.submitGenericTransaction = exports.submitPaymentTransaction = exports.listTransactions = exports.getAssetBalance = exports.getNativeBalance = exports.getBalance = exports.getAddress = void 0;
const cloud_library_1 = require("@dfns/cloud-library");
const Foundations_1 = require("@dfns/datamodel/dist/Foundations");
const constants_1 = require("./constants");
const signing_group_1 = require("./signing-group");
const types_1 = require("./types");
const getAddress = (walletImplementation) => async ({ body }) => {
    const { publicKeyId, orgId } = body;
    const signer = await (0, signing_group_1.createSigner)({ orgId, publicKeyId });
    const wallet = new walletImplementation(signer);
    return {
        publicKeyId,
        address: await wallet.getAddress(),
    };
};
exports.getAddress = getAddress;
const getBalance = (walletImplementation) => async ({ body }) => {
    const { orgId, publicKeyId, assets } = body;
    const assetsParsed = Array.isArray(assets) ? assets : JSON.parse(assets || '[]');
    const signer = await (0, signing_group_1.createSigner)({ orgId, publicKeyId });
    const wallet = new walletImplementation(signer);
    return {
        publicKeyId,
        balance: await wallet.getBalance(assetsParsed),
    };
};
exports.getBalance = getBalance;
const getNativeBalance = (walletImplementation) => async ({ body }) => {
    const { orgId, publicKeyId, blockNumber } = body;
    const signer = await (0, signing_group_1.createSigner)({ orgId, publicKeyId });
    const wallet = new walletImplementation(signer);
    if (!wallet.getNativeBalance)
        throw new Foundations_1.NotImplementedError('Method not supported', constants_1.SERVICE_NAME);
    return {
        publicKeyId,
        balance: await wallet.getNativeBalance(blockNumber),
    };
};
exports.getNativeBalance = getNativeBalance;
const getAssetBalance = (walletImplementation) => async ({ body }) => {
    const { orgId, publicKeyId, contract, blockNumber } = body;
    if (!(0, cloud_library_1.isStringAndNonEmpty)(contract))
        throw new Foundations_1.BadRequestError('contract should be a non-empty string', constants_1.SERVICE_NAME);
    const signer = await (0, signing_group_1.createSigner)({ orgId, publicKeyId });
    const wallet = new walletImplementation(signer);
    if (!wallet.getAssetBalance)
        throw new Foundations_1.NotImplementedError('Method not supported', constants_1.SERVICE_NAME);
    return {
        publicKeyId,
        balance: await wallet.getAssetBalance(contract, blockNumber),
    };
};
exports.getAssetBalance = getAssetBalance;
const listTransactions = (walletImplementation) => async ({ body }) => {
    const { publicKeyId, orgId, assets } = body;
    const assetsParsed = Array.isArray(assets) ? assets : JSON.parse(assets || '[]');
    const signer = await (0, signing_group_1.createSigner)({ orgId, publicKeyId });
    const wallet = new walletImplementation(signer);
    return {
        publicKeyId,
        transactions: await wallet.getTransactions(assetsParsed),
    };
};
exports.listTransactions = listTransactions;
const submitPaymentTransaction = (walletImplementation) => async ({ body }) => {
    const { publicKeyId, orgId, asset, to, value } = body;
    const signer = await (0, signing_group_1.createSigner)({ orgId, publicKeyId });
    const wallet = new walletImplementation(signer);
    const tx = await wallet.sendPaymentTx({ asset, to, value });
    return { publicKeyId, tx };
};
exports.submitPaymentTransaction = submitPaymentTransaction;
const submitGenericTransaction = (walletImplementation) => async ({ body }) => {
    const { body: txParams, orgId, publicKeyId } = body;
    const signer = await (0, signing_group_1.createSigner)({ orgId, publicKeyId });
    const wallet = new walletImplementation(signer);
    if ((0, types_1.isSendNftTxParams)(txParams)) {
        if (!wallet.sendNftTx)
            throw new Foundations_1.NotImplementedError('Method not supported', constants_1.SERVICE_NAME);
        return {
            publicKeyId,
            tx: await wallet.sendNftTx(txParams),
            response: undefined,
        };
    }
    if (!wallet.sendTx) {
        throw new Foundations_1.NotImplementedError('Send Transaction is not implemented yet', constants_1.SERVICE_NAME);
    }
    const transactionBody = txParams;
    const networkResponse = await wallet.sendTx(transactionBody);
    return {
        publicKeyId,
        tx: networkResponse.hash,
        response: networkResponse.response,
    };
};
exports.submitGenericTransaction = submitGenericTransaction;
const getNftBalance = (walletImplementation) => async ({ body }) => {
    const { orgId, publicKeyId, contract, blockNumber } = body;
    if (!(0, cloud_library_1.isStringAndNonEmpty)(contract))
        throw new Foundations_1.BadRequestError('contract should be a non-empty string', constants_1.SERVICE_NAME);
    const signer = await (0, signing_group_1.createSigner)({ orgId, publicKeyId });
    const wallet = new walletImplementation(signer);
    if (!wallet.getNftBalance)
        throw new Foundations_1.NotImplementedError('Method not supported', constants_1.SERVICE_NAME);
    return {
        publicKeyId,
        ...(await wallet.getNftBalance(contract, blockNumber)),
    };
};
exports.getNftBalance = getNftBalance;
const getNft = (walletImplementation) => async ({ body }) => {
    const { orgId, publicKeyId, contract, tokenId } = body;
    if (!(0, cloud_library_1.isStringAndNonEmpty)(contract))
        throw new Foundations_1.BadRequestError('contract should be a non-empty string', constants_1.SERVICE_NAME);
    if (!(0, cloud_library_1.isStringAndNonEmpty)(tokenId))
        throw new Foundations_1.BadRequestError('tokenId should be a non-empty string', constants_1.SERVICE_NAME);
    const signer = await (0, signing_group_1.createSigner)({ orgId, publicKeyId });
    const wallet = new walletImplementation(signer);
    if (!wallet.getNft)
        throw new Foundations_1.NotImplementedError('Method not supported', constants_1.SERVICE_NAME);
    return {
        publicKeyId,
        nft: await wallet.getNft(contract, tokenId),
    };
};
exports.getNft = getNft;
const getContract = (blockchainImplementation) => async ({ body }) => {
    if (!blockchainImplementation)
        throw new Foundations_1.NotImplementedError('Method not supported', constants_1.SERVICE_NAME);
    const { contract, params } = body;
    if (!(0, cloud_library_1.isStringAndNonEmpty)(contract))
        throw new Foundations_1.BadRequestError('contract should be a non-empty string', constants_1.SERVICE_NAME);
    const blockchain = new blockchainImplementation();
    if (!blockchain.getContract)
        throw new Foundations_1.NotImplementedError('Method not supported', constants_1.SERVICE_NAME);
    const metadata = await blockchain.getContract(contract, params);
    return { contract, metadata };
};
exports.getContract = getContract;
const callContractView = (blockchainImplementation) => async ({ body }) => {
    if (!blockchainImplementation)
        throw new Foundations_1.NotImplementedError('Method not supported', constants_1.SERVICE_NAME);
    const { contract, data } = body;
    if (!(0, cloud_library_1.isStringAndNonEmpty)(contract))
        throw new Foundations_1.BadRequestError('contract should be a non-empty string', constants_1.SERVICE_NAME);
    const blockchain = new blockchainImplementation();
    if (!blockchain.callContract)
        throw new Foundations_1.NotImplementedError('Method not supported', constants_1.SERVICE_NAME);
    const result = await blockchain.callContract(contract, data);
    return { data: result };
};
exports.callContractView = callContractView;
