import * as KeetaNet from '@keetanetwork/keetanet-client';
import { KeetaAnchorUserError } from '../../lib/error.js';
import { convertAssetLocationInputToCanonical } from './lib/location.js';
import { convertAssetSearchInputToCanonical } from '../../lib/asset.js';
import { assertKeetaAssetMovementAnchorAdditionalKYCNeededErrorJSONProperties, assertKeetaAssetMovementAnchorKYCShareNeededErrorJSONProperties, assertKeetaAssetMovementAnchorOperationNotSupportedErrorJSONProperties, assertKeetaAssetMovementAnchorUserActionNeededErrorJSONProperties } from './common.generated.js';
import { objectToSignable } from '../../lib/utils/signing.js';
export * from './lib/data/addresses/types.generated.js';
export * from './lib/location.js';
export * from './common.generated.js';
export { toEVMAsset, parseEVMAsset, isEVMAsset, toTronAsset, parseTronAsset, isTronAsset, toSolanaAsset, parseSolanaAsset, isSolanaAsset, convertAssetSearchInputToCanonical, isExternalChainAsset } from '../../lib/asset.js';
;
;
export function commonJSONStringify(input) {
    return (JSON.stringify(input, function (_, value) {
        if (typeof value === 'bigint') {
            return (String(value));
        }
        else if (KeetaNet.lib.Account.isInstance(value)) {
            return (value.publicKeyString.get());
        }
        return (value);
    }));
}
function isAssetPairLike(input) {
    return (typeof input === 'object' && input !== null && 'from' in input && 'to' in input);
}
export function toAssetPair(input) {
    if (isAssetPairLike(input)) {
        return (input);
    }
    return ({ from: input, to: input });
}
export function convertAssetOrPairSearchInputToCanonical(input) {
    if (isAssetPairLike(input)) {
        return ({
            from: convertAssetSearchInputToCanonical(input.from),
            to: convertAssetSearchInputToCanonical(input.to)
        });
    }
    else {
        return (convertAssetSearchInputToCanonical(input));
    }
}
export function getKeetaAssetMovementAnchorInitiateTransferRequestSigningData(input) {
    return (objectToSignable({
        asset: convertAssetOrPairSearchInputToCanonical(input.asset),
        from: { location: convertAssetLocationInputToCanonical(input.from.location) },
        to: { location: convertAssetLocationInputToCanonical(input.to.location), recipient: input.to.recipient, depositMessage: input.to.depositMessage },
        value: String(input.value)
    }));
}
export function getKeetaAssetMovementAnchorSimulateTransferRequestSigningData(input) {
    return (getKeetaAssetMovementAnchorInitiateTransferRequestSigningData(input));
}
export function getKeetaAssetMovementAnchorExecuteTransferRequestSigningData(input) {
    return (objectToSignable({
        id: input.id,
        instruction: input.instruction
    }));
}
export function getKeetaAssetMovementAnchorGetTransferStatusRequestSigningData(input) {
    return (['get-transaction', input.id]);
}
export function getKeetaAssetMovementAnchorInitiatePersistentForwardingAddressTemplateRequestSigningData(input) {
    const pair = toAssetPair(input.asset);
    return (objectToSignable({
        asset: { from: convertAssetSearchInputToCanonical(pair.from), to: convertAssetSearchInputToCanonical(pair.to) },
        location: convertAssetLocationInputToCanonical(input.location)
    }));
}
export function getKeetaAssetMovementAnchorCreatePersistentForwardingAddressTemplateRequestSigningData(input) {
    if ('data' in input) {
        return (objectToSignable({
            id: input.id,
            data: input.data
        }));
    }
    const pair = toAssetPair(input.asset);
    return (objectToSignable({
        asset: { from: convertAssetSearchInputToCanonical(pair.from), to: convertAssetSearchInputToCanonical(pair.to) },
        location: convertAssetLocationInputToCanonical(input.location),
        address: input.address
    }));
}
export function getKeetaAssetMovementAnchorListForwardingAddressTemplateRequestSigningData(_ignore_input) {
    return (['list-templates']);
}
export function getKeetaAssetMovementAnchorCreatePersistentForwardingRequestSigningData(input) {
    return (objectToSignable({
        sourceLocation: convertAssetLocationInputToCanonical(input.sourceLocation),
        asset: convertAssetOrPairSearchInputToCanonical(input.asset),
        outgoingRail: input.outgoingRail,
        ...('destinationLocation' in input ? {
            destinationLocation: convertAssetLocationInputToCanonical(input.destinationLocation),
            destinationAddress: input.destinationAddress
        } : {
            persistentAddressTemplateId: input.persistentAddressTemplateId
        })
    }));
}
export function getKeetaAssetMovementAnchorListPersistentForwardingRequestSigningData(_ignore_input) {
    return (['list-persistent-forwarding-addresses']);
}
export function getKeetaAssetMovementAnchorlistTransactionsRequestSigningData(_ignore_input) {
    return (['list-transactions']);
}
export function getKeetaAssetMovementAnchorShareKYCRequestSigningData(_ignore_input) {
    return (['share-kyc']);
}
class KeetaAssetMovementAnchorKYCShareNeededError extends KeetaAnchorUserError {
    static name = 'KeetaAssetMovementAnchorKYCShareNeededError';
    KeetaAssetMovementAnchorKYCShareNeededErrorObjectTypeID;
    static KeetaAssetMovementAnchorKYCShareNeededErrorObjectTypeID = '3f4d6acd-8915-40de-94fa-4c6c48c01623';
    shareWithPrincipals;
    neededAttributes;
    tosFlow;
    acceptedIssuers;
    constructor(args, message) {
        super(message ?? 'User Not Onboarded to Asset Movement Service');
        this.statusCode = 403;
        Object.defineProperty(this, 'KeetaAssetMovementAnchorKYCShareNeededErrorObjectTypeID', {
            value: KeetaAssetMovementAnchorKYCShareNeededError.KeetaAssetMovementAnchorKYCShareNeededErrorObjectTypeID,
            enumerable: false
        });
        this.neededAttributes = args.neededAttributes;
        this.tosFlow = args.tosFlow;
        this.shareWithPrincipals = args.shareWithPrincipals;
        this.acceptedIssuers = args.acceptedIssuers;
    }
    static isInstance(input) {
        return (this.hasPropWithValue(input, 'KeetaAssetMovementAnchorKYCShareNeededErrorObjectTypeID', KeetaAssetMovementAnchorKYCShareNeededError.KeetaAssetMovementAnchorKYCShareNeededErrorObjectTypeID));
    }
    asErrorResponse(contentType) {
        const { tosFlow, neededAttributes, shareWithPrincipals, acceptedIssuers } = this.toJSON();
        let message = this.message;
        if (contentType === 'application/json') {
            message = JSON.stringify({
                ok: false,
                name: this.name,
                code: 'KEETA_ANCHOR_ASSET_MOVEMENT_KYC_SHARE_NEEDED',
                data: { tosFlow, neededAttributes, shareWithPrincipals, acceptedIssuers },
                error: this.message
            });
        }
        return ({
            error: message,
            statusCode: this.statusCode,
            contentType: contentType
        });
    }
    toJSON() {
        return ({
            ...super.toJSON(),
            tosFlow: this.tosFlow,
            neededAttributes: this.neededAttributes,
            shareWithPrincipals: this.shareWithPrincipals.map(function (account) {
                return (account.publicKeyString.get());
            }),
            acceptedIssuers: this.acceptedIssuers
        });
    }
    static async fromJSON(input) {
        const { message, other } = this.extractErrorProperties(input, this);
        if (!('data' in other)) {
            throw (new Error('Invalid KeetaAssetMovementAnchorKYCShareNeededError JSON: missing data property'));
        }
        const parsed = assertKeetaAssetMovementAnchorKYCShareNeededErrorJSONProperties(other.data);
        const error = new this({
            shareWithPrincipals: parsed.shareWithPrincipals.map(function (pubKeyString) {
                return (KeetaNet.lib.Account.fromPublicKeyString(pubKeyString).assertAccount());
            }),
            neededAttributes: parsed.neededAttributes,
            tosFlow: parsed.tosFlow,
            acceptedIssuers: parsed.acceptedIssuers
        }, message);
        error.restoreFromJSON(other);
        return (error);
    }
}
class KeetaAssetMovementAnchorAdditionalKYCNeededError extends KeetaAnchorUserError {
    static name = 'KeetaAssetMovementAnchorAdditionalKYCNeededError';
    KeetaAssetMovementAnchorAdditionalKYCNeededErrorObjectTypeID;
    static KeetaAssetMovementAnchorAdditionalKYCNeededErrorObjectTypeID = '3f4d6acd-8915-40de-94fa-4c6c48c01623';
    toCompleteFlow;
    constructor(args, message) {
        super(message ?? 'User requires additional KYC to proceed with asset movement');
        this.statusCode = 403;
        Object.defineProperty(this, 'KeetaAssetMovementAnchorAdditionalKYCNeededErrorObjectTypeID', {
            value: KeetaAssetMovementAnchorAdditionalKYCNeededError.KeetaAssetMovementAnchorAdditionalKYCNeededErrorObjectTypeID,
            enumerable: false
        });
        this.toCompleteFlow = args.toCompleteFlow;
    }
    static isInstance(input) {
        return (this.hasPropWithValue(input, 'KeetaAssetMovementAnchorAdditionalKYCNeededErrorObjectTypeID', KeetaAssetMovementAnchorAdditionalKYCNeededError.KeetaAssetMovementAnchorAdditionalKYCNeededErrorObjectTypeID));
    }
    asErrorResponse(contentType) {
        const { toCompleteFlow } = this.toJSON();
        let message = this.message;
        if (contentType === 'application/json') {
            message = JSON.stringify({
                ok: false,
                name: this.name,
                code: 'KEETA_ANCHOR_ASSET_MOVEMENT_ADDITIONAL_KYC_NEEDED',
                data: { toCompleteFlow },
                error: this.message
            });
        }
        return ({
            error: message,
            statusCode: this.statusCode,
            contentType: contentType
        });
    }
    toJSON() {
        return ({
            ...super.toJSON(),
            toCompleteFlow: this.toCompleteFlow
        });
    }
    static async fromJSON(input) {
        const { message, other } = this.extractErrorProperties(input, this);
        if (!('data' in other)) {
            throw (new Error('Invalid KeetaAssetMovementAnchorAdditionalKYCNeededError JSON: missing data property'));
        }
        const parsed = assertKeetaAssetMovementAnchorAdditionalKYCNeededErrorJSONProperties(other.data);
        const error = new this({
            toCompleteFlow: parsed.toCompleteFlow
        }, message);
        error.restoreFromJSON(other);
        return (error);
    }
}
class KeetaAssetMovementAnchorOperationNotSupportedError extends KeetaAnchorUserError {
    static name = 'KeetaAssetMovementAnchorOperationNotSupportedError';
    KeetaAssetMovementAnchorOperationNotSupportedErrorObjectTypeID;
    static KeetaAssetMovementAnchorOperationNotSupportedErrorObjectTypeID = 'b613cd80-57ac-4be5-ad4a-bb8644d50de6';
    forAsset;
    forRail;
    constructor(args, message) {
        super(message ?? `Operation not supported`);
        this.statusCode = 400;
        Object.defineProperty(this, 'KeetaAssetMovementAnchorOperationNotSupportedErrorObjectTypeID', {
            value: KeetaAssetMovementAnchorOperationNotSupportedError.KeetaAssetMovementAnchorOperationNotSupportedErrorObjectTypeID,
            enumerable: false
        });
        this.forAsset = args.forAsset;
        this.forRail = args.forRail;
    }
    static isInstance(input) {
        return (this.hasPropWithValue(input, 'KeetaAssetMovementAnchorOperationNotSupportedErrorObjectTypeID', KeetaAssetMovementAnchorOperationNotSupportedError.KeetaAssetMovementAnchorOperationNotSupportedErrorObjectTypeID));
    }
    asErrorResponse(contentType) {
        const { forAsset, forRail } = this.toJSON();
        let message = this.message;
        if (contentType === 'application/json') {
            message = JSON.stringify({
                ok: false,
                name: this.name,
                code: 'KEETA_ANCHOR_ASSET_MOVEMENT_OPERATION_NOT_SUPPORTED',
                data: { forAsset, forRail },
                error: this.message
            });
        }
        return ({
            error: message,
            statusCode: this.statusCode,
            contentType: contentType
        });
    }
    toJSON() {
        return ({
            ...super.toJSON(),
            forRail: this.forRail,
            forAsset: this.forAsset ? convertAssetOrPairSearchInputToCanonical(this.forAsset) : undefined
        });
    }
    static async fromJSON(input) {
        const { message, other } = this.extractErrorProperties(input, this);
        if (!('data' in other)) {
            throw (new Error('Invalid KeetaAssetMovementAnchorOperationNotSupportedError JSON: missing data property'));
        }
        const parsed = assertKeetaAssetMovementAnchorOperationNotSupportedErrorJSONProperties(other.data);
        const error = new this({
            forAsset: parsed.forAsset,
            forRail: parsed.forRail
        }, message);
        error.restoreFromJSON(other);
        return (error);
    }
}
class KeetaAssetMovementAnchorUserActionNeededError extends KeetaAnchorUserError {
    static name = 'KeetaAssetMovementAnchorUserActionNeededError';
    KeetaAssetMovementAnchorUserActionNeededErrorObjectTypeID;
    static KeetaAssetMovementAnchorUserActionNeededErrorObjectTypeID = 'f2160fd8-a1d3-4a6d-ae22-da0dd642c44e';
    actionsNeeded;
    constructor(args, message) {
        super(message ?? `Actions are needed to perform operation`);
        this.statusCode = 400;
        Object.defineProperty(this, 'KeetaAssetMovementAnchorUserActionNeededErrorObjectTypeID', {
            value: KeetaAssetMovementAnchorUserActionNeededError.KeetaAssetMovementAnchorUserActionNeededErrorObjectTypeID,
            enumerable: false
        });
        this.actionsNeeded = args.actionsNeeded;
    }
    static #parseJSONActions(actions) {
        return (actions.map(function (action) {
            const shared = {
                ...(action.details ? { details: action.details } : {})
            };
            if (action.type === 'add-certificate') {
                return ({
                    ...shared,
                    type: action.type,
                    ...(action.account ? { account: KeetaNet.lib.Account.fromPublicKeyString(action.account).assertAccount() } : {}),
                    certificate: new KeetaNet.lib.Utils.Certificate.Certificate(action.certificate),
                    ...(action.intermediates ? {
                        intermediates: action.intermediates.map(function (cert) {
                            return (new KeetaNet.lib.Utils.Certificate.Certificate(cert));
                        })
                    } : {})
                });
            }
            else if (action.type === 'grant-permission') {
                return ({
                    ...shared,
                    type: action.type,
                    permissionToGrant: {
                        principal: KeetaNet.lib.Account.fromPublicKeyString(action.permissionToGrant.principal),
                        ...(action.permissionToGrant.entity ? { entity: KeetaNet.lib.Account.fromPublicKeyString(action.permissionToGrant.entity) } : {}),
                        ...(action.permissionToGrant.target ? { target: KeetaNet.lib.Account.fromPublicKeyString(action.permissionToGrant.target) } : {}),
                        permissions: new KeetaNet.lib.Permissions(BigInt(action.permissionToGrant.permissions[0]), BigInt(action.permissionToGrant.permissions[1]))
                    }
                });
            }
            else {
                throw (new Error('Unsupported action type'));
            }
        }));
    }
    static isInstance(input) {
        return (this.hasPropWithValue(input, 'KeetaAssetMovementAnchorUserActionNeededErrorObjectTypeID', KeetaAssetMovementAnchorUserActionNeededError.KeetaAssetMovementAnchorUserActionNeededErrorObjectTypeID));
    }
    asErrorResponse(contentType) {
        const { actionsNeeded } = this.toJSON();
        let message = this.message;
        if (contentType === 'application/json') {
            message = JSON.stringify({
                ok: false,
                name: this.name,
                code: 'KEETA_ANCHOR_ASSET_MOVEMENT_USER_ACTION_NEEDED',
                data: { actionsNeeded },
                error: this.message
            });
        }
        return ({
            error: message,
            statusCode: this.statusCode,
            contentType: contentType
        });
    }
    static addOperationsToBuilder(actions, builder) {
        for (const action of actions) {
            if (action.type === 'add-certificate') {
                let intermediates;
                if (action.intermediates) {
                    intermediates = new KeetaNet.lib.Utils.Certificate.CertificateBundle(action.intermediates);
                }
                builder.modifyCertificate(KeetaNet.lib.Block.AdjustMethod.ADD, action.certificate, intermediates, action.account ? { account: action.account } : undefined);
            }
            else if (action.type === 'grant-permission') {
                builder.updatePermissions(action.permissionToGrant.principal, action.permissionToGrant.permissions, action.permissionToGrant.target, KeetaNet.lib.Block.AdjustMethod.ADD, action.permissionToGrant.entity ? { account: action.permissionToGrant.entity } : {});
            }
        }
    }
    toJSON() {
        return ({
            ...super.toJSON(),
            actionsNeeded: this.actionsNeeded.map(function (action) {
                const shared = {
                    ...(action.details ? { details: action.details } : {})
                };
                if (action.type === 'add-certificate') {
                    return ({
                        ...shared,
                        type: action.type,
                        ...(action.account ? { account: action.account.publicKeyString.get() } : {}),
                        certificate: action.certificate.toPEM(),
                        ...(action.intermediates ? { intermediates: action.intermediates.map(function (cert) {
                                return (cert.toPEM());
                            }) } : {})
                    });
                }
                else if (action.type === 'grant-permission') {
                    return ({
                        ...shared,
                        type: action.type,
                        permissionToGrant: {
                            principal: action.permissionToGrant.principal.publicKeyString.get(),
                            ...(action.permissionToGrant.entity ? { entity: action.permissionToGrant.entity.publicKeyString.get() } : {}),
                            ...(action.permissionToGrant.target ? { target: action.permissionToGrant.target.publicKeyString.get() } : {}),
                            permissions: [String(action.permissionToGrant.permissions.base.bigint), String(action.permissionToGrant.permissions.external.bigint)]
                        }
                    });
                }
                else {
                    throw (new Error('Unsupported action type'));
                }
            })
        });
    }
    static async fromJSON(input) {
        const { message, other } = this.extractErrorProperties(input, this);
        if (!('data' in other)) {
            throw (new Error('Invalid KeetaAssetMovementAnchorUserActionNeededError JSON: missing data property'));
        }
        const parsed = assertKeetaAssetMovementAnchorUserActionNeededErrorJSONProperties(other.data);
        const error = new this({ actionsNeeded: this.#parseJSONActions(parsed.actionsNeeded) }, message);
        error.restoreFromJSON(other);
        return (error);
    }
}
export const Errors = {
    /**
     * The user is required to share KYC details
     */
    KYCShareNeeded: KeetaAssetMovementAnchorKYCShareNeededError,
    /**
     * The user is required to complete additional KYC steps
     */
    AdditionalKYCNeeded: KeetaAssetMovementAnchorAdditionalKYCNeededError,
    /**
     * The requested operation is not supported
     */
    OperationNotSupported: KeetaAssetMovementAnchorOperationNotSupportedError,
    /**
     * An action is required by the user to complete the requested operation
     */
    UserActionNeeded: KeetaAssetMovementAnchorUserActionNeededError
};
//# sourceMappingURL=common.js.map