diff --git a/lib/account.dart b/lib/account.dart
index ac4201f..1408566 100644
--- a/lib/account.dart
+++ b/lib/account.dart
@@ -124,15 +124,15 @@ extension LanguageExtension on Language {
 }
 
 class Account {
-  String gid = '';
+  String pid = '';
   String name = '';
   Uint8List? avatar;
   bool online = false;
   bool hasNew = false;
   String pin = '';
 
-  Account(String gid, String name, [String avatar = "", bool online = false]) {
-    this.gid = gid;
+  Account(String pid, String name, [String avatar = "", bool online = false]) {
+    this.pid = pid;
     this.name = name;
     this.updateAvatar(avatar);
     this.online = online;
diff --git a/lib/apps/chat/add.dart b/lib/apps/chat/add.dart
index 80c312e..687024a 100644
--- a/lib/apps/chat/add.dart
+++ b/lib/apps/chat/add.dart
@@ -26,9 +26,8 @@ import 'package:esse/apps/domain/models.dart';
 
 class ChatAdd extends StatefulWidget {
   final String id;
-  final String addr;
   final String name;
-  ChatAdd({Key? key, this.id = '', this.addr = '', this.name = ''}) : super(key: key);
+  ChatAdd({Key? key, this.id = '', this.name = ''}) : super(key: key);
 
   @override
   _ChatAddState createState() => _ChatAddState();
@@ -42,18 +41,16 @@ class _ChatAddState extends State<ChatAdd> {
 
   void _scanCallback(bool isOk, String app, List params) {
     Navigator.of(context).pop();
-    if (isOk && app == 'add-friend' && params.length == 3) {
+    if (isOk && app == 'add-friend' && params.length == 2) {
       setState(() {
           this._showHome = false;
-          final avatar = Avatar(name: params[2], width: 100.0, colorSurface: false);
-          String id = gidParse(params[0].trim());
-          String addr = addrParse(params[1]);
+          final avatar = Avatar(name: params[1], width: 100.0, colorSurface: false);
+          String id = pidParse(params[0].trim());
 
           this._coreScreen = _InfoScreen(
             callback: this._sendCallback,
             id: id,
-            addr: addr,
-            name: params[2],
+            name: params[1],
             bio: '',
             avatar: avatar,
           );
@@ -61,13 +58,12 @@ class _ChatAddState extends State<ChatAdd> {
     }
   }
 
-  void _searchCallBack(String id, String addr, String name, String bio, Avatar avatar) {
+  void _searchCallBack(String id, String name, String bio, Avatar avatar) {
     setState(() {
         this._showHome = false;
         this._coreScreen = _InfoScreen(
           callback: this._sendCallback,
           id: id,
-          addr: addr,
           name: name,
           bio: bio,
           avatar: avatar,
@@ -151,7 +147,6 @@ class _ChatAddState extends State<ChatAdd> {
                 callback: this._sendCallback,
                 name: widget.name,
                 id: widget.id,
-                addr: widget.addr,
                 bio: '',
                 avatar: avatar,
               );
@@ -196,9 +191,7 @@ class _ChatAddState extends State<ChatAdd> {
     final res = await httpPost('chat-request-list', []);
     if (res.isOk) {
       res.params.forEach((param) {
-          if (param.length == 10) {
-            this._requests[param[0]] = Request.fromList(param);
-          }
+          this._requests[param[0]] = Request.fromList(param);
       });
       setState(() {});
     } else {
@@ -235,8 +228,7 @@ class _ChatAddState extends State<ChatAdd> {
               context,
               Icons.info,
               lang.info,
-              UserInfo(app: 'add-friend',
-                id: account.gid, name: account.name, addr: Global.addr)
+              UserInfo(app: 'add-friend', id: account.pid, name: account.name)
             ),
             child: Padding(
               padding: const EdgeInsets.only(right: 10.0),
@@ -320,8 +312,7 @@ class _ChatAddState extends State<ChatAdd> {
         const SizedBox(height: 10.0),
         const Divider(height: 1.0, color: Color(0x40ADB0BB)),
         const SizedBox(height: 10.0),
-        _infoListTooltip(Icons.person, color.primary, gidText(request.gid), gidPrint(request.gid)),
-        _infoListTooltip(Icons.location_on, color.primary, addrText(request.addr), addrPrint(request.addr)),
+        _infoListTooltip(Icons.person, color.primary, pidText(request.pid), pidPrint(request.pid)),
         _infoList(Icons.turned_in, color.primary, request.remark),
         _infoList(Icons.access_time_rounded, color.primary, request.time.toString()),
         const SizedBox(height: 10.0),
@@ -415,9 +406,7 @@ class _ChatAddState extends State<ChatAdd> {
             InkWell(
               onTap: () {
                 Navigator.pop(context);
-                rpc.send('chat-request-create', [
-                    request.gid, request.addr, request.name, request.remark
-                ]);
+                rpc.send('chat-request-create', [request.pid, request.name, request.remark]);
                 setState(() {
                     this._requests.remove(request.id);
                 });
@@ -672,27 +661,23 @@ class _InputScreen extends StatefulWidget {
 
 class _InputScreenState extends State<_InputScreen> {
   TextEditingController userIdEditingController = TextEditingController();
-  TextEditingController addrEditingController = TextEditingController();
   TextEditingController remarkEditingController = TextEditingController();
   TextEditingController nameEditingController = TextEditingController();
   FocusNode userIdFocus = FocusNode();
-  FocusNode addrFocus = FocusNode();
   FocusNode remarkFocus = FocusNode();
 
   send() {
-    final id = gidParse(userIdEditingController.text.trim());
-    final addr = addrParse(addrEditingController.text.trim());
-    if (id == '' || addr == '') {
+    final id = pidParse(userIdEditingController.text.trim());
+    if (id == '') {
       return;
     }
 
     final name = nameEditingController.text.trim();
     final remark = remarkEditingController.text.trim();
 
-    rpc.send('chat-request-create', [id, addr, name, remark]);
+    rpc.send('chat-request-create', [id, name, remark]);
     setState(() {
         userIdEditingController.text = '';
-        addrEditingController.text = '';
         nameEditingController.text = '';
         remarkEditingController.text = '';
     });
@@ -714,12 +699,6 @@ class _InputScreenState extends State<_InputScreen> {
           controller: userIdEditingController,
           focus: userIdFocus),
         const SizedBox(height: 20.0),
-        InputText(
-          icon: Icons.location_on,
-          text: lang.address + ' (0x00..00)',
-          controller: addrEditingController,
-          focus: addrFocus),
-        const SizedBox(height: 20.0),
         InputText(
           icon: Icons.turned_in,
           text: lang.remark,
@@ -735,7 +714,6 @@ class _InputScreenState extends State<_InputScreen> {
 class _InfoScreen extends StatelessWidget {
   final Function callback;
   final String id;
-  final String addr;
   final String name;
   final String bio;
   final Avatar avatar;
@@ -744,7 +722,6 @@ class _InfoScreen extends StatelessWidget {
       Key? key,
       required this.callback,
       required this.id,
-      required this.addr,
       required this.name,
       required this.bio,
       required this.avatar,
@@ -773,19 +750,10 @@ class _InfoScreen extends StatelessWidget {
           ListTile(
             contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0),
             leading: Icon(Icons.person, color: color.primary),
-            title: Text(gidPrint(this.id), style: TextStyle(fontSize: 16.0)),
-            trailing: TextButton(
-              child: Icon(Icons.copy, size: 20.0),
-              onPressed: () => Clipboard.setData(ClipboardData(text: gidText(this.id))),
-            )
-          ),
-          ListTile(
-            contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0),
-            leading: Icon(Icons.location_on, color: color.primary),
-            title: Text(addrPrint(this.addr), style: TextStyle(fontSize: 16.0)),
+            title: Text(pidPrint(this.id), style: TextStyle(fontSize: 16.0)),
             trailing: TextButton(
               child: Icon(Icons.copy, size: 20.0),
-              onPressed: () => Clipboard.setData(ClipboardData(text: addrText(this.addr))),
+              onPressed: () => Clipboard.setData(ClipboardData(text: pidText(this.id))),
             )
           ),
           ListTile(
@@ -797,7 +765,7 @@ class _InfoScreen extends StatelessWidget {
           TextButton(
             child: Text(lang.addFriend, style: TextStyle(fontSize: 20.0)),
             onPressed: () {
-              rpc.send('chat-request-create', [this.id, this.addr, this.name, '']);
+              rpc.send('chat-request-create', [this.id, this.name, '']);
               this.callback();
             }
           ),
diff --git a/lib/apps/chat/detail.dart b/lib/apps/chat/detail.dart
index a3664f1..77c81b0 100644
--- a/lib/apps/chat/detail.dart
+++ b/lib/apps/chat/detail.dart
@@ -26,7 +26,7 @@ class ChatDetail extends StatefulWidget {
 
 class _ChatDetailState extends State<ChatDetail> {
   bool _loading = false;
-  Friend _friend = Friend('', '', '');
+  Friend _friend = Friend('', '');
   Map<int, Message> _messages = {};
 
   @override
@@ -83,7 +83,7 @@ class _ChatDetailState extends State<ChatDetail> {
   }
 
   _send(MessageType mtype, String raw) {
-    rpc.send('chat-message-create', [_friend.id, _friend.gid, mtype.toInt(), raw]);
+    rpc.send('chat-message-create', [_friend.id, _friend.pid, mtype.toInt(), raw]);
   }
 
   @override
@@ -165,9 +165,8 @@ class _ChatDetailState extends State<ChatDetail> {
                     lang.friendInfo,
                     UserInfo(
                       app: 'add-friend',
-                      id: _friend.gid,
+                      id: _friend.pid,
                       name: _friend.name,
-                      addr: _friend.addr,
                       title: lang.qrFriend,
                       remark: _friend.remark,
                     ),
@@ -207,7 +206,7 @@ class _ChatDetailState extends State<ChatDetail> {
                   );
                 } else if (value == 4) {
                   rpc.send('chat-request-create', [
-                      _friend.gid, _friend.addr, _friend.name, lang.fromContactCard(meName)
+                      _friend.pid, _friend.name, lang.fromContactCard(meName)
                   ]);
                 } else if (value == 5) {
                   showDialog(
@@ -264,7 +263,7 @@ class _ChatDetailState extends State<ChatDetail> {
               itemCount: recentMessageKeys.length,
               reverse: true,
               itemBuilder: (BuildContext context, index) => ChatMessage(
-                fgid: _friend.gid,
+                fpid: _friend.pid,
                 name: _friend.name,
                 message: this._messages[recentMessageKeys[index]]!,
               )
diff --git a/lib/apps/chat/models.dart b/lib/apps/chat/models.dart
index 413a6a6..ed87780 100644
--- a/lib/apps/chat/models.dart
+++ b/lib/apps/chat/models.dart
@@ -8,9 +8,8 @@ import 'package:esse/apps/primitives.dart';
 
 class Friend {
   int id = 0;
-  String gid = '';
+  String pid = '';
   String name = '';
-  String addr = '';
   String wallet = '';
   String remark = '';
   bool isClosed = false;
@@ -18,10 +17,10 @@ class Friend {
   bool online = false;
 
   // new friend from network
-  Friend(this.gid, this.name, this.addr);
+  Friend(this.pid, this.name);
 
   Avatar showAvatar({bool needOnline = false, double width = 45.0}) {
-    final avatar = Global.avatarPath + this.gid + '.png';
+    final avatar = Global.avatarPath + this.pid + '.png';
     if (needOnline) {
       return Avatar(width: width, name: this.name, avatarPath: avatar,
         online: this.online,
@@ -34,23 +33,21 @@ class Friend {
 
   Friend.fromList(List params) {
     this.id = params[0];
-    this.gid = params[1];
-    this.addr = params[2];
-    this.name = params[3];
-    this.wallet = params[4];
-    this.remark = params[5];
-    this.isClosed = params[6];
-    this.time = RelativeTime.fromInt(params[7]);
-    if (params.length == 9) {
-      this.online = params[8];
+    this.pid = params[1];
+    this.name = params[2];
+    this.wallet = params[3];
+    this.remark = params[4];
+    this.isClosed = params[5];
+    this.time = RelativeTime.fromInt(params[6]);
+    if (params.length == 8) {
+      this.online = params[7];
     }
   }
 }
 
 class Request {
   int id = 0;
-  String gid = '';
-  String addr = '';
+  String pid = '';
   String name = '';
   String remark = '';
   bool isMe = true;
@@ -59,33 +56,32 @@ class Request {
   bool isDelivery = false;
   RelativeTime time = RelativeTime();
 
-  Request(this.gid, this.addr, this.name, this.remark);
+  Request(this.pid, this.name, this.remark);
 
   overIt(bool isOk) {
     this.over = true;
     this.ok = isOk;
   }
 
-  Friend toFriend(String gid) {
-    return Friend(gid, this.name, this.addr);
+  Friend toFriend(String pid) {
+    return Friend(pid, this.name);
   }
 
   Avatar showAvatar([double width = 45.0]) {
-    final avatar = Global.avatarPath + this.gid + '.png';
+    final avatar = Global.avatarPath + this.pid + '.png';
     return Avatar(width: width, name: this.name, avatarPath: avatar);
   }
 
   Request.fromList(List params) {
     this.id = params[0];
-    this.gid = params[1];
-    this.addr = params[2];
-    this.name = params[3];
-    this.remark = params[4];
-    this.isMe = params[5];
-    this.ok = params[6];
-    this.over = params[7];
-    this.isDelivery = params[8];
-    this.time = RelativeTime.fromInt(params[9]);
+    this.pid = params[1];
+    this.name = params[2];
+    this.remark = params[3];
+    this.isMe = params[4];
+    this.ok = params[5];
+    this.over = params[6];
+    this.isDelivery = params[7];
+    this.time = RelativeTime.fromInt(params[8]);
   }
 }
 
diff --git a/lib/apps/device/page.dart b/lib/apps/device/page.dart
index 8e324e5..d6fbc0f 100644
--- a/lib/apps/device/page.dart
+++ b/lib/apps/device/page.dart
@@ -48,11 +48,11 @@ class _DevicesPageState extends State<DevicesPage> {
     ));
   }
 
-  _showQrCode(String name, String id, String addr, String lock, ColorScheme color, lang) async {
+  _showQrCode(String name, String id, String lock, ColorScheme color, lang) async {
     final res = await httpPost('account-mnemonic', [lock]);
     if (res.isOk) {
       final words = res.params[0];
-      final info = json.encode({'app': 'distribute', 'params': [name, gidText(id), addrText(addr), words]});
+      final info = json.encode({'app': 'distribute', 'params': [name, pidText(id), words]});
       showShadowDialog(context, Icons.qr_code_rounded, lang.deviceQrcode,
         Column(
           children: [
@@ -109,7 +109,7 @@ class _DevicesPageState extends State<DevicesPage> {
   }
 
   Widget deviceWidget(ColorScheme color, Device device, bool isDesktop, double widgetWidth, lang) {
-    final bool isLocal = device.addr == Global.addr;
+    final bool isLocal = true; // TODO
     final String name = isLocal ? (device.name + " (${lang.deviceLocal})") : device.name;
 
     return Container(
@@ -126,10 +126,6 @@ class _DevicesPageState extends State<DevicesPage> {
             ? Icon(Icons.cloud_done_rounded, size: 38.0, color: Color(0xFF6174FF))
             : Icon(Icons.cloud_off_rounded, size: 38.0, color: Colors.grey),
             title: Text(name),
-            subtitle: Container(
-              padding: const EdgeInsets.only(top: 8.0),
-              child: Text(addrPrint(device.addr))
-            ),
           ),
           Row(
             mainAxisAlignment: MainAxisAlignment.spaceEvenly,
@@ -207,13 +203,12 @@ class _DevicesPageState extends State<DevicesPage> {
                   Icons.security_rounded,
                   lang.verifyPin,
                   PinWords(
-                    gid: account.gid,
+                    pid: account.pid,
                     callback: (key) async {
                       Navigator.of(context).pop();
                       _showQrCode(
                         account.name,
-                        account.gid,
-                        Global.addr,
+                        account.pid,
                         key,
                         color,
                         lang,
diff --git a/lib/apps/group/detail.dart b/lib/apps/group/detail.dart
index a32c83e..5c28b63 100644
--- a/lib/apps/group/detail.dart
+++ b/lib/apps/group/detail.dart
@@ -289,7 +289,7 @@ class _GroupChatDetailState extends State<GroupChatDetail> {
               final msg = this._messages[recentMessageKeys[index]]!;
               return ChatMessage(
                 avatar: this._members[msg.mid]!.showAvatar(isOnline: false),
-                fgid: this._members[msg.mid]!.mid,
+                fpid: this._members[msg.mid]!.mid,
                 name: this._members[msg.mid]!.name,
                 message: msg,
               );
@@ -336,7 +336,6 @@ class _MemberScreenState extends State<_MemberScreen> {
             app: 'add-friend',
             id: member.mid,
             name: member.name,
-            addr: member.addr,
             title: lang.qrFriend,
           ),
           0.0,
diff --git a/lib/apps/group/models.dart b/lib/apps/group/models.dart
index 672b9cf..4ae9acc 100644
--- a/lib/apps/group/models.dart
+++ b/lib/apps/group/models.dart
@@ -47,7 +47,7 @@ class Member {
     this.addr = params[3];
     this.name = params[4];
     this.leave = params[5];
-    if (this.addr == Global.addr) {
+    if (this.mid == Global.pid) {
       this.online = true;
     }
   }
diff --git a/lib/apps/jarvis/detail.dart b/lib/apps/jarvis/detail.dart
index 816f6e8..10ce312 100644
--- a/lib/apps/jarvis/detail.dart
+++ b/lib/apps/jarvis/detail.dart
@@ -120,7 +120,7 @@ class _JarvisDetailState extends State<JarvisDetail> {
               itemCount: recentMessageKeys.length,
               reverse: true,
               itemBuilder: (BuildContext context, index) => ChatMessage(
-                fgid: '',
+                fpid: '',
                 name: lang.jarvis,
                 message: this._messages[recentMessageKeys[index]]!,
               )
diff --git a/lib/apps/primitives.dart b/lib/apps/primitives.dart
index e969f89..de83051 100644
--- a/lib/apps/primitives.dart
+++ b/lib/apps/primitives.dart
@@ -154,7 +154,7 @@ class BaseMessage {
 
   List showInvite() {
     var type = GroupType.Tmp;
-    var gid = '';
+    var pid = '';
     var addr = '';
     var name = '';
     var proof = '';
@@ -166,12 +166,12 @@ class BaseMessage {
     }
 
     final raw_0 = this.content.substring(iType + 2);
-    final iGid = raw_0.indexOf(';;');
-    if (iGid > 0) {
-      gid = raw_0.substring(0, iGid);
+    final iPid = raw_0.indexOf(';;');
+    if (iPid > 0) {
+      pid = raw_0.substring(0, iPid);
     }
 
-    final raw_1 = raw_0.substring(iGid + 2);
+    final raw_1 = raw_0.substring(iPid + 2);
     final iAddr = raw_1.indexOf(';;');
     if (iAddr > 0) {
       addr = raw_1.substring(0, iAddr);
@@ -183,7 +183,7 @@ class BaseMessage {
       name = raw_2.substring(0, iName).replaceAll('-;', ';');
     } else {
       name = raw_2.replaceAll('-;', ';');
-      return [type, gid, addr, name, proof, key];
+      return [type, pid, addr, name, proof, key];
     }
 
     final raw_3 = raw_2.substring(iName + 2);
@@ -195,7 +195,7 @@ class BaseMessage {
       proof = raw_3;
     }
 
-    return [type, gid, addr, name, proof, key];
+    return [type, pid, addr, name, proof, key];
   }
 
   // [hash, to, amount, name, network]
diff --git a/lib/apps/wallet/page.dart b/lib/apps/wallet/page.dart
index 0788c7d..0308567 100644
--- a/lib/apps/wallet/page.dart
+++ b/lib/apps/wallet/page.dart
@@ -1025,7 +1025,7 @@ class _TransferTokenState extends State<_TransferToken> {
                         items: this._nft.map((value) {
                             return DropdownMenuItem<String>(
                               value: value,
-                              child: Text(gidPrint(value, '', 6)),
+                              child: Text(pidPrint(value, '', 6)),
                             );
                         }).toList(),
                       ),
@@ -1090,13 +1090,13 @@ class _TransferTokenState extends State<_TransferToken> {
               return;
             }
             final amount = restoreBalance(a, widget.token.decimal);
-            final gid = context.read<AccountProvider>().activedAccount.gid;
+            final pid = context.read<AccountProvider>().activedAccount.pid;
             showShadowDialog(
               context,
               Icons.security_rounded,
               lang.verifyPin,
               PinWords(
-                gid: gid,
+                pid: pid,
                 callback: (key) async {
                   Navigator.of(context).pop();
                   rpc.send('wallet-transfer', [
@@ -1248,7 +1248,7 @@ class _ImportNftState extends State<_ImportNft> {
             itemBuilder: (BuildContext context, int index) {
               final hash = this._nft[index];
               return ListTile(
-                title: Text('TokenID: ' + gidPrint(hash, '', 6)),
+                title: Text('TokenID: ' + pidPrint(hash, '', 6)),
                 trailing: IconButton(icon: Icon(Icons.link, color: color.primary),
                   onPressed: () {
                     launch(widget.token.nftUrl(hash));
diff --git a/lib/global.dart b/lib/global.dart
index ad6e49b..ad62e12 100644
--- a/lib/global.dart
+++ b/lib/global.dart
@@ -1,6 +1,6 @@
 class Global {
   static String version = 'v0.5.0';
-  static String gid = '0000000000000000000000000000000000000000000000000000000000000000';
+  static String pid = '0000000000000000000000000000000000000000000000000000000000000000';
   static String httpRpc = '127.0.0.1:7365';
   static String wsRpc = '127.0.0.1:7366';
   //static String httpRpc = '192.168.2.148:8001';  // test code
@@ -8,24 +8,23 @@ class Global {
   //static String httpRpc = '192.168.50.250:8001'; // test code
   //static String wsRpc = '192.168.50.250:8081';   // test code
   static String optionCache = 'option';
-  static String addr = '0x';
 
   static String home = '.tdn';
-  static String filePath   = home + '/' + gid + '/files/';
-  static String imagePath  = home + '/' + gid + '/images/';
-  static String thumbPath  = home + '/' + gid + '/thumbs/';
-  static String emojiPath  = home + '/' + gid + '/emojis/';
-  static String recordPath = home + '/' + gid + '/records/';
-  static String avatarPath = home + '/' + gid + '/avatars/';
+  static String filePath   = home + '/' + pid + '/files/';
+  static String imagePath  = home + '/' + pid + '/images/';
+  static String thumbPath  = home + '/' + pid + '/thumbs/';
+  static String emojiPath  = home + '/' + pid + '/emojis/';
+  static String recordPath = home + '/' + pid + '/records/';
+  static String avatarPath = home + '/' + pid + '/avatars/';
 
-  static changeGid(String gid) {
-    Global.gid = gid;
-    Global.filePath   = home + '/' + gid + '/files/';
-    Global.imagePath  = home + '/' + gid + '/images/';
-    Global.thumbPath  = home + '/' + gid + '/thumbs/';
-    Global.emojiPath  = home + '/' + gid + '/emojis/';
-    Global.recordPath = home + '/' + gid + '/records/';
-    Global.avatarPath = home + '/' + gid + '/avatars/';
+  static changePid(String pid) {
+    Global.pid = pid;
+    Global.filePath   = home + '/' + pid + '/files/';
+    Global.imagePath  = home + '/' + pid + '/images/';
+    Global.thumbPath  = home + '/' + pid + '/thumbs/';
+    Global.emojiPath  = home + '/' + pid + '/emojis/';
+    Global.recordPath = home + '/' + pid + '/records/';
+    Global.avatarPath = home + '/' + pid + '/avatars/';
   }
 
   static changeWs(String newWs) {
diff --git a/lib/pages/account_quick.dart b/lib/pages/account_quick.dart
index 667c27e..448d6df 100644
--- a/lib/pages/account_quick.dart
+++ b/lib/pages/account_quick.dart
@@ -140,15 +140,20 @@ class _AccountQuickPageState extends State<AccountQuickPage> {
     ]);
 
     if (res.isOk) {
-      // save this User
-      final account = Account(res.params[0], name, avatar);
+      final pid = res.params[0];
+      final login = await httpPost('account-login', [pid, lock]);
 
-      Provider.of<AccountProvider>(context, listen: false).addAccount(account, lock);
-      Provider.of<DeviceProvider>(context, listen: false).updateActived();
+      if (login.isOk) {
+        // save this User
+        final account = Account(pid, name, avatar);
 
-      Navigator.push(context, MaterialPageRoute(builder: (_) => AccountDomainScreen(
-            name: name,
-      )));
+        Provider.of<AccountProvider>(context, listen: false).addAccount(account, lock);
+        Provider.of<DeviceProvider>(context, listen: false).updateActived();
+
+        Navigator.push(context, MaterialPageRoute(builder: (_) => AccountDomainScreen(
+              name: name,
+        )));
+      }
     } else {
       // TODO tostor error
       print(res.error);
diff --git a/lib/pages/account_restore.dart b/lib/pages/account_restore.dart
index c500b67..a07e118 100644
--- a/lib/pages/account_restore.dart
+++ b/lib/pages/account_restore.dart
@@ -324,7 +324,7 @@ class _AccountRestorePageState extends State<AccountRestorePage> {
             Navigator.of(context).pop();
             if (app == 'distribute' && params.length == 4) {
               final name = params[0];
-              //final id = gidParse(params[1]);
+              //final id = pidParse(params[1]);
               final addr = addrParse(params[2]);
               final mnemonicWords = params[3];
               setState(() {
diff --git a/lib/pages/home.dart b/lib/pages/home.dart
index e58a1ee..b823faa 100644
--- a/lib/pages/home.dart
+++ b/lib/pages/home.dart
@@ -98,11 +98,10 @@ class _HomeListState extends State<HomeList> {
       MaterialPageRoute(
         builder: (context) => QRScan(callback: (isOk, app, params) {
             Navigator.of(context).pop();
-            if (app == 'add-friend' && params.length == 3) {
-              final id = gidParse(params[0]);
-              final addr = addrParse(params[1]);
-              final name = params[2].trim();
-              final widget = ChatAdd(id: id, addr: addr, name: name);
+            if (app == 'add-friend' && params.length == 2) {
+              final id = pidParse(params[0]);
+              final name = params[1].trim();
+              final widget = ChatAdd(id: id, name: name);
               Provider.of<AccountProvider>(context, listen: false).systemAppFriendAddNew = false;
               if (isDesktop) {
                 Provider.of<AccountProvider>(context, listen: false).updateActivedWidget(widget);
@@ -111,7 +110,7 @@ class _HomeListState extends State<HomeList> {
               }
             } else if (app == 'distribute' && params.length == 4) {
               //final _name = params[0].trim();
-              //final id = gidParse(params[1]);
+              //final id = pidParse(params[1]);
               final addr = addrParse(params[2]);
               //final _mnemonicWords = params[3];
               Provider.of<DeviceProvider>(context, listen: false).connect(addr);
@@ -174,8 +173,7 @@ class _HomeListState extends State<HomeList> {
                         UserInfo(
                           app: 'add-friend',
                           id: provider.id,
-                          name: provider.activedAccount.name,
-                          addr: Global.addr));
+                          name: provider.activedAccount.name));
                     }
                   },
                   itemBuilder: (context) {
@@ -312,7 +310,7 @@ class DrawerWidget extends StatelessWidget {
             ? () {
                 Navigator.of(context).pop();
                 Provider.of<AccountProvider>(context, listen: false)
-                    .updateActivedAccount(account.gid, account.pin);
+                    .updateActivedAccount(account.pid, account.pin);
                 Provider.of<DeviceProvider>(context, listen: false)
                     .updateActived();
               }
@@ -340,18 +338,18 @@ class DrawerWidget extends StatelessWidget {
                         Icons.security_rounded,
                         lang.verifyPin,
                         PinWords(
-                          gid: account.gid,
+                          pid: account.pid,
                           callback: (key) async {
                             Navigator.of(context).pop();
                             Provider.of<AccountProvider>(context,
                               listen: false)
-                            .onlineAccount(account.gid, key);
+                            .onlineAccount(account.pid, key);
                         }),
                         0.0,
                       );
                     } else {
                       Provider.of<AccountProvider>(context, listen: false)
-                          .offlineAccount(account.gid);
+                          .offlineAccount(account.pid);
                     }
                   },
                 ),
@@ -380,8 +378,8 @@ class DrawerWidget extends StatelessWidget {
     final accounts = provider.accounts;
 
     List<Widget> accountsWidget = [];
-    accounts.forEach((gid, account) {
-      if (gid != me.gid) {
+    accounts.forEach((pid, account) {
+      if (pid != me.pid) {
         accountsWidget.add(_listAccount(context, account, color.primary, lang));
       }
     });
diff --git a/lib/pages/setting/network.dart b/lib/pages/setting/network.dart
index c420a6e..2ed7864 100644
--- a/lib/pages/setting/network.dart
+++ b/lib/pages/setting/network.dart
@@ -26,7 +26,6 @@ class _NetworkDetailState extends State<NetworkDetail> {
   changeWs() async {
     Global.changeWs(wsController.text);
     await rpc.init(wsController.text);
-    rpc.send('system-info', []);
     setState(() {});
   }
 
@@ -42,6 +41,7 @@ class _NetworkDetailState extends State<NetworkDetail> {
 
   void loadNetworkDht() async {
     final res = await httpPost('network-dht', []);
+    print(res);
     if (res.isOk) {
       this.networkDht.clear();
       res.params.forEach((p) {
diff --git a/lib/pages/setting/profile.dart b/lib/pages/setting/profile.dart
index 59a7eb5..6583e84 100644
--- a/lib/pages/setting/profile.dart
+++ b/lib/pages/setting/profile.dart
@@ -167,8 +167,7 @@ class _ProfileDetailState extends State<ProfileDetail> {
                   crossAxisAlignment: CrossAxisAlignment.start,
                   mainAxisSize: MainAxisSize.max,
                   children: [
-                    _infoListTooltip(Icons.person, color.primary, gidText(account.gid), gidPrint(account.gid)),
-                    _infoListTooltip(Icons.location_on, color.primary, addrText(Global.addr), addrPrint(Global.addr)),
+                    _infoListTooltip(Icons.person, color.primary, pidText(account.pid), pidPrint(account.pid)),
                     SizedBox(
                       height: 40.0,
                       child: Row(
@@ -177,8 +176,8 @@ class _ProfileDetailState extends State<ProfileDetail> {
                             size: 20.0, color: color.primary),
                           const SizedBox(width: 20.0),
                           TextButton(
-                            onPressed: () => _pinCheck(account.gid,
-                              (key) => _changePin(context, account.gid, key, lang.setPin),
+                            onPressed: () => _pinCheck(account.pid,
+                              (key) => _changePin(context, account.pid, key, lang.setPin),
                               lang.verifyPin, color
                             ),
                             child: Text(lang.change + ' PIN'),
@@ -200,8 +199,8 @@ class _ProfileDetailState extends State<ProfileDetail> {
                             child: Text(lang.hide + ' ' + lang.mnemonic),
                           )
                           : TextButton(
-                            onPressed: () => _pinCheck(account.gid,
-                              (key) => _showMnemonic(account.gid, key), lang.verifyPin, color),
+                            onPressed: () => _pinCheck(account.pid,
+                              (key) => _showMnemonic(account.pid, key), lang.verifyPin, color),
                             child: Text(lang.show + ' ' + lang.mnemonic),
                           ),
                       ]),
@@ -278,13 +277,13 @@ class _ProfileDetailState extends State<ProfileDetail> {
     }
   }
 
-  _pinCheck(String gid, Function callback, String title, color) {
+  _pinCheck(String pid, Function callback, String title, color) {
     showShadowDialog(
       context,
       Icons.security_rounded,
       title,
       PinWords(
-        gid: gid,
+        pid: pid,
         callback: (key) async {
           Navigator.of(context).pop();
           callback(key);
diff --git a/lib/provider.dart b/lib/provider.dart
index 395812f..aa407e8 100644
--- a/lib/provider.dart
+++ b/lib/provider.dart
@@ -14,12 +14,12 @@ const DEFAULT_ONLINE_INIT = 8;
 const DEFAULT_ONLINE_DELAY = 5;
 
 class AccountProvider extends ChangeNotifier {
-  Map<String, Account> accounts = {}; // account's gid and account.
-  String activedAccountId = ''; // actived account gid.
+  Map<String, Account> accounts = {}; // account's pid and account.
+  String activedAccountId = ''; // actived account pid.
   Account get activedAccount => this.accounts[activedAccountId]!;
 
   /// current user's did.
-  String get id => this.activedAccount.gid;
+  String get id => this.activedAccount.pid;
 
   bool systemAppFriendAddNew = false;
 
@@ -48,7 +48,6 @@ class AccountProvider extends ChangeNotifier {
     rpc.addNotice(_accountNotice);
 
     // rpc
-    rpc.addListener('account-system-info', _systemInfo);
     rpc.addListener('account-update', _accountUpdate);
     rpc.addListener('account-login', _accountLogin);
 
@@ -65,28 +64,26 @@ class AccountProvider extends ChangeNotifier {
   }
 
   /// when security load accounts from cache.
-  autoAccounts(String gid, String pin, Map<String, Account> accounts) {
-    Global.changeGid(gid);
+  autoAccounts(String pid, String pin, Map<String, Account> accounts) {
+    Global.changePid(pid);
     this.accounts = accounts;
 
-    this.activedAccountId = gid;
+    this.activedAccountId = pid;
     this.activedAccount.online = true;
     this.activedAccount.pin = pin;
 
     rpc.send('session-list', []);
-    new Future.delayed(Duration(seconds: DEFAULT_ONLINE_INIT),
-      () => rpc.send('account-online', [gid]));
 
-    initLogined(gid, this.accounts.values.toList());
+    initLogined(pid, this.accounts.values.toList());
     this.coreShowWidget = DefaultCoreShow();
   }
 
   /// when security add account.
   addAccount(Account account, String pin) {
-    Global.changeGid(account.gid);
-    this.accounts[account.gid] = account;
+    Global.changePid(account.pid);
+    this.accounts[account.pid] = account;
 
-    this.activedAccountId = account.gid;
+    this.activedAccountId = account.pid;
     this.activedAccount.online = true;
     this.activedAccount.pin = pin;
 
@@ -94,11 +91,11 @@ class AccountProvider extends ChangeNotifier {
     updateLogined(account);
   }
 
-  updateActivedAccount(String gid, String pin) {
-    Global.changeGid(gid);
+  updateActivedAccount(String pid, String pin) {
+    Global.changePid(pid);
     this.clearActivedAccount();
 
-    this.activedAccountId = gid;
+    this.activedAccountId = pid;
     this.activedAccount.online = true;
     this.activedAccount.pin = pin;
     this.activedAccount.hasNew = false;
@@ -113,11 +110,9 @@ class AccountProvider extends ChangeNotifier {
 
     if (!this.activedAccount.online) {
       this.activedAccount.online = true;
-      new Future.delayed(Duration(seconds: DEFAULT_ONLINE_DELAY),
-          () => rpc.send('account-online', [gid]));
     }
 
-    mainLogined(gid);
+    mainLogined(pid);
     notifyListeners();
   }
 
@@ -133,25 +128,22 @@ class AccountProvider extends ChangeNotifier {
     clearLogined();
   }
 
-  onlineAccount(String gid, String pin) {
-    this.accounts[gid]!.online = true;
-    this.accounts[gid]!.pin = pin;
+  onlineAccount(String pid, String pin) {
+    this.accounts[pid]!.online = true;
+    this.accounts[pid]!.pin = pin;
 
-    rpc.send('account-login', [gid, pin]);
-
-    new Future.delayed(Duration(seconds: DEFAULT_ONLINE_DELAY),
-        () => rpc.send('account-online', [gid]));
+    rpc.send('account-login', [pid, pin]);
     notifyListeners();
   }
 
-  offlineAccount(String gid) {
-    this.accounts[gid]!.online = false;
-    this.accounts[gid]!.pin = '';
+  offlineAccount(String pid) {
+    this.accounts[pid]!.online = false;
+    this.accounts[pid]!.pin = '';
 
-    if (gid == this.activedAccountId) {
+    if (pid == this.activedAccountId) {
       this.clearActivedAccount();
     }
-    rpc.send('account-offline', [gid]);
+    rpc.send('account-offline', [pid]);
 
     notifyListeners();
   }
@@ -181,7 +173,7 @@ class AccountProvider extends ChangeNotifier {
 
   clearActivedSession(SessionType type) {
     if (this.actived > 0 && this.activedSession.type == type) {
-      rpc.send('session-suspend', [this.actived, this.activedSession.gid,
+      rpc.send('session-suspend', [this.actived, this.activedSession.pid,
           this.activedSession.type == SessionType.Group]
       );
       this.actived = 0;
@@ -202,7 +194,7 @@ class AccountProvider extends ChangeNotifier {
 
     if (id > 0) {
       if (this.actived != id && this.actived > 0) {
-        rpc.send('session-suspend', [this.actived, this.activedSession.gid,
+        rpc.send('session-suspend', [this.actived, this.activedSession.pid,
             this.activedSession.type == SessionType.Group]
         );
       }
@@ -219,7 +211,7 @@ class AccountProvider extends ChangeNotifier {
               }
           });
         }
-        rpc.send('session-connect', [id, this.activedSession.gid]);
+        rpc.send('session-connect', [id, this.activedSession.pid]);
         notifyListeners();
       }
     }
@@ -237,17 +229,13 @@ class AccountProvider extends ChangeNotifier {
   }
 
   // -- callback when receive rpc info. -- //
-  _systemInfo(List params) {
-    Global.addr = params[0];
-  }
-
   _accountLogin(List _params) {
     // nothing.
   }
 
-  _accountNotice(String gid) {
-    if (this.accounts.containsKey(gid)) {
-      this.accounts[gid]!.hasNew = true;
+  _accountNotice(String pid) {
+    if (this.accounts.containsKey(pid)) {
+      this.accounts[pid]!.hasNew = true;
       notifyListeners();
     }
   }
@@ -261,10 +249,10 @@ class AccountProvider extends ChangeNotifier {
   }
 
   _accountUpdate(List params) {
-    final gid = params[0];
-    this.accounts[gid]!.name = params[1];
+    final pid = params[0];
+    this.accounts[pid]!.name = params[1];
     if (params[2].length > 1) {
-      this.accounts[gid]!.updateAvatar(params[2]);
+      this.accounts[pid]!.updateAvatar(params[2]);
     }
     notifyListeners();
   }
diff --git a/lib/security.dart b/lib/security.dart
index b62ad94..663dc81 100644
--- a/lib/security.dart
+++ b/lib/security.dart
@@ -182,11 +182,11 @@ class _SecurityPageState extends State<SecurityPage> {
       final mainAccount = loginedAccounts[0];
       Map<String, Account> accounts = {};
       loginedAccounts.forEach((account) {
-          accounts[account.gid] = account;
+          accounts[account.pid] = account;
       });
-      final res = await httpPost('account-login', [mainAccount.gid, ""]);
+      final res = await httpPost('account-login', [mainAccount.pid, ""]);
       if (res.isOk) {
-        _handleLogined(mainAccount.gid, "", accounts);
+        _handleLogined(mainAccount.pid, "", accounts);
         return;
       } else {
         showShadowDialog(
@@ -194,10 +194,10 @@ class _SecurityPageState extends State<SecurityPage> {
           Icons.security_rounded,
           "PIN",
           PinWords(
-            gid: mainAccount.gid,
+            pid: mainAccount.pid,
             callback: (key) async {
               Navigator.of(context).pop();
-              _handleLogined(mainAccount.gid, key, accounts);
+              _handleLogined(mainAccount.pid, key, accounts);
               return;
           }),
           0.0
@@ -215,7 +215,7 @@ class _SecurityPageState extends State<SecurityPage> {
 
       if (this._accounts.length > 0) {
         final accountId = this._accounts.keys.first;
-        this._selectedUserId = this._accounts[accountId]!.gid;
+        this._selectedUserId = this._accounts[accountId]!.pid;
         this._accountsLoaded = true;
       }
     } else {
@@ -242,7 +242,7 @@ class _SecurityPageState extends State<SecurityPage> {
       Icons.security_rounded,
       title,
       PinWords(
-        gid: this._selectedUserId,
+        pid: this._selectedUserId,
         callback: (pinWords) async {
           Navigator.of(context).pop();
           _verifyAfter(pinWords);
@@ -268,16 +268,16 @@ class _SecurityPageState extends State<SecurityPage> {
             iconEnabledColor: Color(0xFFADB0BB),
             isExpanded: true,
             value: this._selectedUserId,
-            onChanged: (String? gid) {
-              if (gid != null) {
+            onChanged: (String? pid) {
+              if (pid != null) {
                 setState(() {
-                    this._selectedUserId = gid;
+                    this._selectedUserId = pid;
                   });
               }
             },
             items: this._accounts.values.map((Account account) {
                 return DropdownMenuItem<String>(
-                  value: account.gid,
+                  value: account.pid,
                   child: Row(
                     children: [
                       Expanded(
@@ -287,7 +287,7 @@ class _SecurityPageState extends State<SecurityPage> {
                           style: TextStyle(fontSize: 16)
                         ),
                       ),
-                      Text(" (${gidPrint(account.gid)})", style: TextStyle(fontSize: 16)),
+                      Text(" (${pidPrint(account.pid)})", style: TextStyle(fontSize: 16)),
                     ]
                   ),
                 );
diff --git a/lib/session.dart b/lib/session.dart
index 32108d3..f2f1a09 100644
--- a/lib/session.dart
+++ b/lib/session.dart
@@ -41,7 +41,7 @@ enum OnlineType {
 class Session {
   int id;
   int fid;
-  String gid;
+  String pid;
   String addr;
   SessionType type;
   String name;
@@ -147,7 +147,17 @@ class Session {
   }
 
   Avatar showAvatar({double width = 45.0}) {
-    final avatar = Global.avatarPath + this.gid + '.png';
+    String avatar = Global.avatarPath;
+    switch (this.type) {
+      case SessionType.Chat:
+        avatar + this.pid + '.png';
+        break;
+      case SessionType.Group:
+        avatar + 'group_' + this.pid + '.png';
+        break;
+      default:
+        break;
+    }
 
     Color color;
     switch (this.online) {
@@ -194,7 +204,7 @@ class Session {
   Session.fromList(List params)
       : this.id = params[0],
         this.fid = params[1],
-        this.gid = params[2],
+        this.pid = params[2],
         this.addr = params[3],
         this.type = SessionTypeExtension.fromInt(params[4]),
         this.name = params[5],
diff --git a/lib/utils/better_print.dart b/lib/utils/better_print.dart
index 35a1750..882b76d 100644
--- a/lib/utils/better_print.dart
+++ b/lib/utils/better_print.dart
@@ -1,16 +1,16 @@
-String gidText(String? gid, [String pre='EH']) {
-  if (gid == null) {
+String pidText(String? pid, [String pre='EH']) {
+  if (pid == null) {
     return '';
   }
-  return pre + gid.toUpperCase();
+  return pre + pid.toUpperCase();
 }
 
-String gidPrint(String? gid, [String pre='EH', int n = 4]) {
-  if (gid == null) {
+String pidPrint(String? pid, [String pre='EH', int n = 6]) {
+  if (pid == null) {
     return '';
   }
 
-  final info = gid.toUpperCase();
+  final info = pid.toUpperCase();
   final len = info.length;
   if (len > n+n) {
     return pre + info.substring(0, n) + '...' + info.substring(len - n, len);
@@ -19,11 +19,11 @@ String gidPrint(String? gid, [String pre='EH', int n = 4]) {
   }
 }
 
-String gidParse(String gid, [String pre='EH']) {
-  if (gid.length > 2 && gid.substring(0, 2) == pre) {
-    return gid.substring(2);
+String pidParse(String pid, [String pre='EH']) {
+  if (pid.length > 2 && pid.substring(0, 2) == pre) {
+    return pid.substring(2);
   } else {
-    return gid;
+    return pid;
   }
 }
 
diff --git a/lib/utils/logined_cache.dart b/lib/utils/logined_cache.dart
index 6fade09..0e367b5 100644
--- a/lib/utils/logined_cache.dart
+++ b/lib/utils/logined_cache.dart
@@ -14,7 +14,7 @@ Future<List<Account>> getLogined() async {
       final fields = prefs.getStringList(id);
       if (fields != null && fields.length == 5) {
         accounts.add(Account(
-          fields[0], // gid
+          fields[0], // pid
           fields[1], // name
           fields[2], // avatar
           false,
@@ -28,7 +28,7 @@ Future<List<Account>> getLogined() async {
   return accounts;
 }
 
-initLogined(String gid, List<Account> accounts) async {
+initLogined(String pid, List<Account> accounts) async {
   SharedPreferences prefs = await SharedPreferences.getInstance();
   final ids = prefs.getStringList(LOGINED_CACHE_NAME);
   if (ids != null) {
@@ -37,19 +37,19 @@ initLogined(String gid, List<Account> accounts) async {
     });
   }
 
-  List<String> newIds = [gid];
+  List<String> newIds = [pid];
   accounts.forEach((account) {
     final List<String> fields = [
-      account.gid,
+      account.pid,
       account.name,
       account.encodeAvatar(),
     ];
 
-    if (account.gid != gid) {
-      newIds.add(account.gid);
+    if (account.pid != pid) {
+      newIds.add(account.pid);
     }
 
-    prefs.setStringList(account.gid, fields);
+    prefs.setStringList(account.pid, fields);
   });
 
   prefs.setStringList(LOGINED_CACHE_NAME, newIds);
@@ -64,44 +64,44 @@ updateLogined(Account account) async {
   }
 
 
-  if (!ids.contains(account.gid)) {
-    ids.add(account.gid);
+  if (!ids.contains(account.pid)) {
+    ids.add(account.pid);
     prefs.setStringList(LOGINED_CACHE_NAME, ids);
   }
 
   final List<String> fields = [
-    account.gid,
+    account.pid,
     account.name,
     account.encodeAvatar(),
   ];
 
-  prefs.setStringList(account.gid, fields);
+  prefs.setStringList(account.pid, fields);
 }
 
 /// change main logined account.
-mainLogined(String gid) async {
+mainLogined(String pid) async {
   SharedPreferences prefs = await SharedPreferences.getInstance();
   List<String>? ids = prefs.getStringList(LOGINED_CACHE_NAME);
   if (ids == null) {
     ids = [];
   }
 
-  ids.remove(gid);
-  ids.insert(0, gid);
+  ids.remove(pid);
+  ids.insert(0, pid);
   prefs.setStringList(LOGINED_CACHE_NAME, ids);
 }
 
 /// remove auto-login accounts.
-removeLogined(String gid) async {
+removeLogined(String pid) async {
   SharedPreferences prefs = await SharedPreferences.getInstance();
-  prefs.remove(gid);
+  prefs.remove(pid);
   List<String>? ids = prefs.getStringList(LOGINED_CACHE_NAME);
   if (ids == null) {
     ids = [];
   }
 
-  if (ids.contains(gid)) {
-    ids.remove(gid);
+  if (ids.contains(pid)) {
+    ids.remove(pid);
     prefs.setStringList(LOGINED_CACHE_NAME, ids);
   }
 }
diff --git a/lib/widgets/chat_message.dart b/lib/widgets/chat_message.dart
index 1920a7e..ba1e7d3 100644
--- a/lib/widgets/chat_message.dart
+++ b/lib/widgets/chat_message.dart
@@ -22,13 +22,13 @@ import 'package:esse/apps/wallet/models.dart' show NetworkExtension, Network, To
 
 class ChatMessage extends StatelessWidget {
   final Widget? avatar;
-  final String fgid;
+  final String fpid;
   final String name;
   final BaseMessage message;
 
-  const ChatMessage({Key? key, required this.fgid, required this.name, required this.message, this.avatar}): super(key: key);
+  const ChatMessage({Key? key, required this.fpid, required this.name, required this.message, this.avatar}): super(key: key);
 
-  Widget _showContactCard(Widget avatar, String gid, String name, String title, ColorScheme color, [String pre='EH']) {
+  Widget _showContactCard(Widget avatar, String pid, String name, String title, ColorScheme color, [String pre='EH']) {
     return Container(
       padding: const EdgeInsets.only(top: 10, bottom: 6.0, left: 10.0, right: 10.0),
       width: 200.0,
@@ -41,7 +41,7 @@ class ChatMessage extends StatelessWidget {
                 child: Column(children: [
                     Text(name, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(color: color.onPrimary, fontSize: 16.0)),
                     const SizedBox(height: 4.0),
-                    Text(gidPrint(gid, pre), style: TextStyle(color: Colors.grey, fontSize: 12.0)),
+                    Text(pidPrint(pid, pre), style: TextStyle(color: Colors.grey, fontSize: 12.0)),
           ]))]),
           const SizedBox(height: 5.0),
           const Divider(height: 1.0, color: Color(0x40ADB0BB)),
@@ -220,7 +220,7 @@ class ChatMessage extends StatelessWidget {
   }
 
   Widget _showContact(context, lang, color, maxWidth) {
-    // contact [name, gid, addr, avatar]
+    // contact [name, pid, avatar]
     final infos = message.showContact();
     if (infos[1].length > 0) {
       return GestureDetector(
@@ -229,7 +229,7 @@ class ChatMessage extends StatelessWidget {
           Icons.person_rounded,
           lang.contactCard,
           UserInfo(
-            showQr: false, id: infos[1], addr: infos[2], name: infos[0],
+            showQr: false, id: infos[1], name: infos[0],
             remark: lang.fromContactCard(name),
             avatar: Avatar(width: 100.0, name: infos[0], avatarPath: infos[3]),
             callback: () {
@@ -251,7 +251,7 @@ class ChatMessage extends StatelessWidget {
   }
 
   Widget _showInvite(context, lang, color, maxWidth) {
-    // contact [type, gid, addr, name, proof, key]
+    // contact [type, pid, addr, name, proof, key]
     final infos = message.showInvite();
     if (infos[1].length > 0) {
       final GroupType gtype = infos[0];
@@ -260,7 +260,7 @@ class ChatMessage extends StatelessWidget {
           context,
           Icons.groups_rounded,
           lang.groupChat,
-          UserInfo(showQr: false, id: infos[1], addr: infos[2], name: infos[3], pre: 'EG',
+          UserInfo(showQr: false, id: infos[1], name: infos[3], pre: 'EG',
             title: gtype.lang(lang),
             avatar: Container(width: 100.0, height: 100.0,
               padding: const EdgeInsets.all(8.0),
@@ -271,7 +271,7 @@ class ChatMessage extends StatelessWidget {
               Navigator.pop(context);
               // TOOD join invite.
               // Provider.of<GroupChatProvider>(context, listen: false).join(
-              //   gtype, infos[1], infos[2], infos[3], fgid, infos[4], infos[5]
+              //   gtype, infos[1], infos[2], infos[3], fpid, infos[4], infos[5]
               // );
             },
           ),
diff --git a/lib/widgets/show_contact.dart b/lib/widgets/show_contact.dart
index 4b50c97..0dbc745 100644
--- a/lib/widgets/show_contact.dart
+++ b/lib/widgets/show_contact.dart
@@ -40,7 +40,7 @@ class _ContactListState extends State<ContactList> {
         List<Friend> offlines = [];
         res.params.forEach((params) {
             final friend = Friend.fromList(params);
-            if (!widget.filters.contains(friend.gid)) {
+            if (!widget.filters.contains(friend.pid)) {
               if (friend.online) {
                 onlines.add(friend);
               } else {
@@ -52,7 +52,7 @@ class _ContactListState extends State<ContactList> {
       } else {
         res.params.forEach((params) {
             final friend = Friend.fromList(params);
-            if (!widget.filters.contains(friend.gid)) {
+            if (!widget.filters.contains(friend.pid)) {
               this._friends.add(friend);
             }
         });
diff --git a/lib/widgets/show_pin.dart b/lib/widgets/show_pin.dart
index d6ed2d8..1973275 100644
--- a/lib/widgets/show_pin.dart
+++ b/lib/widgets/show_pin.dart
@@ -56,9 +56,9 @@ Widget _keyboradInput(Color color, Color bg, String text, Function callback) {
 
 class PinWords extends StatefulWidget {
   final Function callback;
-  final String gid;
+  final String pid;
 
-  PinWords({Key? key, required this.gid, required this.callback}) : super(key: key);
+  PinWords({Key? key, required this.pid, required this.callback}) : super(key: key);
 
   @override
   _PinWordsState createState() => _PinWordsState();
@@ -71,7 +71,7 @@ class _PinWordsState extends State<PinWords> {
 
   _checkPin() async {
     bool check = false;
-    final res = await httpPost('account-pin-check', [widget.gid, _pinWords]);
+    final res = await httpPost('account-pin-check', [widget.pid, _pinWords]);
     if (res.isOk) {
       check = res.params[0];
     } else {
diff --git a/lib/widgets/transfer.dart b/lib/widgets/transfer.dart
index d94b86c..82545f5 100644
--- a/lib/widgets/transfer.dart
+++ b/lib/widgets/transfer.dart
@@ -353,13 +353,13 @@ class _TransferState extends State<Transfer> {
               return;
             }
             final amount = restoreBalance(a, this._selectedToken.decimal);
-            final gid = context.read<AccountProvider>().activedAccount.gid;
+            final pid = context.read<AccountProvider>().activedAccount.pid;
             showShadowDialog(
               context,
               Icons.security_rounded,
               lang.verifyPin,
               PinWords(
-                gid: gid,
+                pid: pid,
                 callback: (key) async {
                   if (this._main.length < 2) {
                     return;
diff --git a/lib/widgets/user_info.dart b/lib/widgets/user_info.dart
index 8f91aec..31eacea 100644
--- a/lib/widgets/user_info.dart
+++ b/lib/widgets/user_info.dart
@@ -11,7 +11,6 @@ class UserInfo extends StatefulWidget {
   final String? app;
   final String id;
   final String name;
-  final String addr;
   final String? title;
   final String? remark;
   final String? bio;
@@ -23,7 +22,6 @@ class UserInfo extends StatefulWidget {
 
   UserInfo({Key? key,
       required this.id,
-      required this.addr,
       required this.name,
       this.app,
       this.remark,
@@ -37,7 +35,7 @@ class UserInfo extends StatefulWidget {
     if (this.showQr) {
       this.qrInfo = {
         "app": this.app,
-        "params": [gidText(this.id, this.pre), addrText(this.addr), this.name],
+        "params": [pidText(this.id, this.pre), this.name],
       };
     }
   }
@@ -48,7 +46,6 @@ class UserInfo extends StatefulWidget {
 
 class _UserInfoState extends State<UserInfo> {
   bool idCopy = false;
-  bool addrCopy = false;
 
   @override
   Widget build(BuildContext context) {
@@ -57,7 +54,7 @@ class _UserInfoState extends State<UserInfo> {
 
 
     Color idColor = idCopy ? color.primary : color.onPrimary;
-    Color addrColor = addrCopy ? color.primary : color.onPrimary;
+    print(pidText(widget.id));
 
     return Column(
       mainAxisAlignment: MainAxisAlignment.center,
@@ -114,47 +111,28 @@ class _UserInfoState extends State<UserInfo> {
         const SizedBox(height: 20),
         InkWell(
           onTap: () {
-            Clipboard.setData(ClipboardData(text: gidText(widget.id)));
+            Clipboard.setData(ClipboardData(text: pidText(widget.id)));
             setState(() {
                 idCopy = true;
-                addrCopy = false;
             });
           },
           child: Container(
             width: 250.0,
             child: Row(
               children: [
-                Icon(Icons.person, size: 20.0, color: color.primary),
-                Spacer(),
-                Text(gidPrint(widget.id, widget.pre), style: TextStyle(fontSize: 14, color: idColor)),
-                Spacer(),
-                Icon(idCopy ? Icons.file_copy : Icons.copy, size: 20.0, color: color.primary),
+                Expanded(
+                  child: Text(pidText(widget.id, widget.pre),
+                    style: TextStyle(fontSize: 14, color: idColor))),
+                Padding(
+                  padding: const EdgeInsets.symmetric(horizontal: 10.0),
+                  child: Icon(idCopy ? Icons.file_copy : Icons.copy,
+                    size: 20.0, color: color.primary),
+                ),
               ]
             ),
           )
         ),
         const SizedBox(height: 16),
-        InkWell(
-          onTap: () {
-            Clipboard.setData(ClipboardData(text: addrText(widget.addr)));
-            setState(() {
-                idCopy = false;
-                addrCopy = true;
-            });
-          },
-          child: Container(
-            width: 250.0,
-            child: Row(
-              children: [
-                Icon(Icons.location_on, size: 20.0, color: color.primary),
-                Spacer(),
-                Text(addrPrint(widget.addr), style: TextStyle(fontSize: 14, color: addrColor)),
-                Spacer(),
-                Icon(addrCopy ? Icons.file_copy : Icons.copy, size: 20.0, color: color.primary),
-              ]
-            ),
-          )
-        ),
         if (widget.remark != null)
         Container(
           width: 250.0,
diff --git a/src/apps.rs b/src/apps.rs
index ed48be8..b0fb9d4 100644
--- a/src/apps.rs
+++ b/src/apps.rs
@@ -31,6 +31,7 @@ pub(crate) fn app_rpc_inject(handler: &mut RpcHandler<Global>) {
     //cloud::new_rpc_handler(handler);
 }
 
+#[allow(non_snake_case)]
 pub(crate) async fn app_layer_handle(
     fgid: GroupId,
     msg: RecvType,
@@ -55,7 +56,7 @@ pub(crate) async fn app_layer_handle(
 
                 let mut delete = vec![];
                 for (gid, session) in &layer.groups {
-                    if session.pid == peer.id {
+                    if session.addr == peer.id {
                         delete.push(*gid);
                         results.rpcs.push(session_lost(&session.s_id));
                     }
diff --git a/src/apps/chat/models/friend.rs b/src/apps/chat/models/friend.rs
index 07f1b45..33ef7e6 100644
--- a/src/apps/chat/models/friend.rs
+++ b/src/apps/chat/models/friend.rs
@@ -72,6 +72,7 @@ impl Friend {
     pub fn to_session(&self) -> Session {
         Session::new(
             self.id,
+            id_to_str(&self.pid),
             self.pid,
             SessionType::Chat,
             self.name.clone(),
diff --git a/src/apps/chat/models/request.rs b/src/apps/chat/models/request.rs
index 06574b9..56bec98 100644
--- a/src/apps/chat/models/request.rs
+++ b/src/apps/chat/models/request.rs
@@ -65,7 +65,6 @@ impl Request {
         json!([
             self.id,
             id_to_str(&self.pid),
-            self.pid.to_hex(),
             self.name,
             self.remark,
             self.is_me,
@@ -77,7 +76,7 @@ impl Request {
     }
 
     pub fn get_id(db: &DStorage, pid: &PeerId) -> Result<Request> {
-        let sql = format!("SELECT id, pid, name, remark, is_me, is_ok, is_over, is_delivery, datetime FROM requests WHERE pid = '{}'", pid.to_hex());
+        let sql = format!("SELECT id, pid, name, remark, is_me, is_ok, is_over, is_delivery, datetime FROM requests WHERE pid = '{}'", id_to_str(pid));
         let mut matrix = db.query(&sql)?;
         if matrix.len() > 0 {
             Ok(Request::from_values(matrix.pop().unwrap())) // safe unwrap()
diff --git a/src/apps/chat/rpc.rs b/src/apps/chat/rpc.rs
index 7ae7b92..e17e26c 100644
--- a/src/apps/chat/rpc.rs
+++ b/src/apps/chat/rpc.rs
@@ -258,9 +258,8 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<Global>) {
         "chat-request-create",
         |params: Vec<RpcParam>, state: Arc<Global>| async move {
             let remote_pid = id_from_str(params[0].as_str().ok_or(RpcError::ParseError)?)?;
-            let remote_addr = PeerId::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?;
-            let remote_name = params[2].as_str().ok_or(RpcError::ParseError)?.to_string();
-            let remark = params[3].as_str().ok_or(RpcError::ParseError)?.to_string();
+            let remote_name = params[1].as_str().ok_or(RpcError::ParseError)?.to_string();
+            let remark = params[2].as_str().ok_or(RpcError::ParseError)?.to_string();
 
             let pid = state.pid().await;
             let db_key = state.group.read().await.db_key(&pid)?;
diff --git a/src/layer.rs b/src/layer.rs
index 0d6308c..3018e07 100644
--- a/src/layer.rs
+++ b/src/layer.rs
@@ -1,3 +1,4 @@
+use esse_primitives::id_to_str;
 use group_types::GroupChatId;
 use serde::{Deserialize, Serialize};
 use std::collections::HashMap;
@@ -66,7 +67,7 @@ impl Layer {
             return true;
         } else {
             for (_, session) in &self.groups {
-                if session.pid == *addr {
+                if session.addr == *addr {
                     return true;
                 }
             }
@@ -111,12 +112,13 @@ impl Layer {
     }
 
     pub fn chat_rm_online(&mut self, pid: &PeerId) -> Option<PeerId> {
-        self.chats.remove(pid).map(|session| session.pid)
+        self.chats.remove(pid).map(|session| session.addr)
     }
 
     pub fn chat_add(&mut self, pid: PeerId, sid: i64, fid: i64) {
         if !self.chats.contains_key(&pid) {
-            self.chats.insert(pid, LayerSession::new(pid, sid, fid));
+            self.chats
+                .insert(pid, LayerSession::new(id_to_str(&pid), pid, sid, fid));
         }
     }
 
@@ -270,8 +272,10 @@ impl Layer {
 
 /// online connected layer session.
 pub(crate) struct LayerSession {
-    /// session network id.
-    pub pid: PeerId,
+    /// session refs symbol id (Chat is friend's pid, Group is GroupChatId)
+    pub pid: String,
+    /// session network addr.
+    pub addr: PeerId,
     /// session database id.
     pub s_id: i64,
     /// layer service database id.
@@ -285,9 +289,10 @@ pub(crate) struct LayerSession {
 }
 
 impl LayerSession {
-    fn new(pid: PeerId, s_id: i64, db_id: i64) -> Self {
+    fn new(pid: String, addr: PeerId, s_id: i64, db_id: i64) -> Self {
         Self {
             pid,
+            addr,
             s_id,
             db_id,
             suspend_me: false,
@@ -303,7 +308,7 @@ impl LayerSession {
             self.suspend_remote = false;
         }
         self.remain = 0;
-        self.pid
+        self.addr
     }
 
     pub fn suspend(&mut self, is_me: bool, must: bool) -> Option<PeerId> {
@@ -320,7 +325,7 @@ impl LayerSession {
 
         if self.suspend_remote && self.suspend_me {
             self.remain = 6; // keep-alive 10~11 minutes 120s/time
-            Some(self.pid)
+            Some(self.addr)
         } else {
             None
         }
diff --git a/src/migrate/session.rs b/src/migrate/session.rs
index c6f9ce2..d0eb4f3 100644
--- a/src/migrate/session.rs
+++ b/src/migrate/session.rs
@@ -4,6 +4,7 @@ pub(super) const SESSION_VERSIONS: [&str; 2] = [
     id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
     fid INTEGER NOT NULL,
     pid TEXT NOT NULL,
+    addr TEXT NOT NULL,
     s_type INTEGER NOT NULL,
     name TEXT NOT NULL,
     is_top INTEGER NOT NULL,
@@ -11,5 +12,5 @@ pub(super) const SESSION_VERSIONS: [&str; 2] = [
     last_datetime INTEGER,
     last_content TEXT,
     last_readed INTEGER);",
-  "INSERT INTO sessions (fid, pid, s_type, name, is_top, is_close, last_datetime, last_content, last_readed) VALUES (0, '', 3, '', 0, 0, 0, '', 1);", // Jarvis.
+  "INSERT INTO sessions (fid, pid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed) VALUES (0, '', '', 3, '', 0, 0, 0, '', 1);", // Jarvis.
 ];
diff --git a/src/rpc.rs b/src/rpc.rs
index bd7f13c..fc521e1 100644
--- a/src/rpc.rs
+++ b/src/rpc.rs
@@ -7,7 +7,9 @@ use tdn::{
     prelude::{new_send_channel, start_main},
     types::{
         group::GroupId,
-        message::{NetworkType, SendMessage, SendType, StateRequest, StateResponse},
+        message::{
+            NetworkType, RpcSendMessage, SendMessage, SendType, StateRequest, StateResponse,
+        },
         primitives::{HandleResult, Peer, PeerId, Result},
         rpc::{json, rpc_response, RpcError, RpcHandler, RpcParam},
     },
@@ -170,7 +172,10 @@ pub(crate) async fn inner_rpc(uid: u64, method: &str, global: &Arc<Global>) -> R
             }
         };
 
-        global.send(SendMessage::Rpc(uid, param, false)).await?;
+        global
+            .rpc_send
+            .send(RpcSendMessage(uid, param, false))
+            .await?;
         return Ok(());
     }
 
diff --git a/src/server.rs b/src/server.rs
index 8b787ce..c6d3c21 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -18,9 +18,9 @@ use tokio::{
 use tdn_storage::local::DStorage;
 
 use crate::account::Account;
-//use crate::apps::app_layer_handle;
+use crate::apps::app_layer_handle;
 use crate::global::Global;
-use crate::group::Group;
+use crate::group::{handle as group_handle, Group};
 use crate::layer::Layer;
 use crate::migrate::{main_migrate, ACCOUNT_DB};
 use crate::primitives::network_seeds;
@@ -93,14 +93,14 @@ pub async fn start(db_path: String) -> Result<()> {
     while let Some(message) = self_recv.recv().await {
         match message {
             ReceiveMessage::Group(g_msg) => {
-                //if let Ok(handle_result) = group.write().await.handle(g_msg, now_rpc_uid).await {
-                //handle(handle_result, now_rpc_uid, true, &sender).await;
-                //}
+                if let Ok(handle_result) = group_handle(g_msg, &global).await {
+                    handle(handle_result, now_rpc_uid, true, &global).await;
+                }
             }
             ReceiveMessage::Layer(fgid, l_msg) => {
-                // if let Ok(handle_result) = app_layer_handle(&layer, fgid, tgid, l_msg).await {
-                //     handle(handle_result, now_rpc_uid, true, &sender).await;
-                // }
+                if let Ok(handle_result) = app_layer_handle(fgid, l_msg, &global).await {
+                    handle(handle_result, now_rpc_uid, true, &global).await;
+                }
             }
             ReceiveMessage::Rpc(uid, params, is_ws) => {
                 if !is_ws {
diff --git a/src/session.rs b/src/session.rs
index af5b084..3fb050c 100644
--- a/src/session.rs
+++ b/src/session.rs
@@ -1,4 +1,3 @@
-use esse_primitives::{id_from_str, id_to_str};
 use tdn::types::{
     primitives::{PeerId, Result},
     rpc::{json, RpcParam},
@@ -36,7 +35,8 @@ impl SessionType {
 pub(crate) struct Session {
     pub id: i64,
     fid: i64,
-    pub pid: PeerId,
+    pub pid: String,
+    pub addr: PeerId,
     pub s_type: SessionType,
     name: String,
     is_top: bool,
@@ -47,10 +47,18 @@ pub(crate) struct Session {
 }
 
 impl Session {
-    pub fn new(fid: i64, pid: PeerId, s_type: SessionType, name: String, datetime: i64) -> Self {
+    pub fn new(
+        fid: i64,
+        pid: String,
+        addr: PeerId,
+        s_type: SessionType,
+        name: String,
+        datetime: i64,
+    ) -> Self {
         Self {
             fid,
             pid,
+            addr,
             s_type,
             name,
             id: 0,
@@ -66,7 +74,8 @@ impl Session {
         json!([
             self.id,
             self.fid,
-            id_to_str(&self.pid),
+            self.pid,
+            self.addr.to_hex(),
             self.s_type.to_int(),
             self.name,
             self.is_top,
@@ -86,7 +95,8 @@ impl Session {
             is_top: v.pop().unwrap().as_bool(),
             name: v.pop().unwrap().as_string(),
             s_type: SessionType::from_int(v.pop().unwrap().as_i64()),
-            pid: id_from_str(v.pop().unwrap().as_str()).unwrap_or(PeerId::default()),
+            addr: PeerId::from_hex(v.pop().unwrap().as_str()).unwrap_or(PeerId::default()),
+            pid: v.pop().unwrap().as_string(),
             fid: v.pop().unwrap().as_i64(),
             id: v.pop().unwrap().as_i64(),
         }
@@ -102,17 +112,19 @@ impl Session {
             let id = unique_check.pop().unwrap().pop().unwrap().as_i64();
             self.id = id;
 
-            let sql = format!("UPDATE sessions SET pid='{}', name = '{}', is_top = '{}', is_close = false WHERE id = {}",
-                id_to_str(&self.pid),
+            let sql = format!("UPDATE sessions SET pid='{}', addr='{}', name = '{}', is_top = '{}', is_close = false WHERE id = {}",
+                self.pid,
+                self.addr.to_hex(),
                 self.name,
                 self.is_top,
                 self.id,
             );
             db.update(&sql)?;
         } else {
-            let sql = format!("INSERT INTO sessions (fid, pid, s_type, name, is_top, is_close, last_datetime, last_content, last_readed) VALUES ({}, '{}', {}, '{}', {}, {}, {}, '{}', {})",
+            let sql = format!("INSERT INTO sessions (fid, pid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed) VALUES ({}, '{}', '{}', {}, '{}', {}, {}, {}, '{}', {})",
             self.fid,
-            id_to_str(&self.pid),
+            self.pid,
+            self.addr.to_hex(),
             self.s_type.to_int(),
             self.name,
             self.is_top,
@@ -129,7 +141,7 @@ impl Session {
     }
 
     pub fn get(db: &DStorage, id: &i64) -> Result<Session> {
-        let sql = format!("SELECT id, fid, pid, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions WHERE id = {}", id);
+        let sql = format!("SELECT id, fid, pid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions WHERE id = {}", id);
         let mut matrix = db.query(&sql)?;
         if matrix.len() > 0 {
             Ok(Session::from_values(matrix.pop().unwrap())) // safe unwrap()
@@ -139,7 +151,7 @@ impl Session {
     }
 
     pub fn list(db: &DStorage) -> Result<Vec<Session>> {
-        let matrix = db.query("SELECT id, fid, pid, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions ORDER BY last_datetime DESC")?;
+        let matrix = db.query("SELECT id, fid, pid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions ORDER BY last_datetime DESC")?;
         let mut sessions = vec![];
         for values in matrix {
             sessions.push(Session::from_values(values));
@@ -253,17 +265,17 @@ pub(crate) fn connect_session(
     db: &DStorage,
     s_type: &SessionType,
     fid: &i64,
-    pid: &PeerId,
+    addr: &PeerId,
 ) -> Result<Option<Session>> {
-    let sql = format!("SELECT id, fid, pid, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions WHERE s_type = {} AND fid = {}", s_type.to_int(), fid);
+    let sql = format!("SELECT id, fid, pid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions WHERE s_type = {} AND fid = {}", s_type.to_int(), fid);
 
     let mut matrix = db.query(&sql)?;
     if matrix.len() > 0 {
         let session = Session::from_values(matrix.pop().unwrap()); // safe unwrap()
 
         let _ = db.update(&format!(
-            "UPDATE sessions SET pid = '{}' WHERE id = {}",
-            pid.to_hex(),
+            "UPDATE sessions SET addr = '{}' WHERE id = {}",
+            addr.to_hex(),
             session.id,
         ));
 
diff --git a/src/storage.rs b/src/storage.rs
index c447fd9..db7885f 100644
--- a/src/storage.rs
+++ b/src/storage.rs
@@ -350,70 +350,70 @@ pub(crate) fn consensus_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result
 
 pub(crate) fn session_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result<DStorage> {
     let mut db_path = base.clone();
-    db_path.push(pid.to_hex());
+    db_path.push(id_to_str(pid));
     db_path.push(SESSION_DB);
     DStorage::open(db_path, db_key)
 }
 
 pub(crate) fn chat_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result<DStorage> {
     let mut db_path = base.clone();
-    db_path.push(pid.to_hex());
+    db_path.push(id_to_str(pid));
     db_path.push(CHAT_DB);
     DStorage::open(db_path, db_key)
 }
 
 pub(crate) fn file_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result<DStorage> {
     let mut db_path = base.clone();
-    db_path.push(pid.to_hex());
+    db_path.push(id_to_str(pid));
     db_path.push(FILE_DB);
     DStorage::open(db_path, db_key)
 }
 
 pub(crate) fn _service_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result<DStorage> {
     let mut db_path = base.clone();
-    db_path.push(pid.to_hex());
+    db_path.push(id_to_str(pid));
     db_path.push(SERVICE_DB);
     DStorage::open(db_path, db_key)
 }
 
 pub(crate) fn jarvis_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result<DStorage> {
     let mut db_path = base.clone();
-    db_path.push(pid.to_hex());
+    db_path.push(id_to_str(pid));
     db_path.push(JARVIS_DB);
     DStorage::open(db_path, db_key)
 }
 
 pub(crate) fn group_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result<DStorage> {
     let mut db_path = base.clone();
-    db_path.push(pid.to_hex());
+    db_path.push(id_to_str(pid));
     db_path.push(GROUP_DB);
     DStorage::open(db_path, db_key)
 }
 
 pub(crate) fn _dao_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result<DStorage> {
     let mut db_path = base.clone();
-    db_path.push(pid.to_hex());
+    db_path.push(id_to_str(pid));
     db_path.push(DAO_DB);
     DStorage::open(db_path, db_key)
 }
 
 pub(crate) fn domain_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result<DStorage> {
     let mut db_path = base.clone();
-    db_path.push(pid.to_hex());
+    db_path.push(id_to_str(pid));
     db_path.push(DOMAIN_DB);
     DStorage::open(db_path, db_key)
 }
 
 pub(crate) fn wallet_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result<DStorage> {
     let mut db_path = base.clone();
-    db_path.push(pid.to_hex());
+    db_path.push(id_to_str(pid));
     db_path.push(WALLET_DB);
     DStorage::open(db_path, db_key)
 }
 
 pub(crate) fn _cloud_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result<DStorage> {
     let mut db_path = base.clone();
-    db_path.push(pid.to_hex());
+    db_path.push(id_to_str(pid));
     db_path.push(CLOUD_DB);
     DStorage::open(db_path, db_key)
 }