{"id":32306981,"url":"https://github.com/dimchat/plugins-dart","last_synced_at":"2026-02-21T07:40:17.989Z","repository":{"id":308020234,"uuid":"1031379131","full_name":"dimchat/plugins-dart","owner":"dimchat","description":"DIM Plugins (Dart)","archived":false,"fork":false,"pushed_at":"2026-01-13T19:49:42.000Z","size":151,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-13T21:43:58.587Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dimchat.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-03T16:04:52.000Z","updated_at":"2026-01-13T19:49:46.000Z","dependencies_parsed_at":"2025-09-16T00:08:46.680Z","dependency_job_id":"740ffebe-31d4-4f55-8314-5891d874e7af","html_url":"https://github.com/dimchat/plugins-dart","commit_stats":null,"previous_names":["dimchat/plugins-dart"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/dimchat/plugins-dart","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimchat%2Fplugins-dart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimchat%2Fplugins-dart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimchat%2Fplugins-dart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimchat%2Fplugins-dart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dimchat","download_url":"https://codeload.github.com/dimchat/plugins-dart/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimchat%2Fplugins-dart/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29676833,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T06:23:40.028Z","status":"ssl_error","status_checked_at":"2026-02-21T06:23:39.222Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":"2025-10-23T07:12:54.417Z","updated_at":"2026-02-21T07:40:17.983Z","avatar_url":"https://github.com/dimchat.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DIM Plugins (Dart)\n\n[![License](https://img.shields.io/github/license/dimchat/plugins-dart)](https://github.com/dimchat/plugins-dart/blob/main/LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/dimchat/plugins-dart/pulls)\n[![Platform](https://img.shields.io/badge/Platform-Dart%203-brightgreen.svg)](https://github.com/dimchat/plugins-dart/wiki)\n[![Issues](https://img.shields.io/github/issues/dimchat/plugins-dart)](https://github.com/dimchat/plugins-dart/issues)\n[![Repo Size](https://img.shields.io/github/repo-size/dimchat/plugins-dart)](https://github.com/dimchat/plugins-dart/archive/refs/heads/main.zip)\n[![Tags](https://img.shields.io/github/tag/dimchat/plugins-dart)](https://github.com/dimchat/plugins-dart/tags)\n[![Version](https://img.shields.io/pub/v/dim_plugins)](https://pub.dev/packages/dim_plugins)\n\n[![Watchers](https://img.shields.io/github/watchers/dimchat/plugins-dart)](https://github.com/dimchat/plugins-dart/watchers)\n[![Forks](https://img.shields.io/github/forks/dimchat/plugins-dart)](https://github.com/dimchat/plugins-dart/forks)\n[![Stars](https://img.shields.io/github/stars/dimchat/plugins-dart)](https://github.com/dimchat/plugins-dart/stargazers)\n[![Followers](https://img.shields.io/github/followers/dimchat)](https://github.com/orgs/dimchat/followers)\n\n## Plugins\n\n1. Data Coding\n   * Base-58\n   * Base-64\n   * Hex\n   * UTF-8\n   * JsON\n   * PNF _(Portable Network File)_\n   * TED _(Transportable Encoded Data)_\n2. Digest Digest\n   * MD-5\n   * SHA-1\n   * SHA-256\n   * Keccak-256\n   * RipeMD-160\n3. Cryptography\n   * AES-256 _(AES/CBC/PKCS7Padding)_\n   * RSA-1024 _(RSA/ECB/PKCS1Padding)_, _(SHA256withRSA)_\n   * ECC _(Secp256k1)_\n4. Address\n   * BTC\n   * ETH\n5. Meta\n   * MKM _(Default)_\n   * BTC\n   * ETH\n6. Document\n   * Visa _(User)_\n   * Profile\n   * Bulletin _(Group)_\n\n## Extends\n\n### Address\n\n```dart\nimport 'package:dimp/dimp.dart';\nimport 'package:dim_plugins/mkm.dart';\n\n\nclass CompatibleAddressFactory extends BaseAddressFactory {\n\n  @override\n  Address? parse(String address) {\n    int len = address.length;\n    if (len == 0) {\n      assert(false, 'address empty');\n      return null;\n    } else if (len == 8) {\n      // \"anywhere\"\n      String lower = address.toLowerCase();\n      if (lower == Address.ANYWHERE.toString()) {\n        return Address.ANYWHERE;\n      }\n    } else if (len == 10) {\n      // \"everywhere\"\n      String lower = address.toLowerCase();\n      if (lower == Address.EVERYWHERE.toString()) {\n        return Address.EVERYWHERE;\n      }\n    }\n    Address? res;\n    if (26 \u003c= len \u0026\u0026 len \u003c= 35) {\n      res = BTCAddress.parse(address);\n    } else if (len == 42) {\n      res = ETHAddress.parse(address);\n    } else {\n      // throw AssertionError('invalid address: $address');\n      res = null;\n    }\n    //\n    //  TODO: parse for other types of address\n    //\n    if (res == null \u0026\u0026 4 \u003c= len \u0026\u0026 len \u003c= 64) {\n      res = UnknownAddress(address);\n    }\n    assert(res != null, 'invalid address: $address');\n    return res;\n  }\n\n}\n\n\n/// Unsupported Address\n/// ~~~~~~~~~~~~~~~~~~~\nclass UnknownAddress extends ConstantString implements Address {\n  UnknownAddress(super.string);\n\n  @override\n  int get network =\u003e 0;  // EntityType.USER;\n\n}\n```\n\n### Meta\n\n```dart\nimport 'package:dimp/crypto.dart';\nimport 'package:dimp/mkm.dart';\nimport 'package:dimp/ext.dart';\nimport 'package:dim_plugins/mkm.dart';\n\n\nclass CompatibleMetaFactory extends BaseMetaFactory {\n  CompatibleMetaFactory(super.type);\n\n  @override\n  Meta? parseMeta(Map meta) {\n    Meta out;\n    var ext = SharedAccountExtensions();\n    String? version = ext.helper!.getMetaType(meta);\n    switch (version) {\n\n      case 'MKM':\n      case 'mkm':\n      case '1':\n        out = DefaultMeta(meta);\n        break;\n\n      case 'BTC':\n      case 'btc':\n      case '2':\n        out = BTCMeta(meta);\n        break;\n\n      case 'ETH':\n      case 'eth':\n      case '4':\n        out = ETHMeta(meta);\n        break;\n\n      default:\n        // TODO: other types of meta\n        throw Exception('unknown meta type: $type');\n    }\n    return out.isValid ? out : null;\n  }\n\n}\n```\n\n### Plugin Loader\n\n```dart\nimport 'dart:typed_data';\n\nimport 'package:dimp/crypto.dart';\nimport 'package:dimp/mkm.dart';\nimport 'package:dim_plugins/format.dart';\nimport 'package:dim_plugins/plugins.dart';\n\nimport 'compat_address.dart';\nimport 'compat_meta.dart';\n\n\nclass CompatiblePluginLoader extends PluginLoader {\n\n  @override\n  void registerAddressFactory() {\n    Address.setFactory(CompatibleAddressFactory());\n  }\n\n  @override\n  void registerMetaFactories() {\n    var mkm = CompatibleMetaFactory(Meta.MKM);\n    var btc = CompatibleMetaFactory(Meta.BTC);\n    var eth = CompatibleMetaFactory(Meta.ETH);\n\n    Meta.setFactory('1', mkm);\n    Meta.setFactory('2', btc);\n    Meta.setFactory('4', eth);\n\n    Meta.setFactory('mkm', mkm);\n    Meta.setFactory('btc', btc);\n    Meta.setFactory('eth', eth);\n\n    Meta.setFactory('MKM', mkm);\n    Meta.setFactory('BTC', btc);\n    Meta.setFactory('ETH', eth);\n  }\n\n  @override\n  void registerBase64Coder() {\n    /// Base64 coding\n    Base64.coder = PatchBase64Coder();\n  }\n}\n\n\n/// Base-64\nclass PatchBase64Coder extends Base64Coder {\n\n  @override\n  Uint8List? decode(String string) {\n    string = trimBase64String(string);\n    return super.decode(string);\n  }\n\n  static String trimBase64String(String b64) {\n    if (b64.contains('\\n')) {\n      b64 = b64.replaceAll('\\n', '');\n      b64 = b64.replaceAll('\\r', '');\n      b64 = b64.replaceAll('\\t', '');\n      b64 = b64.replaceAll(' ', '');\n    }\n    return b64.trim();\n  }\n}\n```\n\n### ExtensionLoader\n\n```dart\nimport 'package:dimp/ext.dart';\n\nimport '../../common/protocol/handshake.dart';\n\n\n/// Extensions Loader\n/// ~~~~~~~~~~~~~~~~~\nclass CommonExtensionLoader extends ExtensionLoader {\n\n  @override\n  void registerCustomizedFactories() {\n    \n    // Application Customized\n    setContentFactory(ContentType.CUSTOMIZED, 'customized', creator: (dict) =\u003e AppCustomizedContent(dict));\n    setContentFactory(ContentType.APPLICATION, 'application', creator: (dict) =\u003e AppCustomizedContent(dict));\n    \n  }\n\n  @override\n  void registerCommandFactories() {\n    super.registerCommandFactories();\n\n    // Handshake\n    setCommandFactory(HandshakeCommand.HANDSHAKE, creator: (dict) =\u003e BaseHandshakeCommand(dict));\n\n  }\n\n}\n```\n\n## Usage\n\nYou must load all plugins before your business run:\n\n```dart\nimport 'package:dimp/ext.dart';\n\nimport 'compat_loader.dart';\n\n\nclass LibraryLoader {\n  LibraryLoader({ExtensionLoader? extensionLoader, PluginLoader? pluginLoader}) {\n    this.extensionLoader = extensionLoader ?? CommonExtensionLoader();\n    this.pluginLoader = pluginLoader ?? CompatiblePluginLoader();\n  }\n\n  late final ExtensionLoader extensionLoader;\n  late final PluginLoader pluginLoader;\n\n  bool _loaded = false;\n\n  void run() {\n     if (_loaded) {\n        // no need to load it again\n        return;\n     } else {\n        // mark it to loaded\n        _loaded = true;\n     }\n     // try to load all plugins\n     load();\n  }\n\n  // protected\n  void load() {\n     extensionLoader.load();\n     pluginLoader.load();\n  }\n\n}\n\n\nvoid main() {\n\n  var loader = LibraryLoader();\n  loader.run();\n  \n  // do your jobs after all extensions \u0026 plugins loaded\n  \n}\n```\n\nYou must ensure that every ```Address``` you extend has a ```Meta``` type that can correspond to it one by one.\n\n----\n\nCopyright \u0026copy; 2023-2025 Albert Moky\n[![Followers](https://img.shields.io/github/followers/moky)](https://github.com/moky?tab=followers)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdimchat%2Fplugins-dart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdimchat%2Fplugins-dart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdimchat%2Fplugins-dart/lists"}