https://github.com/dimchat/plugins-dart
DIM Plugins (Dart)
https://github.com/dimchat/plugins-dart
Last synced: 4 months ago
JSON representation
DIM Plugins (Dart)
- Host: GitHub
- URL: https://github.com/dimchat/plugins-dart
- Owner: dimchat
- License: mit
- Created: 2025-08-03T16:04:52.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2026-01-13T19:49:42.000Z (5 months ago)
- Last Synced: 2026-01-13T21:43:58.587Z (5 months ago)
- Language: Dart
- Size: 147 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# DIM Plugins (Dart)
[](https://github.com/dimchat/plugins-dart/blob/main/LICENSE)
[](https://github.com/dimchat/plugins-dart/pulls)
[](https://github.com/dimchat/plugins-dart/wiki)
[](https://github.com/dimchat/plugins-dart/issues)
[](https://github.com/dimchat/plugins-dart/archive/refs/heads/main.zip)
[](https://github.com/dimchat/plugins-dart/tags)
[](https://pub.dev/packages/dim_plugins)
[](https://github.com/dimchat/plugins-dart/watchers)
[](https://github.com/dimchat/plugins-dart/forks)
[](https://github.com/dimchat/plugins-dart/stargazers)
[](https://github.com/orgs/dimchat/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
```dart
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
```dart
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 ext = SharedAccountExtensions();
String? version = ext.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;
}
}
```
### Plugin Loader
```dart
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 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 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();
}
}
```
### ExtensionLoader
```dart
import 'package:dimp/ext.dart';
import '../../common/protocol/handshake.dart';
/// Extensions Loader
/// ~~~~~~~~~~~~~~~~~
class CommonExtensionLoader extends ExtensionLoader {
@override
void registerCustomizedFactories() {
// Application Customized
setContentFactory(ContentType.CUSTOMIZED, 'customized', creator: (dict) => AppCustomizedContent(dict));
setContentFactory(ContentType.APPLICATION, 'application', creator: (dict) => AppCustomizedContent(dict));
}
@override
void registerCommandFactories() {
super.registerCommandFactories();
// Handshake
setCommandFactory(HandshakeCommand.HANDSHAKE, creator: (dict) => BaseHandshakeCommand(dict));
}
}
```
## Usage
You must load all plugins before your business run:
```dart
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-2025 Albert Moky
[](https://github.com/moky?tab=followers)