{"id":51005372,"url":"https://github.com/interopio/finsemble-fdc3","last_synced_at":"2026-06-20T20:02:00.618Z","repository":{"id":51231278,"uuid":"269192381","full_name":"InteropIO/finsemble-fdc3","owner":"InteropIO","description":"FDC3 Implementation For Finsemble","archived":false,"fork":false,"pushed_at":"2021-06-11T21:36:14.000Z","size":447,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":7,"default_branch":"master","last_synced_at":"2023-06-29T15:39:55.715Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/InteropIO.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-03T20:53:08.000Z","updated_at":"2023-06-27T14:25:39.000Z","dependencies_parsed_at":"2022-08-27T00:42:50.457Z","dependency_job_id":null,"html_url":"https://github.com/InteropIO/finsemble-fdc3","commit_stats":null,"previous_names":["interopio/finsemble-fdc3"],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/InteropIO/finsemble-fdc3","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InteropIO%2Ffinsemble-fdc3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InteropIO%2Ffinsemble-fdc3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InteropIO%2Ffinsemble-fdc3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InteropIO%2Ffinsemble-fdc3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/InteropIO","download_url":"https://codeload.github.com/InteropIO/finsemble-fdc3/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InteropIO%2Ffinsemble-fdc3/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34583589,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-20T20:01:55.079Z","updated_at":"2026-06-20T20:02:00.605Z","avatar_url":"https://github.com/InteropIO.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Finsemble FDC3 1.1\n\n- [Finsemble FDC3 1.1](#finsemble-fdc3-11)\n- [Intro to FDC3](#intro-to-fdc3)\n- [Getting Started](#getting-started)\n  - [Installation](#installation)\n    - [Quick Install Steps](#quick-install-steps)\n  - [Using FDC3 in Finsemble](#using-fdc3-in-finsemble)\n    - [FDC3 in Finsemble Components](#fdc3-in-finsemble-components)\n      - [Component Config](#component-config)\n        - [Preload](#preload)\n        - [Toolbar Icon URL](#toolbar-icon-url)\n        - [FDC3 configuration](#fdc3-configuration)\n    - [FDC3 in Finsemble Services](#fdc3-in-finsemble-services)\n  - [API](#api)\n    - [App](#app)\n    - [Context](#context)\n    - [Intents](#intents)\n    - [Channels](#channels)\n  - [Example use cases:](#example-use-cases)\n  - [FDC3 in Finsemble Dot-Net Components](#fdc3-in-finsemble-dot-net-components)\n    - [Dot-Net API](#dot-net-api)\n      - [Dot-Net App](#dot-net-app)\n      - [Dot-Net Context](#dot-net-context)\n      - [Dot-Net Intents](#dot-net-intents)\n      - [Dot-Net Channels](#dot-net-channels)\n\n# Intro to FDC3\n\nWelcome to the Finsemble FDC3 implementation. For those not familiar with FDC3 here is a summary taken from their\ncharter:\n\n\u003e The mission of the Financial Desktop Connectivity and Collaboration Consortium (FDC3) is to develop specific protocols\n\u003e and taxonomies to advance the ability of desktop applications in financial workflows to interoperate in a\n\u003e plug-and-play fashion, without prior bi-lateral agreements. They aim to do this by\n\nThe FDC3 revolves around a few core concepts; Apps, Intents and Context. Apps - These are the applications that\nparticipate in FDC3. You can launch these applications and send data. Intents - These are the verbs, what you would like\nto do e.g. _Launch a chart application_ Context - The noun, this is the data you want to share with other applications,\nthey will in turn use this.\n\nA good example putting all this together looks like this:\n\n\u003e Open (_intent_) a Chart (_app_) and send an instrument (_context_).\n\nThe Finsemble FDC3 implementation is comprised of four parts:\n\n- Component Config\n- Preload\n- Client\n- Service\n\n# Getting Started\n\n## Installation\n\nBy following the 6 steps below you will be able to start working with FDC3 inside your Finsemble Components / Services.\n\n**How it works:**\n\nThe project's watch script monitors the project for any changes in the _src_ directory or config file. When folders or\nfiles are updated, added or removed the change will automatically be reflected in the Finsemble Seed Project. Source\nfiles are from this project's _src_ directory are synced to matching locations in the Finsemble Seed project, while the\ncontent of the _finsemble.config.json_ file is added to the seed project's _configs/application/config.json_ file.\n\n#### Quick Install Steps\n\n1. Clone the Finsemble [seed-project](https://github.com/ChartIQ/finsemble-seed) (if you don't already have a local\n   version - see our [Getting Started Tutorial](https://www.chartiq.com/tutorials/?slug=finsemble))\n2. `npm install react-syntax-highlighter @types/react @types/react-syntax-highlighter` in the seed project\n3. Clone this repo\n   - **our advice:** clone this repo to the same directory as the seed-project e.g _myfolder/finsemble-seed_ \u0026\n     _myfolder/finsemble-fdc3_\n4. If you clone in a different location, open **finsemble.config.json** and update `seedProjectDirectory` with the path\n   to your local Finsemble Seed Project.\n5. Inside this project run `npm install` then run `npm run watch` **Note:** The watch script will continue to monitor\n   this project for file changes. If you do not need it to, it can be stopped once all the files have been copied to the\n   seed project (which takes approx. 30 seconds).\n6. Follow the instructions on how to add the FDC3 to your [Component](###-FDC3-in-Finsemble-Components) /\n   [Service](###FDC3-in-Finsemble-Services):\n\n## Using FDC3 in Finsemble\n\nThe Finsemble implementation of the FDC3 DesktopAgent and Channels APIs can be used in both Finsemble Components and\nServices.\n\n### FDC3 in Finsemble Components\n\nThe FDC3 client is most easily made available to your components via preload, which will give your component access to\nit as if it were any other Finsemble client. It is anticipated that later versions of Finsemble will include the FDC3\nclient by default.\n\n#### Component Config\n\nTo use the FDC3 client in your component, you will need to make 3 additions to your component's configuration:\n\n- Preload the client,\n- Ensure that you have a Toolbar Icon URL set\n- Add FDC3 specific configuration\n\n##### Preload\n\nTo add the FDC3 preload to your component, set `component.preload` in its configuration to the path to the built preload\nscript, e.g. `\"$applicationRoot/preloads/FDC3Client.js\"`, or if using multiple preload scripts add it to an array of\ntheir paths (see the config example below).\n\n##### Toolbar Icon URL\n\nThe icon url is used by the intent resolver to display the logo of your component. This URL can use the\n`$applicationRoot` variable to set a local path or can be an external URL. Supported formats: `.jpg`, `.png`, `.svg`.\n\n##### FDC3 configuration\n\nAn additional section in your component config, `foreign.services.fdc3`, is used to specify intents and associated\ncontext types that your component can accept. See the section **fdc3** in the example below.\n\nExample:\n\n```\n{\n  \"FDC3 Component\": {\n    \"window\": {},\n    \"component\": {\n      \"preload\": [\n        \"$applicationRoot/preloads/FDC3Client.js\"\n\t\t\t\t]\n    },\n    \"foreign\": {\n      \"services\": {\n        \"fdc3\": {\n          \"intents\": [\n            {\n              \"name\": \"StartCall\",\n              \"displayName\": \"Call\",\n              \"contexts\": [\n                \"fdc3.contact\"\n              ]\n            }\n          ]\n        }\n      },\n      \"components\": {\n        \"Toolbar\": {\n          \"iconURL\": \"$applicationRoot/assets/img/Finsemble_Taskbar_Icon.png\"\n        }\n      }\n    }\n  }\n}\n```\n\n### FDC3 in Finsemble Services\n\nThe Finsemble FDC3 client may also be used in Finsemble services, where it is imported into the service implementation.\nPlease see our [exampleFDC3Service](./src/services/testFDC3) for an example of how to structure your service to work\nwith FDC3.\n\n## API\n\nPlease note that the FINOS FDC3 website provides documentation for the\n[Desktop Agent](https://fdc3.finos.org/docs/1.1/api/ref/DesktopAgent) and\n[Channel](https://fdc3.finos.org/docs/1.1/api/ref/Channel) APIs. The main API calls are also detailed here for\nconvenience.\n\n### App\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n  \u003cth\u003eAPI\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003cth\u003eExample\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n  \u003ctd\u003e \u003ccode\u003eopen(name: string, context?: Context): Promise\u0026lt;void\u003e\u003c/code\u003e \u003c/td\u003e\n  \u003ctd\u003eOpen a component and optionally send context for it to use. Name relates to a Finsemble Component type such as \"Welcome Component\"\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003efdc3.open('ChartIQ Chart')\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003cbr/\u003e\n\n### Context\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n  \u003cth\u003eAPI\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003cth\u003eExample\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n  \u003ctd\u003e\u003ccode\u003ebroadcast(context: Context): void\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eSend context to the channel the app is currently join to. We default applications to join on the Global Channel.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003efdc3.broadcast({\n        type: 'fdc3.instrument',\n        name: 'Microsoft',\n        id: {\n                ticker: 'MSFT'\n        }\n})\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n  \u003ctd\u003e\n  \u003ccode\u003eaddContextListener(handler: ContextHandler): Listener;\n  addContextListener(contextType: string, handler: ContextHandler): Listener;\u003c/code\u003e\n  \u003c/td\u003e\n  \u003ctd\u003eListen to broadcast context on the channel the app is currently join to. We default applications to join on the Global Channel.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003efdc3.addContextListener({\n        type: 'fdc3.instrument',\n        name: 'Microsoft',\n        id: {\n                ticker: 'MSFT'\n        }\n},context =\u003e {context.type === 'fdc3.instrument'})\u003c/code\u003e \u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003cbr/\u003e\n\n### Intents\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n  \u003cth\u003eAPI\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003cth\u003eExample\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n  \u003ctd\u003e\u003ccode\u003efindIntent(intent: string, context?: Context): Promise\u0026lt;AppIntent\u003e;\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eList all the applications that can deal with a certain intent.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003efdc3.findIntent(\"ViewChart\")\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n  \u003ctd\u003e\u003ccode\u003efindIntentsByContext(context: Context): Promise\u0026lt;Array\u0026lt;AppIntent\u003e\u003e;\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eList all the applications that can deal with a certain context.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003efdc3.findIntentsByContext({ type: \"fdc3.instrument\" })\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n  \u003ctd\u003e\u003ccode\u003eraiseIntent(intent: string, context: Context, target?: string): Promise\u003cIntentResolution\u003e;\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eOpen an application by name and optionally pass context to be used by that app.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003efdc3.raiseIntent(\"ViewInstrument\", {\n        type: 'fdc3.instrument',\n        name: 'Microsoft',\n        id: {\n                ticker: 'MSFT'\n        }\n});\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n  \u003ctd\u003e\u003ccode\u003eaddIntentListener(intent: string, handler: ContextHandler): Listener;\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eAdd this to your component so that it can action intents when they are sent.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003efdc3.addIntentListener(\n\"ViewChart\",\ncontext =\u003e { //do something here  }\n)\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003cbr/\u003e\n\n### Channels\n\nThe DesktopAgent API will allow you to join, listen to and broadcast context to a single 'channel' via its API. However,\nyou can also interact directly with FDC3 channels, which have the following interface:\n\n```javascript\ninterface Channel {\n\t// properties\n\tid: string;\n\ttype: string;\n\tdisplayMetadata?: DisplayMetadata;\n\n\t// methods\n\tbroadcast(context: Context): void;\n\tgetCurrentContext(contextType?: string): Promise\u003cContext | null\u003e;\n\taddContextListener(handler: ContextHandler): Listener;\n\taddContextListener(contextType: string, handler: ContextHandler): Listener;\n}\n```\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n  \u003cth\u003eAPI\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003cth\u003eExample\u003c/th\u003e\n\u003c/tr\u003e\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n  \u003ctd\u003e \u003ccode\u003e getOrCreateChannel(channelId: string): Promise\u0026lt;Channel\u003e\u003c/code\u003e \u003c/td\u003e\n  \u003ctd\u003eIf the channel does not exist it will be created.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003efdc3.getOrCreateChannel(\"channel1\")\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003e \u003ccode\u003egetSystemChannels(): Promise\u0026lt;Array\u0026lt;Channel\u003e\u003e\u003c/code\u003e \u003c/td\u003e\n  \u003ctd\u003eList all the system channels including the \"global\" channel.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003efdc3.getSystemChannels()\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003e \u003ccode\u003ejoinChannel(channelId: string): Promise\u0026lt;void\u003e\u003c/code\u003e \u003c/td\u003e\n  \u003ctd\u003eJoin a channel by using it's name. If the channel is not found it will Error. \u003cb\u003eYou can only join one channel at a time.\u003c/b\u003e \u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003efdc3.joinChannel('channel1')\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003e \u003ccode\u003egetCurrentChannel(): Promise\u0026lt;Channel\u003e\u003c/code\u003e \u003c/td\u003e\n  \u003ctd\u003eReturns the channel that you are currently joined to.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003efdc3.getCurrentChannel()\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003e \u003ccode\u003eleaveCurrentChannel(): Promise\u0026lt;void\u003e\u003c/code\u003e \u003c/td\u003e\n  \u003ctd\u003eLeave the channel that you are currently joined to.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003efdc3.leaveCurrentChannel()\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n## Example use cases:\n\n\u003e When a user clicks on the chart button I want to open my ChartIQ Chart, how would I do this?\n\nThere is a simple command for this! `fdc3.open(\"ChartIQ\")`\n\n\u003e My Chart opens but now I need to send instrument data to it, what do I need to do next?\n\nThe fdc3.open call allows you to send context with it too. Here is an example of opening the chart and sending the GOOGL\n(Google) ticker symbol to it.\n\n```javascript\nfdc3.open(\"ChartIQ\", {\n\ttype: \"fdc3.instrument\",\n\tname: \"Google\",\n\tid: {\n\t\tticker: \"GOOGL\",\n\t},\n});\n```\n\n\u003e I want to send an instrument (MSFT) but I want the user to choose the application they want to display it with, how\n\u003e would I do that?\n\nThis is where you can raise an intent. Once the intent has been raised it will show all the apps capable of dealing with\nyour intent in the intent resolver. This works in a similar fashion to your phone when you want to share a link or open\na calendar invite and it asks which application you would like to use. To do this you need two things\n\n1. A Finsemble component that has been set up to accept your intent (you can read the section on config above to do\n   this).\n2. Your component to have a button or event to run the following code\n\n```javascript\nconst instrument = {\n\ttype: \"fdc3.instrument\",\n\tname: \"Microsoft\",\n\tid: { ticker: \"MSFT\" },\n};\nfdc3.raiseIntent(\"ViewInstrument\", instrument);\n```\n\nOnce executed Finsemble will display the Intent Resolver UI, a modal type component to display the apps that can accept\nyour intent. The rest is dealt with by your end-user.\n\n\u003e I made an application that can be opened by the Intent Resolver via raiseIntent but I don't see my data updating, how\n\u003e do I get the data when it's sent?\n\u003e\n\u003e When you develop your application you will need to add one or more intent listeners for each intent that your\n\u003e application can be used with.\n\u003e `const listener = fdc3.addIntentListener('ViewInstrument', context =\u003e { // view instrument has been requested by another application });`\n\n\u003e Is there a way I can find out intents in advance so that if there are no applications that accept my intent I can do\n\u003e something else with a user request?\n\u003e\n\u003e Yes. You have two options to find intents, you can\n\u003e `fdc3.findIntent(\"ViewChart\", context); //context object is optional` OR `fdc3.findIntentsByContext(context);`\n\n\u003e I don't want to use the intent resolver each time I want to send context (data) between components, is there another\n\u003e way?\n\u003e\n\u003e FDC3 1.1 introduces the Channels API. You can connect your components to a channel either programmatically or user-led\n\u003e via the Finsemble Linker. Channels then allow you to share context between them. A single application (component) can\n\u003e only join one channel at a time e.g it cannot join the purple and the yellow channel, if the user tries to do this\n\u003e they will be removed from the last channel joined. You can however programmatically listen to as many channels as you\n\u003e like from your application. Many applications can be joined to a single-channel e.g App A, B and C can all be joined\n\u003e by the purple channel.\n\n\u003e What do I need to do to enable the channels so that my end users can start using it?\n\u003e\n\u003e Finsemble includes user interface for selecting built-in (or system) color channels, normally used with the Finsemble\n\u003e Linker API. The Finsemble FDC3 implementation, if preloaded into a component, will take over the Linker UI allowing\n\u003e you to use it select FDC3 system channels instead. All you need to do is add the FDC3 preload to your component then\n\u003e set up a [context listener](#context-listener) and Finsemble will handle the rest. Your end-users can now use the\n\u003e Finsemble Linker button to change the FDC3 channel they are joined to.\n\n\u003e How do I know what channels I have access to?\n\u003e\n\u003e You can list the available System channels (including a global channel) by doing the following:\n\u003e `const systemChannels = await fdc3.getSystemChannels(); // Array of System Channels`\n\n\u003e Am I limited to just your Finsemble Linker channels?\n\u003e\n\u003e No. You can add as many channels as you like, try it by using `const Channel = fdc3.getOrCreateChannel(\"myChannel\")`\n\n\u003e You mentioned programmatically sending context (data) over channels how do I do that?\n\u003e\n\u003e If you want to send context via the channel that you are currently joined to you can do the following:\n\n```javascript\nconst instrument = {\n\ttype: \"fdc3.instrument\",\n\tid: { ticker: \"MSFT\" },\n};\nfdc3.broadcast(instrument);\n```\n\nIf you want to send context to a channel you are not joined to you need to get the channel first.\n\n```javascript\ntry {\n  const myChannel = await fdc3.getOrCreateChannel(\"myChannel\");\n\n  const instrument = {\n    type: 'fdc3.instrument',\n    id: { ticker: 'MSFT' }\n    };\n\n  const myChannel.broadcast(instrument);\n\n} catch (err){\n  //app could not register the channel\n};\n```\n\n\u003e Now I have sent context (data) how do I listen for it?\n\nIt depends on if you want to listen for context on the channel you are joined to or a different channel(s).\n\nIf you are joined to a channel you can use the following:\n\n```javascript\n// any context\nconst listener = fdc3.addContextListener(context =\u003e { ... });\n\n// listener for a specific type\nconst contactListener = fdc3.addContextListener('fdc3.contact', contact =\u003e { ... });\n```\n\nIf you want to listen to a specific channel you need to get it first like this:\n\n```javascript\ntry {\n\n  const myChannel = await fdc3.getOrCreateChannel(\"myChannel\");\n  const myChannel.addContextListener(context =\u003e {});\n\n} catch (err){\n  //app could not register the channel\n};\n```\n\n\u003e Is there a list of default context types?\n\u003e\n\u003e Yes, you can find a list of FDC3 context types here [https://fdc3.finos.org/docs/1.1/context/overview](). FDC3 context\n\u003e types start with \"fdc3.\".\n\n\u003e What if the default FDC3 context types don't fit with my data structure?\n\u003e\n\u003e You will need to create a custom context type. The only value required is the type(see below).\n\n_Note: When broadcasting a custom context type the receiving application will need to know the content and structure of\nthe context you are sending._\n\n```\ninterface Context {\n    type: string;\n    name?: string;\n    id?: {\n        [x:string]: string;\n    },\n    [x: string]: any;\n}\n```\n\nAn example of a finsemble custom type may look like this:\n\n```\n{\n  \"type\": \"com.finsemble.chart\",\n  \"name\": \"Microsoft Mountain Chart\",\n  \"settings\": [\n    {\n      \"type\": \"chart\",\n      \"chartType\": \"mountain\",\n      \"studies\": [\n        \"bollinger\",\n        \"ab\"\n      ],\n      \"instrument\": [\n        {\n          \"type\": \"fdc3.instrument\",\n          \"name\": \"Microsoft\",\n          \"id\": {\n            \"ticker\": \"MSFT\"\n          }\n        }\n      ]\n    }\n  ]\n}\n```\n\n## FDC3 in Finsemble Dot-Net Components\n\nYou can use FDC3 in your dot-net application. The\n[finsemble-dotnet-seed](https://github.com/ChartIQ/finsemble-dotnet-seed) project provides a WPF Example on how to\nenable FDC3 support in dot-net application.\n\nTo enable FDC3 in you Dot-Net components, in you dot-net component config set \u003ccode\u003ecomponent.useFdc3\u003c/code\u003e to\n\u003ccode\u003etrue\u003c/code\u003e. You can find example in the \u003ccode\u003ewfpExample.json\u003c/code\u003e\n\n### Dot-Net API\n\n#### Dot-Net App\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n  \u003cth\u003eAPI\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003cth\u003eExample\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n  \u003ctd\u003e \u003ccode\u003evoid open(String name, JObject context, EventHandler \u003c JObject \u003e cb)\u003c/code\u003e \u003c/td\u003e\n  \u003ctd\u003eOpen a component and optionally send context for it to use. Name relates to a Finsemble Component type such as \"Welcome Component\"\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eFSBL.FDC3Client.fdc3.open('ChartIQ Chart')\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003cbr/\u003e\n\n#### Dot-Net Context\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n  \u003cth\u003eAPI\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003cth\u003eExample\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n  \u003ctd\u003e\u003ccode\u003evoid broadcast(JObject context);\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eSend context to the channel the app is currently join to. We default applications to join on the Global Channel.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eFSBL.FDC3Client.fdc3.open(componentName, new JObject\n\t\t\t\t\t{\n\t\t\t\t\t\t[\"type\"] = \"fdc3.instrument\",\n\t\t\t\t\t\t[\"name\"] = \"AAPL\",\n\t\t\t\t\t\t[\"id\"] = new JObject\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t[\"ticker\"] = \"AAPL\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}, (s, args) =\u003e { });\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n  \u003ctd\u003e\n  \u003ccode\u003eIListener addContextListener(String contextType, EventHandler\u003c JObject \u003e handler);\n\nIListener addContextListener(EventHandler\u003c JObject \u003e handler);\u003c/code\u003e\n\n  \u003c/td\u003e\n  \u003ctd\u003eListen to broadcast context on the channel the app is currently join to. We default applications to join on the Global Channel.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003e\nFSBL.FDC3Client.fdc3.addContextListener((s, context) =\u003e {});\nFSBL.FDC3Client.fdc3.addContextListener(\"fdc3.instrument\", (s, context) =\u003e {});\u003c/code\u003e \u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003cbr/\u003e\n\n#### Dot-Net Intents\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n  \u003cth\u003eAPI\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003cth\u003eExample\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n  \u003ctd\u003e\u003ccode\u003evoid findIntent(String intent, JObject context, EventHandler\u003c JObject \u003e cb);\n\nvoid findIntent(String intent, EventHandler\u003c JObject \u003e cb);\u003c/code\u003e\u003c/td\u003e\n\n  \u003ctd\u003eList all the applications that can deal with a certain intent.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eFSBL.FDC3Client.fdc3.findIntent(\"ViewChart\", (s, intent) =\u003e{ });\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n  \u003ctd\u003e\u003ccode\u003evoid findIntentsByContext(JObject context, EventHandler\u003c JArray \u003e cb);\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eList all the applications that can deal with a certain context.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eFSBL.FDC3Client.fdc3.findIntentsByContext(new JObject{\n\t\t\t\t\t\t[\"type\"] = \"fdc3.instrument\"\n\t\t\t\t\t}, (s, intents) =\u003e\n\t\t\t\t\t{\n\t\t\t\t\t}\n\t\t\t\t\t);\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n  \u003ctd\u003e\u003ccode\u003evoid raiseIntent(String intent, JObject context, EventHandler\u003c JObject \u003e cb);\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eOpen an application by name and optionally pass context to be used by that app.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eFSBL.FDC3Client.fdc3.raiseIntent(\"ViewChart\", new JObject\n\t\t\t\t\t{\n\t\t\t\t\t\t[\"type\"] = \"fdc3.instrument\",\n\t\t\t\t\t\t[\"name\"] = \"AAPL\",\n\t\t\t\t\t\t[\"id\"] = new JObject\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t[\"ticker\"] = \"AAPL\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}, (s, args) =\u003e { });\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n  \u003ctd\u003e\u003ccode\u003eIListener addIntentListener(String intent, EventHandler\u003c JObject \u003e handler);\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eAdd this to your component so that it can action intents when they are sent.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eFSBL.FDC3Client.fdc3.addIntentListener(\"ViewChart\", (s, context) =\u003e { });\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003cbr/\u003e\n\n#### Dot-Net Channels\n\nThe DesktopAgent API will allow you to join, listen to and broadcast context to a single 'channel' via its API. However,\nyou can also interact directly with FDC3 channels, which have the following interface:\n\n```c#\npublic interface IChannel\n{\n  String id { get; }\n  String type { get; }\n  DisplayMetadata displayMetadata { get; }\n  void broadcast(JObject context);\n  void getCurrentContext(String contextType, EventHandler\u003cJObject\u003e cb);\n  IListener addContextListener(EventHandler\u003cJObject\u003e handler);\n  IListener addContextListener(String contextType, EventHandler\u003cJObject\u003e handler);\n}\n```\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n  \u003cth\u003eAPI\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003cth\u003eExample\u003c/th\u003e\n\u003c/tr\u003e\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n  \u003ctd\u003e \u003ccode\u003evoid getOrCreateChannel(String channelId, EventHandler\u003c IChannel \u003e cb);\u003c/code\u003e \u003c/td\u003e\n  \u003ctd\u003eIf the channel does not exist it will be created.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eFSBL.FDC3Client.fdc3.getOrCreateChannel(\"channel1\", (s, args) =\u003e { });\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003e \u003ccode\u003evoid getSystemChannels(EventHandler\u003c List\u003c IChannel \u003e \u003e cb);\u003c/code\u003e \u003c/td\u003e\n  \u003ctd\u003eList all the system channels including the \"global\" channel.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eFSBL.FDC3Client.fdc3.getSystemChannels((s, channelList) =\u003e {});\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003e \u003ccode\u003evoid joinChannel(String channelId);\u003c/code\u003e \u003c/td\u003e\n  \u003ctd\u003eJoin a channel by using it's name. If the channel is not found it will Error. \u003cb\u003eYou can only join one channel at a time.\u003c/b\u003e \u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eFSBL.FDC3Client.fdc3.joinChannel(\"group1\");\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003e \u003ccode\u003eIChannel getCurrentChannel(EventHandler\u003c IChannel \u003e cb);\u003c/code\u003e \u003c/td\u003e\n  \u003ctd\u003eReturns the channel that you are currently joined to.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eFSBL.FDC3Client.fdc3.getCurrentChannel((s, channel) =\u003e {});\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003e \u003ccode\u003evoid leaveCurrentChannel(EventHandler\u003c JObject \u003e cb);\u003c/code\u003e \u003c/td\u003e\n  \u003ctd\u003eLeave the channel that you are currently joined to.\u003c/td\u003e\n  \u003ctd\u003e\u003ccode\u003eFSBL.FDC3Client.fdc3.leaveCurrentChannel((s, args) =\u003e {});\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finteropio%2Ffinsemble-fdc3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finteropio%2Ffinsemble-fdc3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finteropio%2Ffinsemble-fdc3/lists"}