Skip to content

dimchat/plugins-dart

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DIM Plugins (Dart)

License PRs Welcome Platform Issues Repo Size Tags Version

Watchers Forks Stars Followers

Plugins

  1. Data Coding
    • Base-58
    • Base-64
    • Hex
    • UTF-8
    • JsON
    • PNF (Portable Network File)
    • TED (Transportable Encoded Data)
  2. Digest Digest
    • MD-5
    • SHA-1
    • SHA-256
    • Keccak-256
    • RipeMD-160
  3. Cryptography
    • AES-256 (AES/CBC/PKCS7Padding)
    • RSA-1024 (RSA/ECB/PKCS1Padding), (SHA256withRSA)
    • ECC (Secp256k1)
  4. Address
    • BTC
    • ETH
  5. Meta
    • MKM (Default)
    • BTC
    • ETH
  6. Document
    • Visa (User)
    • Profile
    • Bulletin (Group)

Extends

Address

import 'package:dimp/dimp.dart';
import 'package:dim_plugins/mkm.dart';


class CompatibleAddressFactory extends BaseAddressFactory {

  @override
  Address? parse(String address) {
    int len = address.length;
    if (len == 0) {
      assert(false, 'address empty');
      return null;
    } else if (len == 8) {
      // "anywhere"
      String lower = address.toLowerCase();
      if (lower == Address.ANYWHERE.toString()) {
        return Address.ANYWHERE;
      }
    } else if (len == 10) {
      // "everywhere"
      String lower = address.toLowerCase();
      if (lower == Address.EVERYWHERE.toString()) {
        return Address.EVERYWHERE;
      }
    }
    Address? res;
    if (26 <= len && len <= 35) {
      res = BTCAddress.parse(address);
    } else if (len == 42) {
      res = ETHAddress.parse(address);
    } else {
      // throw AssertionError('invalid address: $address');
      res = null;
    }
    //
    //  TODO: parse for other types of address
    //
    if (res == null && 4 <= len && len <= 64) {
      res = UnknownAddress(address);
    }
    assert(res != null, 'invalid address: $address');
    return res;
  }

}


/// Unsupported Address
/// ~~~~~~~~~~~~~~~~~~~
class UnknownAddress extends ConstantString implements Address {
  UnknownAddress(super.string);

  @override
  int get network => 0;  // EntityType.USER;

}

Meta

import 'package:dimp/crypto.dart';
import 'package:dimp/mkm.dart';
import 'package:dimp/ext.dart';
import 'package:dim_plugins/mkm.dart';


class CompatibleMetaFactory extends BaseMetaFactory {
  CompatibleMetaFactory(super.type);

  @override
  Meta? parseMeta(Map meta) {
    Meta out;
    var helper = sharedAccountExtensions.helper;
    String? version = helper?.getMetaType(meta);
    switch (version) {

      case 'MKM':
      case 'mkm':
      case '1':
        out = DefaultMeta(meta);
        break;

      case 'BTC':
      case 'btc':
      case '2':
        out = BTCMeta(meta);
        break;

      case 'ETH':
      case 'eth':
      case '4':
        out = ETHMeta(meta);
        break;

      default:
        // TODO: other types of meta
        throw Exception('unknown meta type: $type');
    }
    return out.isValid ? out : null;
  }

}

ExtensionLoader

import 'package:dimp/ext.dart';

import '../../common/protocol/handshake.dart';


/// Extensions Loader
/// ~~~~~~~~~~~~~~~~~
class CommonExtensionLoader extends ExtensionLoader {

  @override
  void registerAddressFactory() {

    Address.setFactory(CompatibleAddressFactory());

  }

  @override
  void registerMetaFactories() {

    var mkm = CompatibleMetaFactory(Meta.MKM);
    var btc = CompatibleMetaFactory(Meta.BTC);
    var eth = CompatibleMetaFactory(Meta.ETH);

    Meta.setFactory('1', mkm);
    Meta.setFactory('2', btc);
    Meta.setFactory('4', eth);

    Meta.setFactory('mkm', mkm);
    Meta.setFactory('btc', btc);
    Meta.setFactory('eth', eth);

    Meta.setFactory('MKM', mkm);
    Meta.setFactory('BTC', btc);
    Meta.setFactory('ETH', eth);

  }

  @override
  void registerContentFactories() {
    super.registerContentFactories();

    registerCustomizedFactories();

  }

  void registerCustomizedFactories() {

    // Application Customized
    var factory = ContentParser((dict) => AppCustomizedContent(dict));
    setContentFactory(ContentType.APPLICATION, factory: factory);
    setContentFactory(ContentType.CUSTOMIZED, factory: factory);
    
  }

  @override
  void registerCommandFactories() {
    super.registerCommandFactories();

    // Handshake
    setCommandFactory(HandshakeCommand.HANDSHAKE, creator: (dict) => BaseHandshakeCommand(dict));

  }

}

Plugin Loader

import 'dart:typed_data';

import 'package:dimp/crypto.dart';
import 'package:dimp/mkm.dart';
import 'package:dim_plugins/format.dart';
import 'package:dim_plugins/plugins.dart';

import 'compat_address.dart';
import 'compat_meta.dart';


class CompatiblePluginLoader extends PluginLoader {

  @override
  void registerBase64Coder() {

    /// Base64 coding
    Base64.coder = _PatchBase64Coder();

  }

}

/// Base-64
class _PatchBase64Coder extends Base64Coder {

  @override
  Uint8List? decode(String string) {
    string = trimBase64String(string);
    return super.decode(string);
  }

  static String trimBase64String(String b64) {
    if (b64.contains('\n')) {
      b64 = b64.replaceAll('\n', '');
      b64 = b64.replaceAll('\r', '');
      b64 = b64.replaceAll('\t', '');
      b64 = b64.replaceAll(' ', '');
    }
    return b64.trim();
  }
}

Usage

You must load all plugins before your business run:

import 'package:dimp/ext.dart';

import 'compat_loader.dart';


class LibraryLoader {
  LibraryLoader({ExtensionLoader? extensionLoader, PluginLoader? pluginLoader}) {
    this.extensionLoader = extensionLoader ?? CommonExtensionLoader();
    this.pluginLoader = pluginLoader ?? CompatiblePluginLoader();
  }

  late final ExtensionLoader extensionLoader;
  late final PluginLoader pluginLoader;

  bool _loaded = false;

  void run() {
     if (_loaded) {
        // no need to load it again
        return;
     } else {
        // mark it to loaded
        _loaded = true;
     }
     // try to load all plugins
     load();
  }

  // protected
  void load() {
     extensionLoader.load();
     pluginLoader.load();
  }

}


void main() {

  var loader = LibraryLoader();
  loader.run();
  
  // do your jobs after all extensions & plugins loaded
  
}

You must ensure that every Address you extend has a Meta type that can correspond to it one by one.


Copyright © 2023-2026 Albert Moky Followers

About

DIM Plugins (Dart)

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages