FDC3 Compliance

Overview

FDC3 aims at developing specific protocols and classifications in order to advance the ability of desktop apps in financial workflows to interoperate in a plug-and-play fashion without prior bilateral agreements.

FDC3 for io.Connect Desktop

io.Connect Desktop supports fully the FDC3 2.0 standards.

The following sections explain the specifics for running FDC3-compliant apps within io.Connect Desktop and using the @interopio/fdc3 library which provides an io.Connect implementation of the FDC3 standards. For more detailed information on the FDC3 standards and APIs, see the FDC3 documentation.

App Definition

To use your FDC3-compliant app in io.Connect Desktop, you must create an app definition file for it.

The following example demonstrates a minimal configuration for an interop-enabled app:

{
    "title": "My FDC3 App",
    "type": "window",
    "name": "my-fdc3-app",
    "details": {
        "url": "https://my-fdc3-app.com",
        "height": 800,
        "width": 600
    }
}

For more information on configuring your apps for io.Connect Desktop, see the Developers > Configuration > Application section.

io.Connect Desktop can also fetch FDC3 app definitions from a remote FDC3 app store. In this case, io.Connect Desktop automatically converts the FDC3 app definitions to io.Connect ones, preserving the original FDC3 app definition in a top-level "fdc3" property added to the resulting io.Connect app definition.

For more details on the FDC3 app definition standards, see the FDC3 Application schema.

FDC3 Implementations

Implementations of the FDC3 API are available for:

JavaScript

The @interopio/fdc3 library provides an io.Connect implementation of the FDC3 standards and can be either automatically injected in your app, or installed and imported manually. In either case, it's important to consider that the io.Connect FDC3 API implementation depends on the @interopio/desktop library which must be initialized with the appropriate settings in order for the @interopio/fdc3 library to function properly.

Direct Usage

To manually install the @interopio/fdc3 library, execute the following command:

npm install @interopio/fdc3

To use the @interopio/fdc3 library in your apps, import it and initialize the @interopio/desktop library with the following configuration:

import IODesktop from "@interopio/desktop";
import "@interopio/fdc3";

const config = {
    // This is needed for the default Intents Resolver UI app to work properly.
    appManager: "full",
    // This is necessary in order to use the FDC3 Channels.
    channels: true
};

await IODesktop(config);

⚠️ Note that the @interopio/desktop library can also be auto injected and auto initialized through system configuration or app definition. For more details, see the How to Interop-Enable Your Apps > JavaScript section.

Auto Injection

When auto injecting the @interopio/fdc3 library, it isn't necessary to install, auto inject or initialize the @interopio/desktop library, on which it depends, as io.Connect Desktop does this automatically without the need for explicit configuration.

For details on how to specify auto injection settings for FDC3 apps fetched from a remote app store, see the App Directory section.

To specify global settings for auto injecting the @interopio/fdc3 library, use the "autoInjectFdc3" property under the "windows" top-level key in the system.json system configuration of io.Connect Desktop located in %LocalAppData%/interop.io/io.Connect Desktop/Desktop/config.

The following example demonstrates how to specify settings for injecting the @interopio/fdc3 library for all apps:

{
    "windows": {
        "autoInjectFdc3": {
            "enabled": true,
            "library": {
                "source": "https://my-fdc3-library/umd.min.js",
                "fallback": "2.*",
                "timeout": 5000
            }
        }
    }
}

The "autoInjectFdc3" object has the following properties:

Property Type Description
"allowed" string[] List of io.Connect app names in which the @interopio/fdc3 library will be injected.
"blocked" string[] List of io.Connect app names in which the @interopio/fdc3 library won't be injected.
"enabled" boolean Required. If true, will enable auto injecting the @interopio/fdc3 library.
"library" object Settings for the @interopio/fdc3 library to be injected.

The "library" object has the following properties:

Property Type Description
"fallback" string Fallback location of the @interopio/fdc3 library in case the one specified in the "source" property doesn't load. Accepts a URL pointing to a locally or remotely hosted @interopio/fdc3 library, or a string specifying the version of the @interopio/fdc3 library to be used from the locally available packages in the %LocalAppData%/interop.io/io.Connect Desktop/Desktop/assets folder.
"source" string URL pointing to a locally or remotely hosted @interopio/fdc3 library, or a string specifying the version of the @interopio/fdc3 library to be used from the locally available packages in the %LocalAppData%/interop.io/io.Connect Desktop/Desktop/assets folder.
"timeout" number Interval in milliseconds to wait for loading the @interopio/fdc3 library.

After injection, the FDC3 API will be available as an fdc3 object attached to the global window object:

const contextType = "Contact";
const handler = context => console.log(`Context: ${JSON.stringify(context)}`);

await fdc3.addContextListener(contextType, handler);

You can override the settings for injecting the @interopio/fdc3 library per app from the app definition by using the "autoInjectFdc3" property of the "details" top-level key.

The following example demonstrates how to disable injecting the @interopio/fdc3 for an app:

{
    "title": "My Non-FDC3 App",
    "type": "window",
    "name": "my-non-fdc3-app",
    "details": {
        "url": "https://my-non-fdc3-app.com",
        "autoInjectFdc3": {
            "enabled": false
        }
    }
}

.NET

Available since io.Connect Desktop 9.3

io.Connect .NET implementations of the FDC3 standards are available for .NET Standard and .NET Framework on NuGet.

Both .NET FDC3 libraries depend on the respective io.Connect .NET library, provide identical APIs that strictly follow the FDC3 standards, and are initialized in the same way.

⚠️ Note that the .NET FDC3 library for .NET Standard depends on the io.Connect .NET library for .NET Standard which is meant to provide cross-platform support (e.g., for Android, Linux, Blazor) and doesn't work with window handles. This means that if you want to register you .NET FDC3 apps as io.Connect Windows, you must also include the io.Connect .NET library for .NET 5+ as a dependency in your project.

To initialize the .NET FDC3 libraries, invoke the DesktopAgent() constructor which accepts as a required argument an initialized instance of the io.Connect .NET library. The following example demonstrates basic initialization of the .NET FDC3 library:

// Initialize the io.Connect .NET library or provide an already initialized instance.
Glue42 io = await Glue42.InitializeGlue();

// Creating a Desktop Agent.
DesktopAgent desktopAgent = new DesktopAgent(io);

⚠️ Note that both io.Connect .NET FDC3 implementations follow strictly the FDC3 API standards. For examples on using the FDC3 APIs, see the FDC3 official documentation.

When initializing the io.Connect .NET FDC3 libraries, you can provide an optional configuration for your Desktop Agent. This configuration is outside the scope of the FDC3 standards and its purpose is to enable finer tuning of the library behavior. You can specify a Dispatcher to be used, whether your app will receive its own context updates, and you can also load custom contexts that aren't defined in the FDC3 standards:

// Defining a custom context that must inherit the necessary library classes.
public class NewCustomFDC3Context :
    Finos.Fdc3.Context.Context<NewCustomFDC3Context.CustomID>,
    IContext,
    IContext<object>,
    IIntentResult,
    IDynamicContext
{
    public class CustomID
    {
        public string? PROP1 { get; set; }
        public string? PROP2 { get; set; }
        public string? PROP3 { get; set; }

    }

    public NewCustomFDC3Context(CustomID? id = null, string? name = null)
        : base("fdc3.new.custom", id, name)
    {
    }

    object? IContext<object>.ID => (object)this.ID;
}

// Initialize the .NET io.Connect library or provide an already initialized instance.
Glue42 io = await Glue42.InitializeGlue();

// Optional Desktop Agent configuration.
var configuration = new DesktopAgent.Configuration
{
    // Providing a `Dispatcher`.
    Dispatcher = new GlueDispatcher(Dispatcher.CurrentDispatcher),
    // Enabling your app to receive its own context updates.
    HearOwnBroadcasts = true,
    // Describe how your custom context is loaded.
    ContextLoader = loader =>
    {
        loader.AddLoader<NewCustomFDC3Context>((prop, value) =>
        {
            // You can add custom logic based on the raw value.

            // Creating an instance of the context using the property loader to avoid typos.
            // The rest of the properties will be loaded automatically using reflection.
            return new NewCustomFDC3Context(prop.Load(c => c.ID), prop.Load(c => c.Name));
        });
    }
};

DesktopAgent desktopAgent = new DesktopAgent(io, configuration);

Intents

The FDC3 Intents concept serves the purpose of enabling the creation of cross-app workflows on the desktop. An app declares an Intent through configuration or at runtime. An Intent specifies what action the app can execute and with what data structure it can work.

Intents can be defined both in the "intents" top-level array of an io.Connect app definition file, or using the "intents" property in an FDC3 app definition file.

The following example demonstrates how to define an Intent in the configuration of an interop-enabled app:

{
    "intents": [
        {
            "name": "ShowChart",
            "displayName": "BBG Instrument Chart",
            "contexts": ["Instrument"]
        }
    ]
}
Property Description
"name" Required. The name of the Intent.
"displayName" The display name of the Intent. Can be used in context menus, etc., to visualize the Intent.
"contexts" The type of predefined data structures that the app can work with (see FDC3 Contexts).

For more details on using Intents, see the FDC3 Intents API.

The Intents Resolver UI app allows users to choose an app for handling a raised Intent:

Intents Resolver

For more details on how to enable or disable the Intents Resolver UI, or on how to create your own custom Intents Resolver App, see the Capabilities > Intents > Overview > Intents Resolver section.

Channels

An FDC3 Channel is a named context object that an app can join in order to share and update context data and also be alerted when the context data changes. By specification, Channels can be either well-known system Channels or Channels created by apps. On a UI level, Channels can be represented by colors and names.

All system defined Channels in io.Connect Desktop can be found in the channels.json file located in the %LocalAppData%/interop.io/io.Connect Desktop/Desktop/config folder. There you can define as many custom Channels as you need. For instance, to add a black Channel to the existing list of system Channels, add the following configuration:

{
    "name": "Black",
    "meta": {
        "color": "black"
    }
}

The default io.Connect Channels are mapped to the default FDC3 Channels. Any custom Channel you define, must be mapped to an FDC3 Channels if you want to use it as such.

For more details on defining Channels, Channel mapping and how to enable the Channel Selector for your apps, see the Developers > Configuration > Channels section.

To be able to use the FDC3 Channels, the @interopio/desktop library (on which the @interopio/fdc3 library depends) must be initialized with enabled io.Connect Channels.

For more details on using Channels, see the FDC3 Channels API.

App Directory

The goal of the FDC3 App Directory REST service is to provide trusted identity for desktop apps. App definitions are provided by one or more App Directory REST services where user entitlements and security can also be handled.

For more details on the FDC3 app definition standards, see the FDC3 Application schema.

To configure io.Connect Desktop to retrieve app definitions from remote app stores, add a new entry to the "appStores" top-level key in the system.json file located in the %LocalAppData%/interop.io/io.Connect Desktop/Desktop/config folder:

{
    "appStores": [
        {
            "type": "rest",
            "details": {
                "url": "https://example.com/my-app-store/",
                "auth": "no-auth",
                "pollInterval": 30000,
                "enablePersistentCache": true,
                "cacheFolder": "%LocalAppData%/interop.io/io.Connect Desktop/UserData/%GLUE-ENV%-%GLUE-REGION%/configCache/"
            }
        }
    ]
}

io.Connect Desktop automatically converts the retrieved FDC3 app definitions to io.Connect ones, preserving the original FDC3 app definition in a top-level "fdc3" property added to the resulting io.Connect app definition.

To be able to use the @interopio/fdc3 library in the FDC3 apps fetched from a remote store, you must override their definitions to enable auto injecting the @interopio/fdc3 library. To override the retrieved app definitions, use the "appDefinitionOverrides" property in the app store configuration object:

{
    "appStores": [
        {
            "type": "rest",
            "details": {
                "url": "https://example.com/my-app-store/",
                "auth": "no-auth",
                "pollInterval": 30000,
                "enablePersistentCache": true,
                "cacheFolder": "%LocalAppData%/interop.io/io.Connect Desktop/UserData/%GLUE-ENV%-%GLUE-REGION%/configCache/"
            },
            "appDefinitionOverrides": {
                // Overrides for the properties under the `"details"` top-level key in apps of type `"window"`.
                "window": {
                    // Settings for auto injecting the `@interopio/fdc3` library.
                    "autoInjectFdc3": {
                        "enabled": true,
                        "library": {
                            "source": "https://my-fdc3-library/umd.js",
                            "fallback": "2.*",
                            "timeout": 5000
                        }
                    }
                }
            }
        }
    ]
}

For more details on configuring remote app stores, see Capabilities > App Management > Overview > App Stores > Remote.

According to the FDC3 App Directory specifications, the remote store must return app definitions in the following response shape:

{
    "applications": [
        // List of app definition objects.
        {}, {}
    ]
}

For a reference implementation of the FDC3 App Directory, see the Node.js REST Config Example on GitHub.

For more details on using App Directory, see the FDC3 App Directory documentation.